]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_resolve/lib.rs
clarify what the item is in "not a module" error
[rust.git] / src / librustc_resolve / lib.rs
index f48cfa0b1479f2f66dc42dfb2c4edc8f1e64c06d..ffc783ae9f235dd56eee44cadce2cbb94b4e5362 100644 (file)
@@ -8,6 +8,7 @@
 #![recursion_limit="256"]
 
 #![deny(rust_2018_idioms)]
+#![cfg_attr(not(stage0), deny(internal))]
 
 pub use rustc::hir::def::{Namespace, PerNS};
 
@@ -1352,7 +1353,7 @@ fn is_ambiguity(&self) -> bool {
         }
     }
 
-    // We sometimes need to treat variants as `pub` for backwards compatibility
+    // We sometimes need to treat variants as `pub` for backwards compatibility.
     fn pseudo_vis(&self) -> ty::Visibility {
         if self.is_variant() && self.def().def_id().is_local() {
             ty::Visibility::Public
@@ -1697,7 +1698,12 @@ fn resolve_str_path(
         components: &[&str],
         is_value: bool
     ) -> hir::Path {
-        let segments = iter::once(keywords::PathRoot.ident())
+        let root = if crate_root.is_some() {
+            keywords::PathRoot
+        } else {
+            keywords::Crate
+        };
+        let segments = iter::once(root.ident())
             .chain(
                 crate_root.into_iter()
                     .chain(components.iter().cloned())
@@ -1733,7 +1739,6 @@ impl<'a> Resolver<'a> {
     /// just that an error occurred.
     pub fn resolve_str_path_error(&mut self, span: Span, path_str: &str, is_value: bool)
         -> Result<hir::Path, ()> {
-        use std::iter;
         let mut errored = false;
 
         let path = if path_str.starts_with("::") {
@@ -2710,7 +2715,7 @@ fn with_self_rib<F>(&mut self, self_def: Def, f: F)
     {
         let mut self_type_rib = Rib::new(NormalRibKind);
 
-        // plain insert (no renaming, types are not currently hygienic....)
+        // Plain insert (no renaming, since types are not currently hygienic)
         self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_def);
         self.ribs[TypeNS].push(self_type_rib);
         f(self);
@@ -3726,9 +3731,16 @@ fn resolve_path(
                             def, path.len() - i - 1
                         ));
                     } else {
+                        let label = format!(
+                            "`{}` is {} {}, not a module",
+                            ident,
+                            def.article(),
+                            def.kind_name(),
+                        );
+
                         return PathResult::Failed {
                             span: ident.span,
-                            label: format!("not a module `{}`", ident),
+                            label,
                             suggestion: None,
                             is_error_from_last_segment: is_last,
                         };
@@ -4434,26 +4446,47 @@ fn get_traits_in_module_containing_item(&mut self,
             let mut collected_traits = Vec::new();
             module.for_each_child(|name, ns, binding| {
                 if ns != TypeNS { return }
-                if let Def::Trait(_) = binding.def() {
-                    collected_traits.push((name, binding));
+                match binding.def() {
+                    Def::Trait(_) |
+                    Def::TraitAlias(_) => collected_traits.push((name, binding)),
+                    _ => (),
                 }
             });
             *traits = Some(collected_traits.into_boxed_slice());
         }
 
         for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
-            let module = binding.module().unwrap();
-            let mut ident = ident;
-            if ident.span.glob_adjust(module.expansion, binding.span.ctxt().modern()).is_none() {
-                continue
-            }
-            if self.resolve_ident_in_module_unadjusted(
-                ModuleOrUniformRoot::Module(module),
-                ident,
-                ns,
-                false,
-                module.span,
-            ).is_ok() {
+            // Traits have pseudo-modules that can be used to search for the given ident.
+            if let Some(module) = binding.module() {
+                let mut ident = ident;
+                if ident.span.glob_adjust(
+                    module.expansion,
+                    binding.span.ctxt().modern(),
+                ).is_none() {
+                    continue
+                }
+                if self.resolve_ident_in_module_unadjusted(
+                    ModuleOrUniformRoot::Module(module),
+                    ident,
+                    ns,
+                    false,
+                    module.span,
+                ).is_ok() {
+                    let import_id = match binding.kind {
+                        NameBindingKind::Import { directive, .. } => {
+                            self.maybe_unused_trait_imports.insert(directive.id);
+                            self.add_to_glob_map(&directive, trait_name);
+                            Some(directive.id)
+                        }
+                        _ => None,
+                    };
+                    let trait_def_id = module.def_id().unwrap();
+                    found_traits.push(TraitCandidate { def_id: trait_def_id, import_id });
+                }
+            } else if let Def::TraitAlias(_) = binding.def() {
+                // For now, just treat all trait aliases as possible candidates, since we don't
+                // know if the ident is somewhere in the transitive bounds.
+
                 let import_id = match binding.kind {
                     NameBindingKind::Import { directive, .. } => {
                         self.maybe_unused_trait_imports.insert(directive.id);
@@ -4462,8 +4495,10 @@ fn get_traits_in_module_containing_item(&mut self,
                     }
                     _ => None,
                 };
-                let trait_def_id = module.def_id().unwrap();
-                found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: import_id });
+                let trait_def_id = binding.def().def_id();
+                found_traits.push(TraitCandidate { def_id: trait_def_id, import_id });
+            } else {
+                bug!("candidate is not trait or trait alias?")
             }
         }
     }