Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d800540

Browse files
compiler-errorspietroalbini
authored andcommitted
Review
1 parent 2f71d0a commit d800540

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
146146

147147
let principal_trait = regular_traits.into_iter().next();
148148

149-
let mut needed_associated_types = vec![];
149+
// A stable ordering of associated types from the principal trait and all its
150+
// supertraits. We use this to ensure that different substitutions of a trait
151+
// don't result in `dyn Trait` types with different projections lists, which
152+
// can be unsound: <https://github.com/rust-lang/rust/pull/136458>.
153+
// We achieve a stable ordering by walking over the unsubstituted principal
154+
// trait ref.
155+
let mut ordered_associated_types = vec![];
156+
150157
if let Some((principal_trait, ref spans)) = principal_trait {
151158
let principal_trait = principal_trait.map_bound(|trait_pred| {
152159
assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive);
@@ -171,7 +178,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
171178
// FIXME(negative_bounds): Handle this correctly...
172179
let trait_ref =
173180
tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
174-
needed_associated_types.extend(
181+
ordered_associated_types.extend(
175182
tcx.associated_items(pred.trait_ref.def_id)
176183
.in_definition_order()
177184
// We only care about associated types.
@@ -249,15 +256,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
249256
}
250257
}
251258

259+
// We compute the list of projection bounds taking the ordered associated types,
260+
// and check if there was an entry in the collected `projection_bounds`. Those
261+
// are computed by first taking the user-written associated types, then elaborating
262+
// the principal trait ref, and only using those if there was no user-written.
263+
// See note below about how we handle missing associated types with `Self: Sized`,
264+
// which are not required to be provided, but are still used if they are provided.
252265
let mut missing_assoc_types = FxIndexSet::default();
253-
let projection_bounds: Vec<_> = needed_associated_types
266+
let projection_bounds: Vec<_> = ordered_associated_types
254267
.into_iter()
255268
.filter_map(|key| {
256269
if let Some(assoc) = projection_bounds.get(&key) {
257270
Some(*assoc)
258271
} else {
259-
// If the associated type has a `where Self: Sized` bound,
260-
// we do not need to constrain the associated type.
272+
// If the associated type has a `where Self: Sized` bound, then
273+
// we do not need to provide the associated type. This results in
274+
// a `dyn Trait` type that has a different number of projection
275+
// bounds, which may lead to type mismatches.
261276
if !tcx.generics_require_sized_self(key.0) {
262277
missing_assoc_types.insert(key);
263278
}

‎tests/ui/traits/object/constrain-via-unnecessary-bound.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub trait Trait {
1313
}
1414

1515
impl Other for dyn Trait {}
16-
// `dyn Trait<Assoc = ()>` is a different "nominal type" than `dyn Traiat`.
16+
// `dyn Trait<Assoc = ()>` is a different "nominal type" than `dyn Trait`.
1717
impl Other for dyn Trait<Assoc = ()> {}
1818
//~^ WARN unnecessary associated type bound for dyn-incompatible associated type
1919

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /