From 9a4eac3944e2e2668b4aea0b5afd3d83b88e992e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Feb 2020 12:27:45 +0100 Subject: [PATCH] ast_validation: fix visiting bug. --- src/librustc_ast_passes/ast_validation.rs | 49 +++++++++++-------- .../issue-68788-in-trait-item-propagation.rs | 21 ++++++++ 2 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/parser/issue-68788-in-trait-item-propagation.rs diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 53911d14780..79ed7f234f7 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -81,6 +81,12 @@ struct AstValidator<'a> { } impl<'a> AstValidator<'a> { + fn with_in_trait_impl(&mut self, is_in: bool, f: impl FnOnce(&mut Self)) { + let old = mem::replace(&mut self.in_trait_impl, is_in); + f(self); + self.in_trait_impl = old; + } + fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) { let old = mem::replace(&mut self.is_impl_trait_banned, true); f(self); @@ -737,28 +743,29 @@ fn visit_item(&mut self, item: &'a Item) { ref self_ty, items: _, } => { - let old_in_trait_impl = mem::replace(&mut self.in_trait_impl, true); - - self.invalid_visibility(&item.vis, None); - if let TyKind::Err = self_ty.kind { - self.err_handler() - .struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax") - .help("use `auto trait Trait {}` instead") + self.with_in_trait_impl(true, |this| { + this.invalid_visibility(&item.vis, None); + if let TyKind::Err = self_ty.kind { + this.err_handler() + .struct_span_err( + item.span, + "`impl Trait for .. {}` is an obsolete syntax", + ) + .help("use `auto trait Trait {}` instead") + .emit(); + } + if unsafety == Unsafety::Unsafe && polarity == ImplPolarity::Negative { + struct_span_err!( + this.session, + item.span, + E0198, + "negative impls cannot be unsafe" + ) .emit(); - } - if unsafety == Unsafety::Unsafe && polarity == ImplPolarity::Negative { - struct_span_err!( - self.session, - item.span, - E0198, - "negative impls cannot be unsafe" - ) - .emit(); - } + } - visit::walk_item(self, item); - - self.in_trait_impl = old_in_trait_impl; + visit::walk_item(this, item); + }); return; // Avoid visiting again. } ItemKind::Impl { @@ -1142,7 +1149,7 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { } } - visit::walk_assoc_item(self, item, ctxt); + self.with_in_trait_impl(false, |this| visit::walk_assoc_item(this, item, ctxt)); } } diff --git a/src/test/ui/parser/issue-68788-in-trait-item-propagation.rs b/src/test/ui/parser/issue-68788-in-trait-item-propagation.rs new file mode 100644 index 00000000000..7c3dd1d5a98 --- /dev/null +++ b/src/test/ui/parser/issue-68788-in-trait-item-propagation.rs @@ -0,0 +1,21 @@ +// Make sure we don't propagate restrictions on trait impl items to items inside them. + +// check-pass +// edition:2018 + +fn main() {} + +trait X { + fn foo(); +} + +impl X for () { + fn foo() { + struct S; + impl S { + pub const X: u8 = 0; + pub const fn bar() {} + async fn qux() {} + } + } +}