@@ -836,6 +836,62 @@ impl AttributesExt for Attributes {
836
836
}
837
837
}
838
838
839
+ /// Given a def, returns its name and disambiguator
840
+ /// for a value namespace
841
+ ///
842
+ /// Returns None for things which cannot be ambiguous since
843
+ /// they exist in both namespaces (structs and modules)
844
+ fn value_ns_kind ( def : Def , path_str : & str ) -> Option < ( & ' static str , String ) > {
845
+ match def {
846
+ // structs and mods exist in both namespaces. skip them
847
+ Def :: StructCtor ( ..) | Def :: Mod ( ..) => None ,
848
+ Def :: Variant ( ..) | Def :: VariantCtor ( ..)
849
+ => Some ( ( "variant" , format ! ( "{}()" , path_str) ) ) ,
850
+ Def :: Fn ( ..)
851
+ => Some ( ( "function" , format ! ( "{}()" , path_str) ) ) ,
852
+ Def :: Method ( ..)
853
+ => Some ( ( "method" , format ! ( "{}()" , path_str) ) ) ,
854
+ Def :: Const ( ..)
855
+ => Some ( ( "const" , format ! ( "const@{}" , path_str) ) ) ,
856
+ Def :: Static ( ..)
857
+ => Some ( ( "static" , format ! ( "static@{}" , path_str) ) ) ,
858
+ _ => Some ( ( "value" , format ! ( "value@{}" , path_str) ) ) ,
859
+ }
860
+ }
861
+
862
+ /// Given a def, returns its name, the article to be used, and a disambiguator
863
+ /// for the type namespace
864
+ fn type_ns_kind ( def : Def , path_str : & str ) -> ( & ' static str , & ' static str , String ) {
865
+ let ( kind, article) = match def {
866
+ // we can still have non-tuple structs
867
+ Def :: Struct ( ..) => ( "struct" , "a" ) ,
868
+ Def :: Enum ( ..) => ( "enum" , "an" ) ,
869
+ Def :: Trait ( ..) => ( "trait" , "a" ) ,
870
+ Def :: Union ( ..) => ( "union" , "a" ) ,
871
+ _ => ( "type" , "a" ) ,
872
+ } ;
873
+ ( kind, article, format ! ( "{}@{}" , kind, path_str) )
874
+ }
875
+
876
+ fn ambiguity_error ( cx : & DocContext , attrs : & Attributes ,
877
+ path_str : & str ,
878
+ article1 : & str , kind1 : & str , disambig1 : & str ,
879
+ article2 : & str , kind2 : & str , disambig2 : & str ) {
880
+ let sp = attrs. doc_strings . first ( )
881
+ . map_or ( DUMMY_SP , |a| a. span ( ) ) ;
882
+ cx. sess ( )
883
+ . struct_span_err ( sp,
884
+ & format ! ( "`{}` is both {} {} and {} {}" ,
885
+ path_str, article1, kind1,
886
+ article2, kind2) )
887
+ . help ( & format ! ( "try `{0}` if you want to select the {1}, \
888
+ or `{2}@{3}` if you want to \
889
+ select the {2}",
890
+ disambig1, kind1, disambig2,
891
+ kind2) )
892
+ . emit ( ) ;
893
+ }
894
+
839
895
enum PathKind {
840
896
/// can be either value or type, not a macro
841
897
Unknown ,
@@ -846,6 +902,7 @@ enum PathKind {
846
902
/// types, traits, everything in the type namespace
847
903
Type
848
904
}
905
+
849
906
impl Clean < Attributes > for [ ast:: Attribute ] {
850
907
fn clean ( & self , cx : & DocContext ) -> Attributes {
851
908
let mut attrs = Attributes :: from_ast ( cx. sess ( ) . diagnostic ( ) , self ) ;
@@ -957,43 +1014,13 @@ impl Clean<Attributes> for [ast::Attribute] {
957
1014
if let Ok ( path) = resolve ( false ) {
958
1015
// if there is something in both namespaces
959
1016
if let Ok ( value_path) = resolve ( true ) {
960
- let kind = match value_path. def {
961
- // structs and mods exist in both namespaces. skip them
962
- Def :: StructCtor ( ..) | Def :: Mod ( ..) => None ,
963
- Def :: Variant ( ..) | Def :: VariantCtor ( ..)
964
- => Some ( ( "variant" , format ! ( "{}()" , path_str) ) ) ,
965
- Def :: Fn ( ..)
966
- => Some ( ( "function" , format ! ( "{}()" , path_str) ) ) ,
967
- Def :: Method ( ..)
968
- => Some ( ( "method" , format ! ( "{}()" , path_str) ) ) ,
969
- Def :: Const ( ..)
970
- => Some ( ( "const" , format ! ( "const@{}" , path_str) ) ) ,
971
- Def :: Static ( ..)
972
- => Some ( ( "static" , format ! ( "static@{}" , path_str) ) ) ,
973
- _ => Some ( ( "value" , format ! ( "static@{}" , path_str) ) ) ,
974
- } ;
975
- if let Some ( ( value_kind, disambig) ) = kind {
976
- let ( type_kind, article) = match path. def {
977
- // we can still have non-tuple structs
978
- Def :: Struct ( ..) => ( "struct" , "a" ) ,
979
- Def :: Enum ( ..) => ( "enum" , "an" ) ,
980
- Def :: Trait ( ..) => ( "trait" , "a" ) ,
981
- Def :: Union ( ..) => ( "union" , "a" ) ,
982
- _ => ( "type" , "a" ) ,
983
- } ;
984
- let sp = attrs. doc_strings . first ( )
985
- . map_or ( DUMMY_SP , |a| a. span ( ) ) ;
986
- cx. sess ( )
987
- . struct_span_err ( sp,
988
- & format ! ( "`{}` is both {} {} and a {}" ,
989
- path_str, article, type_kind,
990
- value_kind) )
991
- . help ( & format ! ( "try `{0}` if you want to select the {1}, \
992
- or `{2}@{3}` if you want to \
993
- select the {2}",
994
- disambig, value_kind, type_kind,
995
- path_str) )
996
- . emit ( ) ;
1017
+ let kind = value_ns_kind ( value_path. def , path_str) ;
1018
+ if let Some ( ( value_kind, value_disambig) ) = kind {
1019
+ let ( type_kind, article, type_disambig)
1020
+ = type_ns_kind ( path. def ) ;
1021
+ ambiguity_error ( cx, & attrs,
1022
+ article, type_kind, type_disambig,
1023
+ "a" , value_kind, value_disambig) ;
997
1024
continue ;
998
1025
}
999
1026
}
0 commit comments