Skip to content

Commit

Permalink
Remove generic_associated_types_extended feature gate
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Dec 2, 2024
1 parent 3bff51e commit 4eed6f6
Show file tree
Hide file tree
Showing 24 changed files with 312 additions and 125 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.

11 changes: 2 additions & 9 deletions tests/ui/generic-associated-types/extended/lending_iterator.rs
Original file line number Diff line number Diff line change
@@ -1,17 +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))]

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
//~^ impl has stricter
let mut v = vec![];
while let Some(item) = iter.next() {
v.push(item);
Expand All @@ -32,7 +25,7 @@ pub trait LendingIterator {
Self: for<'q> LendingIterator<Item<'q> = A>,
{
<B as FromLendingIterator<A>>::from_iter(self)
//[base]~^ ERROR: does not live long enough
//~^ 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:6: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:27:9
|
LL | <B as FromLendingIterator<A>>::from_iter(self)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +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))]

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
//~^ 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
@@ -0,0 +1,12 @@
error[E0276]: impl has stricter requirements than trait
--> $DIR/lending_iterator_2.rs:6:45
|
LL | fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
| ------------------------------------------------------------------------ definition of `from_iter` from trait
...
LL | fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
| ^^^^^^^^^^^^ impl has extra requirement `I: 'x`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0276`.
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 4eed6f6

Please sign in to comment.