ast_validation: fix visiting bug.

This commit is contained in:
Mazdak Farrokhzad 2020-02-05 12:27:45 +01:00
parent 67c29ed8fc
commit 9a4eac3944
2 changed files with 49 additions and 21 deletions

View 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));
}
}

View File

@ -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() {}
}
}
}