From 7a295d1be07d191527dfcdf4613ced7ab6fa9676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 28 Mar 2025 15:14:35 +0100 Subject: [PATCH] Fix TAIT & ATPIT feature gating in the presence of anon consts --- compiler/rustc_ast_passes/src/feature_gate.rs | 7 ++ .../feature-gate-impl_trait_in_assoc_type.rs | 9 ++ ...ature-gate-impl_trait_in_assoc_type.stderr | 20 +++- .../feature-gate-type_alias_impl_trait.rs | 26 ++-- .../feature-gate-type_alias_impl_trait.stderr | 111 ++++++++++++++++++ tests/ui/impl-trait/impl_trait_projections.rs | 5 + .../impl-trait/impl_trait_projections.stderr | 10 +- .../inside-item-nested-in-anon-const.rs | 25 ++++ 8 files changed, 200 insertions(+), 13 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr create mode 100644 tests/ui/impl-trait/inside-item-nested-in-anon-const.rs diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 31ff102c127a3..a3fcc110a1666 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -99,6 +99,13 @@ impl<'a> PostExpansionVisitor<'a> { } visit::walk_ty(self, ty); } + + fn visit_anon_const(&mut self, _: &ast::AnonConst) -> Self::Result { + // We don't walk the anon const because it crosses a conceptual boundary: We're no + // longer "inside" the original type. + // Brittle: We assume that the callers of `check_impl_trait` will later recurse into + // the items found in the AnonConst to look for nested TyAliases. + } } ImplTraitVisitor { vis: self, in_associated_ty }.visit_ty(ty); } diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs index 2c130664e9a1f..f9b5176d78ac7 100644 --- a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs +++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs @@ -17,4 +17,13 @@ impl Mop { //~| ERROR: unconstrained opaque type } +fn funky(_: [(); { + impl Foo for fn() { + type Bar = impl Sized; + //~^ ERROR: `impl Trait` in associated types is unstable + //~| ERROR: unconstrained opaque type + } + 0 +}]) {} + fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr index 7dfd79c728641..01d25c1622813 100644 --- a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr +++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr @@ -18,6 +18,16 @@ LL | type Bop = impl std::fmt::Debug; = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0658]: `impl Trait` in associated types is unstable + --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:22:20 + | +LL | type Bar = impl Sized; + | ^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: inherent associated types are unstable --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:14:5 | @@ -44,6 +54,14 @@ LL | type Bop = impl std::fmt::Debug; | = note: `Bop` must be used in combination with a concrete type within the same impl -error: aborting due to 5 previous errors +error: unconstrained opaque type + --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:22:20 + | +LL | type Bar = impl Sized; + | ^^^^^^^^^^ + | + = note: `Bar` must be used in combination with a concrete type within the same impl + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs index ec70a20844a55..d332fba0623c3 100644 --- a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs +++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -1,38 +1,42 @@ -//@ check-pass -#![feature(type_alias_impl_trait)] use std::fmt::Debug; -type Foo = impl Debug; +type Foo = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable struct Bar(Foo); -#[define_opaque(Foo)] +#[define_opaque(Foo)] //~ ERROR use of unstable library feature `type_alias_impl_trait` fn define() -> Bar { Bar(42) } -type Foo2 = impl Debug; +type Foo2 = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable -#[define_opaque(Foo2)] +#[define_opaque(Foo2)] //~ ERROR use of unstable library feature `type_alias_impl_trait` fn define2() { let x = || -> Foo2 { 42 }; } -type Foo3 = impl Debug; +type Foo3 = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable -#[define_opaque(Foo3)] +#[define_opaque(Foo3)] //~ ERROR use of unstable library feature `type_alias_impl_trait` fn define3(x: Foo3) { let y: i32 = x; } -#[define_opaque(Foo3)] +#[define_opaque(Foo3)] //~ ERROR use of unstable library feature `type_alias_impl_trait` fn define3_1() { define3(42) } -type Foo4 = impl Debug; +type Foo4 = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable -#[define_opaque(Foo4)] +#[define_opaque(Foo4)] //~ ERROR use of unstable library feature `type_alias_impl_trait` fn define4(_: Foo4) { let y: Foo4 = 42; } +type Foo5 = [(); { + type Foo = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable + //~^ ERROR unconstrained opaque type + 0 +}]; + fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr new file mode 100644 index 0000000000000..bab60eb429303 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr @@ -0,0 +1,111 @@ +error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns + --> $DIR/feature-gate-type_alias_impl_trait.rs:6:3 + | +LL | #[define_opaque(Foo)] + | ^^^^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns + --> $DIR/feature-gate-type_alias_impl_trait.rs:13:3 + | +LL | #[define_opaque(Foo2)] + | ^^^^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns + --> $DIR/feature-gate-type_alias_impl_trait.rs:20:3 + | +LL | #[define_opaque(Foo3)] + | ^^^^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns + --> $DIR/feature-gate-type_alias_impl_trait.rs:24:3 + | +LL | #[define_opaque(Foo3)] + | ^^^^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns + --> $DIR/feature-gate-type_alias_impl_trait.rs:31:3 + | +LL | #[define_opaque(Foo4)] + | ^^^^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/feature-gate-type_alias_impl_trait.rs:3:12 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/feature-gate-type_alias_impl_trait.rs:11:13 + | +LL | type Foo2 = impl Debug; + | ^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/feature-gate-type_alias_impl_trait.rs:18:13 + | +LL | type Foo3 = impl Debug; + | ^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/feature-gate-type_alias_impl_trait.rs:29:13 + | +LL | type Foo4 = impl Debug; + | ^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/feature-gate-type_alias_impl_trait.rs:37:16 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: unconstrained opaque type + --> $DIR/feature-gate-type_alias_impl_trait.rs:37:16 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same crate + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-trait/impl_trait_projections.rs b/tests/ui/impl-trait/impl_trait_projections.rs index 2c277aee06dad..89fe3c1509cc5 100644 --- a/tests/ui/impl-trait/impl_trait_projections.rs +++ b/tests/ui/impl-trait/impl_trait_projections.rs @@ -35,4 +35,9 @@ fn projection_from_impl_trait_inside_dyn_trait_is_disallowed() panic!() } +fn parametrized_value_in_anon_const_is_disallowed() -> [(); None::] { + //~^ ERROR `impl Trait` is not allowed in paths + loop {} +} + fn main() {} diff --git a/tests/ui/impl-trait/impl_trait_projections.stderr b/tests/ui/impl-trait/impl_trait_projections.stderr index 5e0b80fcd5922..21f45613938f5 100644 --- a/tests/ui/impl-trait/impl_trait_projections.stderr +++ b/tests/ui/impl-trait/impl_trait_projections.stderr @@ -30,6 +30,14 @@ LL | -> as Iterator>::Item | = note: `impl Trait` is only allowed in arguments and return types of functions and methods -error: aborting due to 4 previous errors +error[E0562]: `impl Trait` is not allowed in paths + --> $DIR/impl_trait_projections.rs:38:68 + | +LL | fn parametrized_value_in_anon_const_is_disallowed() -> [(); None::] { + | ^^^^^^^^^^ + | + = note: `impl Trait` is only allowed in arguments and return types of functions and methods + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/inside-item-nested-in-anon-const.rs b/tests/ui/impl-trait/inside-item-nested-in-anon-const.rs new file mode 100644 index 0000000000000..ab54d5f87baef --- /dev/null +++ b/tests/ui/impl-trait/inside-item-nested-in-anon-const.rs @@ -0,0 +1,25 @@ +// Ensure we don't misclassify `impl Trait` as TAIT/ATPIT if located inside an anon const in a +// type alias/assoc type. +// issue: +//@ check-pass +#![forbid(unstable_features)] + +struct Girder; + +type Alias = Girder<{ + fn pass(input: impl Sized) -> impl Sized { input } + 0 +}>; + +trait Trait { + type Assoc; +} + +impl Trait for () { + type Assoc = [(); { + fn pass(input: impl Sized) -> impl Sized { input } + 0 + }]; +} + +fn main() {}