From 7d428db605d305198481b2201f46f5f91d5f8369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Tue, 5 Mar 2024 00:02:35 +0100 Subject: [PATCH] AST validation: Improve handling of inherent impls nested within functions and anon consts --- .../rustc_ast_passes/src/ast_validation.rs | 57 ++++++++++--------- ...mpls-nested-within-anon-consts-semantic.rs | 35 ++++++++++++ .../impls-nested-within-fns-semantic-0.rs | 15 +++++ .../impls-nested-within-fns-semantic-1.rs | 22 +++++++ 4 files changed, 102 insertions(+), 27 deletions(-) create mode 100644 tests/ui/parser/impls-nested-within-anon-consts-semantic.rs create mode 100644 tests/ui/parser/impls-nested-within-fns-semantic-0.rs create mode 100644 tests/ui/parser/impls-nested-within-fns-semantic-1.rs diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index b56d695c6716a..50ca55eb7e342 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -930,35 +930,38 @@ impl<'a> Visitor<'a> for AstValidator<'a> { only_trait: only_trait.then_some(()), }; - self.visibility_not_permitted( - &item.vis, - errors::VisibilityNotPermittedNote::IndividualImplItems, - ); - if let &Unsafe::Yes(span) = unsafety { - self.dcx().emit_err(errors::InherentImplCannotUnsafe { - span: self_ty.span, - annotation_span: span, - annotation: "unsafe", - self_ty: self_ty.span, - }); - } - if let &ImplPolarity::Negative(span) = polarity { - self.dcx().emit_err(error(span, "negative", false)); - } - if let &Defaultness::Default(def_span) = defaultness { - self.dcx().emit_err(error(def_span, "`default`", true)); - } - if let &Const::Yes(span) = constness { - self.dcx().emit_err(error(span, "`const`", true)); - } + self.with_in_trait_impl(None, |this| { + this.visibility_not_permitted( + &item.vis, + errors::VisibilityNotPermittedNote::IndividualImplItems, + ); + if let &Unsafe::Yes(span) = unsafety { + this.dcx().emit_err(errors::InherentImplCannotUnsafe { + span: self_ty.span, + annotation_span: span, + annotation: "unsafe", + self_ty: self_ty.span, + }); + } + if let &ImplPolarity::Negative(span) = polarity { + this.dcx().emit_err(error(span, "negative", false)); + } + if let &Defaultness::Default(def_span) = defaultness { + this.dcx().emit_err(error(def_span, "`default`", true)); + } + if let &Const::Yes(span) = constness { + this.dcx().emit_err(error(span, "`const`", true)); + } - self.visit_vis(&item.vis); - self.visit_ident(item.ident); - self.with_tilde_const(Some(DisallowTildeConstContext::Impl(item.span)), |this| { - this.visit_generics(generics) + this.visit_vis(&item.vis); + this.visit_ident(item.ident); + this.with_tilde_const( + Some(DisallowTildeConstContext::Impl(item.span)), + |this| this.visit_generics(generics), + ); + this.visit_ty(self_ty); + walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl); }); - self.visit_ty(self_ty); - walk_list!(self, visit_assoc_item, items, AssocCtxt::Impl); walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again. } diff --git a/tests/ui/parser/impls-nested-within-anon-consts-semantic.rs b/tests/ui/parser/impls-nested-within-anon-consts-semantic.rs new file mode 100644 index 0000000000000..36a7825cec8f1 --- /dev/null +++ b/tests/ui/parser/impls-nested-within-anon-consts-semantic.rs @@ -0,0 +1,35 @@ +// Regression test for issue #89342 and for part of #119924. +//@ check-pass + +struct Expr; + +trait Trait0 { + fn required(_: Expr<{ + struct Type; + + impl Type { + // This visibility qualifier used to get rejected. + pub fn perform() {} + } + + 0 + }>); +} + +trait Trait1 {} + +impl Trait1 for () +where + [(); { + struct Type; + + impl Type { + // This visibility qualifier used to get rejected. + pub const STORE: Self = Self; + } + + 0 + }]: +{} + +fn main() {} diff --git a/tests/ui/parser/impls-nested-within-fns-semantic-0.rs b/tests/ui/parser/impls-nested-within-fns-semantic-0.rs new file mode 100644 index 0000000000000..107380d33c70a --- /dev/null +++ b/tests/ui/parser/impls-nested-within-fns-semantic-0.rs @@ -0,0 +1,15 @@ +// Regression test for #121607 and for part of issue #119924. +//@ check-pass + +trait Trait { + fn provided() { + pub struct Type; + + impl Type { + // This visibility qualifier used to get rejected. + pub fn perform() {} + } + } +} + +fn main() {} diff --git a/tests/ui/parser/impls-nested-within-fns-semantic-1.rs b/tests/ui/parser/impls-nested-within-fns-semantic-1.rs new file mode 100644 index 0000000000000..43530e41a66c1 --- /dev/null +++ b/tests/ui/parser/impls-nested-within-fns-semantic-1.rs @@ -0,0 +1,22 @@ +// Regression test for part of issue #119924. +//@ check-pass + +#![feature(const_trait_impl, effects)] + +#[const_trait] +trait Trait { + fn required(); +} + +impl const Trait for () { + fn required() { + pub struct Type; + + impl Type { + // This visibility qualifier used to get rejected. + pub fn perform() {} + } + } +} + +fn main() {}