diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs index 7b8e09943df71..542ea1244d4af 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs @@ -234,7 +234,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .filter(|item| item.is_type() || item.is_const()) // Traits with RPITITs are simply not dyn compatible (for now). .filter(|item| !item.is_impl_trait_in_trait()) - .map(|item| (item.def_id, trait_ref)), + .map(|item| (item, trait_ref)), ); } ty::ClauseKind::Projection(pred) => { @@ -314,14 +314,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut missing_assoc_items = FxIndexSet::default(); let projection_bounds: Vec<_> = ordered_associated_items .into_iter() - .filter_map(|key @ (def_id, _)| { - if let Some(&assoc) = projection_bounds.get(&key) { + .filter_map(|(item, trait_ref)| { + let def_id = item.def_id; + let key = (def_id, trait_ref); + if let Some(&(assoc, _)) = projection_bounds.get(&key) { return Some(assoc); } - if !tcx.generics_require_sized_self(def_id) { + let has_default = item.defaultness(tcx).has_value(); + if !has_default && !tcx.generics_require_sized_self(def_id) { missing_assoc_items.insert(key); } - None + if has_default { + Some(trait_ref.map_bound(|trait_ref| ty::ProjectionPredicate { + projection_term: ty::AliasTerm::new_from_args(tcx, def_id, trait_ref.args), + term: tcx.type_of(def_id).instantiate(tcx, trait_ref.args).into(), + })) + } else { + None + } }) .collect(); @@ -394,7 +404,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) }); - let existential_projections = projection_bounds.into_iter().map(|(bound, _)| { + let existential_projections = projection_bounds.into_iter().map(|bound| { bound.map_bound(|mut b| { assert_eq!(b.projection_term.self_ty(), dummy_self); diff --git a/tests/ui/associated-types/defaults-on-trait-object-cycle.rs b/tests/ui/associated-types/defaults-on-trait-object-cycle.rs new file mode 100644 index 0000000000000..57a2418268ee6 --- /dev/null +++ b/tests/ui/associated-types/defaults-on-trait-object-cycle.rs @@ -0,0 +1,14 @@ +#![feature(associated_type_defaults)] + +trait Foo { + // This causes cycle, as being effectively `Box>>>`. + type Assoc = Box; + //~^ ERROR: cycle detected when computing type of `Foo::Assoc` +} + +trait Bar { + // This does not. + type Assoc = Box>; +} + +fn main() {} diff --git a/tests/ui/associated-types/defaults-on-trait-object-cycle.stderr b/tests/ui/associated-types/defaults-on-trait-object-cycle.stderr new file mode 100644 index 0000000000000..5bc38584c4757 --- /dev/null +++ b/tests/ui/associated-types/defaults-on-trait-object-cycle.stderr @@ -0,0 +1,17 @@ +error[E0391]: cycle detected when computing type of `Foo::Assoc` + --> $DIR/defaults-on-trait-object-cycle.rs:5:5 + | +LL | type Assoc = Box; + | ^^^^^^^^^^ + | + = note: ...which immediately requires computing type of `Foo::Assoc` again +note: cycle used when checking that `Foo` is well-formed + --> $DIR/defaults-on-trait-object-cycle.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/associated-types/defaults-on-trait-object.rs b/tests/ui/associated-types/defaults-on-trait-object.rs new file mode 100644 index 0000000000000..660996a96408a --- /dev/null +++ b/tests/ui/associated-types/defaults-on-trait-object.rs @@ -0,0 +1,33 @@ +#![feature(associated_type_defaults)] + +trait Foo { + type Assoc: Default = (); + + fn foo(&self) -> Self::Assoc { + Default::default() + } +} + +// The assoc type constraint can be omitted for the assoc type with a default. +type FooObj = Box; + +trait Bar { + type Assoc1 = i32; + type Assoc2; +} + +// We can't omit assoc type constraints for an assoc type without a default value. +type BarObj1 = Box; +//~^ ERROR: the value of the associated type `Assoc2` in `Bar` must be specified + +type BarObj2 = Box>; + +type BarObj3 = Box>; + +fn check_projs(foo1: &dyn Foo, foo2: &dyn Foo) { + let _: () = foo1.foo(); + let _: () = foo2.foo(); + //~^ ERROR: mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-types/defaults-on-trait-object.stderr b/tests/ui/associated-types/defaults-on-trait-object.stderr new file mode 100644 index 0000000000000..521e47da28e03 --- /dev/null +++ b/tests/ui/associated-types/defaults-on-trait-object.stderr @@ -0,0 +1,26 @@ +error[E0191]: the value of the associated type `Assoc2` in `Bar` must be specified + --> $DIR/defaults-on-trait-object.rs:20:24 + | +LL | type Assoc2; + | ----------- `Assoc2` defined here +... +LL | type BarObj1 = Box; + | ^^^ + | +help: specify the associated type + | +LL | type BarObj1 = Box>; + | +++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/defaults-on-trait-object.rs:29:17 + | +LL | let _: () = foo2.foo(); + | -- ^^^^^^^^^^ expected `()`, found `bool` + | | + | expected due to this + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0191, E0308. +For more information about an error, try `rustc --explain E0191`. diff --git a/tests/ui/associated-types/issue-23595-1.rs b/tests/ui/associated-types/issue-23595-1.rs index 579fde34f53b4..ebb0ea2b1aa5a 100644 --- a/tests/ui/associated-types/issue-23595-1.rs +++ b/tests/ui/associated-types/issue-23595-1.rs @@ -6,7 +6,8 @@ trait Hierarchy { type Value; type ChildKey; type Children = dyn Index; - //~^ ERROR: the value of the associated types + //~^ ERROR: cycle detected when computing type of `Hierarchy::Children` + //~| ERROR: the value of the associated types fn data(&self) -> Option<(Self::Value, Self::Children)>; } diff --git a/tests/ui/associated-types/issue-23595-1.stderr b/tests/ui/associated-types/issue-23595-1.stderr index 11f6889702cc9..ab1c7492ce68b 100644 --- a/tests/ui/associated-types/issue-23595-1.stderr +++ b/tests/ui/associated-types/issue-23595-1.stderr @@ -1,4 +1,18 @@ -error[E0191]: the value of the associated types `Value`, `ChildKey` and `Children` in `Hierarchy` must be specified +error[E0391]: cycle detected when computing type of `Hierarchy::Children` + --> $DIR/issue-23595-1.rs:8:5 + | +LL | type Children = dyn Index; + | ^^^^^^^^^^^^^ + | + = note: ...which immediately requires computing type of `Hierarchy::Children` again +note: cycle used when checking that `Hierarchy` is well-formed + --> $DIR/issue-23595-1.rs:5:1 + | +LL | trait Hierarchy { + | ^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0191]: the value of the associated types `Value` and `ChildKey` in `Hierarchy` must be specified --> $DIR/issue-23595-1.rs:8:60 | LL | type Value; @@ -6,13 +20,14 @@ LL | type Value; LL | type ChildKey; | ------------- `ChildKey` defined here LL | type Children = dyn Index; - | ------------- `Children` defined here ^^^^^^^^^ + | ^^^^^^^^^ | help: specify the associated types | -LL | type Children = dyn Index>; - | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LL | type Children = dyn Index>; + | +++++++++++++++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0191`. +Some errors have detailed explanations: E0191, E0391. +For more information about an error, try `rustc --explain E0191`.