Skip to content

Commit a56820b

Browse files
committed
Allowing dropping principal when unsizing dyn Trait+A -> dyn A
1 parent 068433d commit a56820b

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

chalk-solve/src/clauses/builtin_traits/unsize.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,10 @@ pub fn add_unsize_program_clauses<I: Interner>(
221221

222222
let auto_trait_ids_b: Vec<_> = auto_trait_ids(db, bounds_b).collect();
223223

224-
let may_apply = principal_a == principal_b
224+
// If B has a principal, then A must as well
225+
// (i.e. we allow dropping principal, but not creating a principal out of thin air).
226+
// `AutoB` must be a subset of `AutoA`.
227+
let may_apply = principal_a.is_some() >= principal_b.is_some()
225228
&& auto_trait_ids_b
226229
.iter()
227230
.all(|id_b| auto_trait_ids_a.iter().any(|id_a| id_a == id_b));
@@ -274,7 +277,10 @@ pub fn add_unsize_program_clauses<I: Interner>(
274277

275278
// The only "implements" bound that is not an auto trait, is the principal
276279
assert_eq!(Some(trait_id), principal_a);
277-
Some(bound)
280+
281+
// Only include principal_a if the principal_b is also present
282+
// (this allows dropping principal, `dyn Tr+A -> dyn A`)
283+
principal_b.is_some().then(|| bound)
278284
})
279285
// Add auto traits from B (again, they are already checked above).
280286
.chain(bounds_b.skip_binders().iter(interner).cloned().filter(

tests/test/unsize.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ fn dyn_to_dyn_unsizing() {
110110
dyn Principal + Auto1 + 'a: Unsize<dyn Auto1 + 'a>
111111
}
112112
} yields {
113-
expect![["No possible solution"]]
113+
expect!["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]"]
114114
}
115115

116116
// Non-matching principal traits

0 commit comments

Comments
 (0)