From d0c826cfc2a1d52061a5c72d2dd78a06b51374ce Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 11 Aug 2023 19:05:03 +0000 Subject: [PATCH] Opaques do not constrain generic params --- .../src/constrained_generic_params.rs | 2 +- tests/ui/type-alias-impl-trait/coherence.rs | 2 +- .../ui/type-alias-impl-trait/coherence.stderr | 13 +++------- .../coherence_generalization.rs | 4 +-- .../coherence_generalization.stderr | 9 +++++++ .../unconstrained-impl-param.rs | 25 +++++++++++++++++++ .../unconstrained-impl-param.stderr | 9 +++++++ 7 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/coherence_generalization.stderr create mode 100644 tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs create mode 100644 tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 35882ad352b..5591fa6f2a5 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -59,7 +59,7 @@ struct ParameterCollector { impl<'tcx> TypeVisitor> for ParameterCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match *t.kind() { - ty::Alias(ty::Projection | ty::Inherent, ..) if !self.include_nonconstraining => { + ty::Alias(..) if !self.include_nonconstraining => { // projections are not injective return ControlFlow::Continue(()); } diff --git a/tests/ui/type-alias-impl-trait/coherence.rs b/tests/ui/type-alias-impl-trait/coherence.rs index 077a31494a9..1c0f83d6c12 100644 --- a/tests/ui/type-alias-impl-trait/coherence.rs +++ b/tests/ui/type-alias-impl-trait/coherence.rs @@ -12,6 +12,6 @@ fn use_alias(val: T) -> AliasOfForeignType { } impl foreign_crate::ForeignTrait for AliasOfForeignType {} -//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types +//~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates fn main() {} diff --git a/tests/ui/type-alias-impl-trait/coherence.stderr b/tests/ui/type-alias-impl-trait/coherence.stderr index c923eb08ab3..6ede0fa14ba 100644 --- a/tests/ui/type-alias-impl-trait/coherence.stderr +++ b/tests/ui/type-alias-impl-trait/coherence.stderr @@ -1,14 +1,9 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence.rs:14:1 +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/coherence.rs:14:6 | LL | impl foreign_crate::ForeignTrait for AliasOfForeignType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------- - | | | - | | `AliasOfForeignType` is not defined in the current crate - | impl doesn't use only types from inside the current crate - | - = note: define and implement a trait or new type instead + | ^ unconstrained type parameter error: aborting due to previous error -For more information about this error, try `rustc --explain E0117`. +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/coherence_generalization.rs b/tests/ui/type-alias-impl-trait/coherence_generalization.rs index 679b2b0f188..0e9e0e23270 100644 --- a/tests/ui/type-alias-impl-trait/coherence_generalization.rs +++ b/tests/ui/type-alias-impl-trait/coherence_generalization.rs @@ -1,7 +1,6 @@ -// check-pass - // FIXME(type_alias_impl_trait): What does this test? This needs a comment // explaining what we're worried about here. + #![feature(type_alias_impl_trait)] trait Trait {} type Opaque = impl Sized; @@ -11,5 +10,6 @@ fn foo() -> Opaque { impl Trait for (T, V, V, u32) {} impl Trait for (Opaque, V, i32, V) {} +//~^ ERROR the type parameter `U` is not constrained by the impl trait, self type, or predicates fn main() {} diff --git a/tests/ui/type-alias-impl-trait/coherence_generalization.stderr b/tests/ui/type-alias-impl-trait/coherence_generalization.stderr new file mode 100644 index 00000000000..d5148fbdacf --- /dev/null +++ b/tests/ui/type-alias-impl-trait/coherence_generalization.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates + --> $DIR/coherence_generalization.rs:12:6 + | +LL | impl Trait for (Opaque, V, i32, V) {} + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs new file mode 100644 index 00000000000..288e7d34b48 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Display; + +type Opaque<'a> = impl Sized + 'static; +fn define<'a>() -> Opaque<'a> {} + +trait Trait { + type Assoc: Display; +} +impl<'a> Trait for Opaque<'a> { + //~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + type Assoc = &'a str; +} + +// ======= Exploit ======= + +fn extend(s: T::Assoc) -> Box { + Box::new(s) +} + +fn main() { + let val = extend::>(&String::from("blah blah blah")); + println!("{}", val); +} diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr new file mode 100644 index 00000000000..6fe265c5e20 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr @@ -0,0 +1,9 @@ +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-impl-param.rs:11:6 + | +LL | impl<'a> Trait for Opaque<'a> { + | ^^ unconstrained lifetime parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`.