diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 81bd687e26321..333509e18504d 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -728,9 +728,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { expansion, item.span); self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion)); + self.parent_scope.module = module; for variant in &(*enum_definition).variants { - self.build_reduced_graph_for_variant(variant, module, vis); + self.build_reduced_graph_for_variant(variant, vis); } } @@ -818,10 +819,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // Constructs the reduced graph for one variant. Variants exist in the // type and value namespaces. - fn build_reduced_graph_for_variant(&mut self, - variant: &Variant, - parent: Module<'a>, - vis: ty::Visibility) { + fn build_reduced_graph_for_variant(&mut self, variant: &Variant, vis: ty::Visibility) { + let parent = self.parent_scope.module; let expn_id = self.parent_scope.expansion; let ident = variant.ident; @@ -1253,9 +1252,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { let expansion = self.parent_scope.expansion; self.r.define(parent, item.ident, ns, (res, vis, item.span, expansion)); - self.parent_scope.module = parent.parent.unwrap(); // nearest normal ancestor visit::walk_trait_item(self, item); - self.parent_scope.module = parent; } fn visit_token(&mut self, t: Token) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 7f65e5dfaa2bf..efb64c9341f13 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -538,7 +538,11 @@ impl<'a> ModuleData<'a> { } fn nearest_item_scope(&'a self) -> Module<'a> { - if self.is_trait() { self.parent.unwrap() } else { self } + match self.kind { + ModuleKind::Def(DefKind::Enum, ..) | ModuleKind::Def(DefKind::Trait, ..) => + self.parent.expect("enum or trait module without a parent"), + _ => self, + } } fn is_ancestor_of(&self, mut other: &Self) -> bool { @@ -1640,7 +1644,7 @@ impl<'a> Resolver<'a> { } if let ModuleKind::Block(..) = module.kind { - return Some(module.parent.unwrap()); + return Some(module.parent.unwrap().nearest_item_scope()); } None diff --git a/src/test/ui/resolve/block-with-trait-parent.rs b/src/test/ui/resolve/block-with-trait-parent.rs new file mode 100644 index 0000000000000..bc86f94e921cb --- /dev/null +++ b/src/test/ui/resolve/block-with-trait-parent.rs @@ -0,0 +1,14 @@ +// check-pass + +trait Trait { + fn method(&self) { + // Items inside a block turn it into a module internally. + struct S; + impl Trait for S {} + + // OK, `Trait` is in scope here from method resolution point of view. + S.method(); + } +} + +fn main() {}