1
Fork 0

Don't require specifying unrelated assoc types when trait alias is in dyn type

This commit is contained in:
Michael Goulet 2024-03-07 01:32:01 +00:00
parent 7d3702e472
commit 850cc34da2
4 changed files with 55 additions and 50 deletions

View file

@ -45,10 +45,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
dummy_self, dummy_self,
&mut bounds, &mut bounds,
false, false,
// FIXME: This should be `true`, but we don't really handle // True so we don't populate `bounds` with associated type bounds, even
// associated type bounds or type aliases in objects in a way // though they're disallowed from object types.
// that makes this meaningful, I think. OnlySelfBounds(true),
OnlySelfBounds(false),
) { ) {
potential_assoc_types.extend(cur_potential_assoc_types); potential_assoc_types.extend(cur_potential_assoc_types);
} }
@ -83,9 +82,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let expanded_traits = let expanded_traits =
traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b)| (a, b))); traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b)| (a, b)));
let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) =
.filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self) expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
if regular_traits.len() > 1 { if regular_traits.len() > 1 {
let first_trait = &regular_traits[0]; let first_trait = &regular_traits[0];
let additional_trait = &regular_traits[1]; let additional_trait = &regular_traits[1];
@ -158,7 +156,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
for (base_trait_ref, span) in regular_traits_refs_spans { for (base_trait_ref, span) in regular_traits_refs_spans {
let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx); let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx);
for pred in traits::elaborate(tcx, [base_pred]) { for pred in traits::elaborate(tcx, [base_pred]).filter_only_self() {
debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", pred); debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", pred);
let bound_predicate = pred.kind(); let bound_predicate = pred.kind();
@ -312,12 +310,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}) })
}); });
let existential_projections = projection_bounds let existential_projections = projection_bounds.iter().map(|(bound, _)| {
.iter()
// We filter out traits that don't have `Self` as their self type above,
// we need to do the same for projections.
.filter(|(bound, _)| bound.skip_binder().self_ty() == dummy_self)
.map(|(bound, _)| {
bound.map_bound(|mut b| { bound.map_bound(|mut b| {
assert_eq!(b.projection_ty.self_ty(), dummy_self); assert_eq!(b.projection_ty.self_ty(), dummy_self);
@ -330,10 +323,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
false false
}); });
if references_self { if references_self {
let guar = tcx.dcx().span_delayed_bug( let guar = tcx
span, .dcx()
"trait object projection bounds reference `Self`", .span_delayed_bug(span, "trait object projection bounds reference `Self`");
);
let args: Vec<_> = b let args: Vec<_> = b
.projection_ty .projection_ty
.args .args

View file

@ -127,7 +127,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
} }
// Get components of trait alias. // Get components of trait alias.
let predicates = tcx.implied_predicates_of(trait_ref.def_id()); let predicates = tcx.super_predicates_of(trait_ref.def_id());
debug!(?predicates); debug!(?predicates);
let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| { let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {

View file

@ -1,11 +1,8 @@
error[E0191]: the value of the associated types `Item`, `Item`, `IntoIter` and `IntoIter` in `IntoIterator` must be specified error[E0191]: the value of the associated types `Item` and `IntoIter` in `IntoIterator` must be specified
--> $DIR/overlaping-bound-suggestion.rs:7:13 --> $DIR/overlaping-bound-suggestion.rs:7:13
| |
LL | inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core, LL | inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated types: `IntoIterator<Item: IntoIterator<Item: >, Item = Type, IntoIter = Type>`
| | |
| | associated types `Item`, `IntoIter` must be specified
| associated types `Item`, `IntoIter` must be specified
error[E0223]: ambiguous associated type error[E0223]: ambiguous associated type
--> $DIR/overlaping-bound-suggestion.rs:7:13 --> $DIR/overlaping-bound-suggestion.rs:7:13

View file

@ -0,0 +1,16 @@
//@ check-pass
#![feature(trait_alias)]
trait Foo<T> {}
trait Bar { type Assoc; }
trait Alias<T: Bar> = Foo<T>;
// Check that an alias only requires us to specify the associated types
// of the principal's supertraits. For example, we shouldn't require
// specifying the type `Assoc` on trait `Bar` just because we have some
// `T: Bar` where clause on the alias... because that makes no sense.
fn use_alias<T: Bar>(x: &dyn Alias<T>) {}
fn main() {}