Skip to content

Commit

Permalink
Rollup merge of #133768 - compiler-errors:gate, r=lcnr,jackh726
Browse files Browse the repository at this point in the history
Remove `generic_associated_types_extended` feature gate

This PR retires nightly support for the `generic_associated_types_extended` feature. This feature hasn't received much attention in the last two years or so, and I believe the feature still remains both unsound and ICEy to use. I think that if we were to redesign and reimplement it, we'd want to first figure out how to implement it soundly, but in the mean time I'd prefer to clean this up.

r? ``@lcnr`` cc ``@jackh726`` who added this feature gate I think
  • Loading branch information
matthiaskrgr authored Dec 3, 2024
2 parents e66e632 + f91fd0c commit 12519a6
Show file tree
Hide file tree
Showing 24 changed files with 300 additions and 124 deletions.
7 changes: 7 additions & 0 deletions compiler/rustc_feature/src/removed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ declare_features! (
(removed, generator_clone, "1.65.0", Some(95360), Some("renamed to `coroutine_clone`")),
/// Allows defining generators.
(removed, generators, "1.21.0", Some(43122), Some("renamed to `coroutines`")),
/// An extension to the `generic_associated_types` feature, allowing incomplete features.
(removed, generic_associated_types_extended, "CURRENT_RUSTC_VERSION", Some(95451),
Some(
"feature needs overhaul and reimplementation pending \
better implied higher-ranked implied bounds support"
)
),
/// Allows `impl Trait` in bindings (`let`, `const`, `static`).
(removed, impl_trait_in_bindings, "1.55.0", Some(63065),
Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,6 @@ declare_features! (
(unstable, gen_blocks, "1.75.0", Some(117078)),
/// Infer generic args for both consts and types.
(unstable, generic_arg_infer, "1.55.0", Some(85077)),
/// An extension to the `generic_associated_types` feature, allowing incomplete features.
(incomplete, generic_associated_types_extended, "1.61.0", Some(95451)),
/// Allows non-trivial generic constants which have to have wfness manually propagated to callers
(incomplete, generic_const_exprs, "1.56.0", Some(76560)),
/// Allows generic parameters and where-clauses on free & associated const items.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,10 +329,7 @@ pub fn dyn_compatibility_violations_for_assoc_item(
.collect(),
// Associated types can only be dyn-compatible if they have `Self: Sized` bounds.
ty::AssocKind::Type => {
if !tcx.features().generic_associated_types_extended()
&& !tcx.generics_of(item.def_id).is_own_empty()
&& !item.is_impl_trait_in_trait()
{
if !tcx.generics_of(item.def_id).is_own_empty() && !item.is_impl_trait_in_trait() {
vec![DynCompatibilityViolation::GAT(item.name, item.ident(tcx).span)]
} else {
// We will permit associated types if they are explicitly mentioned in the trait object.
Expand Down
26 changes: 1 addition & 25 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::traits::select::OverflowError;
use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, Term, Ty, TyCtxt, TypingMode, Upcast};
use rustc_middle::{bug, span_bug};
use rustc_span::symbol::sym;
Expand Down Expand Up @@ -179,35 +179,11 @@ pub(super) fn poly_project_and_unify_term<'cx, 'tcx>(
) -> ProjectAndUnifyResult<'tcx> {
let infcx = selcx.infcx;
let r = infcx.commit_if_ok(|_snapshot| {
let old_universe = infcx.universe();
let placeholder_predicate = infcx.enter_forall_and_leak_universe(obligation.predicate);
let new_universe = infcx.universe();

let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate);
match project_and_unify_term(selcx, &placeholder_obligation) {
ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e),
ProjectAndUnifyResult::Holds(obligations)
if old_universe != new_universe
&& selcx.tcx().features().generic_associated_types_extended() =>
{
// If the `generic_associated_types_extended` feature is active, then we ignore any
// obligations references lifetimes from any universe greater than or equal to the
// universe just created. Otherwise, we can end up with something like `for<'a> I: 'a`,
// which isn't quite what we want. Ideally, we want either an implied
// `for<'a where I: 'a> I: 'a` or we want to "lazily" check these hold when we
// instantiate concrete regions. There is design work to be done here; until then,
// however, this allows experimenting potential GAT features without running into
// well-formedness issues.
let new_obligations = obligations
.into_iter()
.filter(|obligation| {
let mut visitor = MaxUniverse::new();
obligation.predicate.visit_with(&mut visitor);
visitor.max_universe() < new_universe
})
.collect();
Ok(ProjectAndUnifyResult::Holds(new_obligations))
}
other => Ok(other),
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
for assoc_type in assoc_types {
let defs: &ty::Generics = tcx.generics_of(assoc_type);

if !defs.own_params.is_empty() && !tcx.features().generic_associated_types_extended() {
if !defs.own_params.is_empty() {
tcx.dcx().span_delayed_bug(
obligation.cause.span,
"GATs in trait object shouldn't have been considered",
Expand Down
13 changes: 0 additions & 13 deletions tests/crashes/131538.rs

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
//@ revisions: base extended
//@[base] check-fail
//@[extended] check-pass

#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
//@ known-bug: #133805

pub trait FromLendingIterator<A>: Sized {
fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
}

impl<A> FromLendingIterator<A> for Vec<A> {
fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
//[base]~^ impl has stricter
let mut v = vec![];
while let Some(item) = iter.next() {
v.push(item);
Expand All @@ -32,7 +26,6 @@ pub trait LendingIterator {
Self: for<'q> LendingIterator<Item<'q> = A>,
{
<B as FromLendingIterator<A>>::from_iter(self)
//[base]~^ ERROR: does not live long enough
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0276]: impl has stricter requirements than trait
--> $DIR/lending_iterator.rs:13:45
--> $DIR/lending_iterator.rs:8:45
|
LL | fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
| ------------------------------------------------------------------------ definition of `from_iter` from trait
Expand All @@ -8,7 +8,7 @@ LL | fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) ->
| ^^^^^^^^^^^^ impl has extra requirement `I: 'x`

error: `Self` does not live long enough
--> $DIR/lending_iterator.rs:34:9
--> $DIR/lending_iterator.rs:28:9
|
LL | <B as FromLendingIterator<A>>::from_iter(self)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
//@ revisions: base extended
//@[base] check-fail
//@[extended] check-pass

#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
//@ known-bug: #133805

pub trait FromLendingIterator<A>: Sized {
fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
}

impl<A> FromLendingIterator<A> for Vec<A> {
fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
//[base]~^ impl has stricter
let mut v = vec![];
while let Some(item) = iter.next() {
v.push(item);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0276]: impl has stricter requirements than trait
--> $DIR/lending_iterator_2.rs:13:45
--> $DIR/lending_iterator_2.rs:8:45
|
LL | fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
| ------------------------------------------------------------------------ definition of `from_iter` from trait
Expand Down
12 changes: 4 additions & 8 deletions tests/ui/generic-associated-types/gat-in-trait-path.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
//@ revisions: base extended
//@[base] check-fail
//@[extended] check-pass
//@ check-fail

#![feature(associated_type_defaults)]
#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]

trait Foo {
type A<'a> where Self: 'a;
Expand All @@ -24,12 +20,12 @@ impl<T> Foo for Fooer<T> {
}

fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
//[base]~^ the trait `Foo` cannot be made into an object
//~^ the trait `Foo` cannot be made into an object


fn main() {
let foo = Fooer(5);
f(Box::new(foo));
//[base]~^ the trait `Foo` cannot be made into an object
//[base]~| the trait `Foo` cannot be made into an object
//~^ the trait `Foo` cannot be made into an object
//~| the trait `Foo` cannot be made into an object
}
58 changes: 58 additions & 0 deletions tests/ui/generic-associated-types/gat-in-trait-path.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/gat-in-trait-path.rs:22:17
|
LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/gat-in-trait-path.rs:6:10
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | type A<'a> where Self: 'a;
| ^ ...because it contains the generic associated type `A`
= help: consider moving `A` to another trait
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
Fooy
Fooer<T>

error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/gat-in-trait-path.rs:28:5
|
LL | f(Box::new(foo));
| ^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/gat-in-trait-path.rs:6:10
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | type A<'a> where Self: 'a;
| ^ ...because it contains the generic associated type `A`
= help: consider moving `A` to another trait
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
Fooy
Fooer<T>

error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/gat-in-trait-path.rs:28:5
|
LL | f(Box::new(foo));
| ^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/gat-in-trait-path.rs:6:10
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | type A<'a> where Self: 'a;
| ^ ...because it contains the generic associated type `A`
= help: consider moving `A` to another trait
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
Fooy
Fooer<T>
= note: required for the cast from `Box<Fooer<{integer}>>` to `Box<(dyn Foo<A<'a> = &'a ()> + 'static)>`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0038`.
9 changes: 2 additions & 7 deletions tests/ui/generic-associated-types/issue-67510-pass.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
//@ revisions: base extended
//@[base] check-fail
//@[extended] check-pass

#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]
//@ check-fail

trait X {
type Y<'a>;
}

fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
//[base]~^ ERROR the trait `X` cannot be made into an object
//~^ ERROR the trait `X` cannot be made into an object

fn main() {}
18 changes: 18 additions & 0 deletions tests/ui/generic-associated-types/issue-67510-pass.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error[E0038]: the trait `X` cannot be made into an object
--> $DIR/issue-67510-pass.rs:7:23
|
LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
| ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
|
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-67510-pass.rs:4:10
|
LL | trait X {
| - this trait cannot be made into an object...
LL | type Y<'a>;
| ^ ...because it contains the generic associated type `Y`
= help: consider moving `Y` to another trait

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0038`.
9 changes: 2 additions & 7 deletions tests/ui/generic-associated-types/issue-76535.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
//@ revisions: base extended

#![cfg_attr(extended, feature(generic_associated_types_extended))]
#![cfg_attr(extended, allow(incomplete_features))]

pub trait SubTrait {}

pub trait SuperTrait {
Expand Down Expand Up @@ -38,6 +33,6 @@ impl SuperTrait for SuperStruct {
fn main() {
let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
//~^ ERROR missing generics for associated type
//[base]~^^ ERROR the trait
//[base]~| ERROR the trait
//~^^ ERROR the trait
//~| ERROR the trait
}
55 changes: 55 additions & 0 deletions tests/ui/generic-associated-types/issue-76535.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
error[E0107]: missing generics for associated type `SuperTrait::SubType`
--> $DIR/issue-76535.rs:34:33
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/issue-76535.rs:4:10
|
LL | type SubType<'a>: SubTrait where Self: 'a;
| ^^^^^^^ --
help: add missing lifetime argument
|
LL | let sub: Box<dyn SuperTrait<SubType<'a> = SubStruct>> = Box::new(SuperStruct::new(0));
| ++++

error[E0038]: the trait `SuperTrait` cannot be made into an object
--> $DIR/issue-76535.rs:34:14
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
|
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-76535.rs:4:10
|
LL | pub trait SuperTrait {
| ---------- this trait cannot be made into an object...
LL | type SubType<'a>: SubTrait where Self: 'a;
| ^^^^^^^ ...because it contains the generic associated type `SubType`
= help: consider moving `SubType` to another trait
= help: only type `SuperStruct` is seen to implement the trait in this crate, consider using it directly instead
= note: `SuperTrait` can be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type

error[E0038]: the trait `SuperTrait` cannot be made into an object
--> $DIR/issue-76535.rs:34:57
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
|
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-76535.rs:4:10
|
LL | pub trait SuperTrait {
| ---------- this trait cannot be made into an object...
LL | type SubType<'a>: SubTrait where Self: 'a;
| ^^^^^^^ ...because it contains the generic associated type `SubType`
= help: consider moving `SubType` to another trait
= help: only type `SuperStruct` is seen to implement the trait in this crate, consider using it directly instead
= note: `SuperTrait` can be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type
= note: required for the cast from `Box<SuperStruct>` to `Box<dyn SuperTrait<SubType<'_> = SubStruct<'_>>>`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0038, E0107.
For more information about an error, try `rustc --explain E0038`.
Loading

0 comments on commit 12519a6

Please sign in to comment.