]> git.lizzy.rs Git - rust.git/commitdiff
ast_validation: fix visiting bug.
authorMazdak Farrokhzad <twingoow@gmail.com>
Wed, 5 Feb 2020 11:27:45 +0000 (12:27 +0100)
committerMazdak Farrokhzad <twingoow@gmail.com>
Wed, 5 Feb 2020 11:27:45 +0000 (12:27 +0100)
src/librustc_ast_passes/ast_validation.rs
src/test/ui/parser/issue-68788-in-trait-item-propagation.rs [new file with mode: 0644]

index 53911d147802d5f893b2a382e4ac2f69afb71b8b..79ed7f234f72e6ee1e92e7550e168f1f396febd4 100644 (file)
@@ -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 (file)
index 0000000..7c3dd1d
--- /dev/null
@@ -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() {}
+        }
+    }
+}