Skip to content

Commit 77da9de

Browse files
author
Ariel Ben-Yehuda
authored
Rollup merge of rust-lang#40319 - eddyb:it's-"unsize"-not-"unsound", r=nikomatsakis
Disallow subtyping between T and U in T: Unsize<U>. Because `&mut T` can be coerced to `&mut U`, `T` and `U` must be unified invariantly. Fixes rust-lang#40288. E.g. coercing `&mut [&'a X; N]` to `&mut [&'b X]` must require `'a` be equal to `'b`, otherwise you can convert between `&'a X` and `&'b X` (in either direction), potentially unsoundly lengthening lifetimes. Subtyping here was introduced with `Unsize` in rust-lang#24619 (landed in 1.1, original PR is rust-lang#23785).
2 parents a658211 + cfb41ae commit 77da9de

14 files changed

+249
-130
lines changed

src/librustc/traits/select.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2461,7 +2461,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
24612461
let new_trait = tcx.mk_dynamic(
24622462
ty::Binder(tcx.mk_existential_predicates(iter)), r_b);
24632463
let InferOk { obligations, .. } =
2464-
self.infcx.sub_types(false, &obligation.cause, new_trait, target)
2464+
self.infcx.eq_types(false, &obligation.cause, new_trait, target)
24652465
.map_err(|_| Unimplemented)?;
24662466
self.inferred_obligations.extend(obligations);
24672467

@@ -2520,7 +2520,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
25202520
// [T; n] -> [T].
25212521
(&ty::TyArray(a, _), &ty::TySlice(b)) => {
25222522
let InferOk { obligations, .. } =
2523-
self.infcx.sub_types(false, &obligation.cause, a, b)
2523+
self.infcx.eq_types(false, &obligation.cause, a, b)
25242524
.map_err(|_| Unimplemented)?;
25252525
self.inferred_obligations.extend(obligations);
25262526
}
@@ -2583,7 +2583,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
25832583
});
25842584
let new_struct = tcx.mk_adt(def, tcx.mk_substs(params));
25852585
let InferOk { obligations, .. } =
2586-
self.infcx.sub_types(false, &obligation.cause, new_struct, target)
2586+
self.infcx.eq_types(false, &obligation.cause, new_struct, target)
25872587
.map_err(|_| Unimplemented)?;
25882588
self.inferred_obligations.extend(obligations);
25892589

src/librustc_typeck/check/autoderef.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use astconv::AstConv;
1212

1313
use super::FnCtxt;
1414

15+
use rustc::infer::InferOk;
1516
use rustc::traits;
1617
use rustc::ty::{self, Ty, TraitRef};
1718
use rustc::ty::{ToPredicate, TypeFoldable};
@@ -149,6 +150,14 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
149150

150151
pub fn finalize<'b, I>(self, pref: LvaluePreference, exprs: I)
151152
where I: IntoIterator<Item = &'b hir::Expr>
153+
{
154+
let fcx = self.fcx;
155+
fcx.register_infer_ok_obligations(self.finalize_as_infer_ok(pref, exprs));
156+
}
157+
158+
pub fn finalize_as_infer_ok<'b, I>(self, pref: LvaluePreference, exprs: I)
159+
-> InferOk<'tcx, ()>
160+
where I: IntoIterator<Item = &'b hir::Expr>
152161
{
153162
let methods: Vec<_> = self.steps
154163
.iter()
@@ -176,8 +185,9 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
176185
}
177186
}
178187

179-
for obligation in self.obligations {
180-
self.fcx.register_predicate(obligation);
188+
InferOk {
189+
value: (),
190+
obligations: self.obligations
181191
}
182192
}
183193
}

0 commit comments

Comments
 (0)