Skip to content

Commit a4c4cd8

Browse files
committed
coercion: restrict the use of snapshots to two cases.
1 parent ada3110 commit a4c4cd8

File tree

2 files changed

+16
-33
lines changed

2 files changed

+16
-33
lines changed

src/librustc_typeck/check/coercion.rs

+15-32
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,13 @@ use middle::traits::{predicate_for_trait_def, report_selection_error};
6868
use middle::ty::{AutoDerefRef, AdjustDerefRef};
6969
use middle::ty::{self, TypeAndMut, Ty, TypeError};
7070
use middle::ty_relate::RelateResult;
71-
use util::common::indent;
7271

73-
use std::cell::RefCell;
7472
use std::collections::VecDeque;
7573
use syntax::ast;
7674

7775
struct Coerce<'a, 'tcx: 'a> {
7876
fcx: &'a FnCtxt<'a, 'tcx>,
79-
origin: infer::TypeOrigin,
80-
unsizing_obligations: RefCell<Vec<traits::PredicateObligation<'tcx>>>,
77+
origin: infer::TypeOrigin
8178
}
8279

8380
type CoerceResult<'tcx> = RelateResult<'tcx, Option<ty::AutoAdjustment<'tcx>>>;
@@ -101,7 +98,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
10198
debug!("coerce({:?} => {:?})", a, b);
10299

103100
// Consider coercing the subtype to a DST
104-
let unsize = self.coerce_unsized(a, b);
101+
let unsize = self.fcx.infcx().commit_if_ok(|_| self.coerce_unsized(a, b));
105102
if unsize.is_ok() {
106103
return unsize;
107104
}
@@ -311,9 +308,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
311308
}
312309
}
313310

314-
let mut obligations = self.unsizing_obligations.borrow_mut();
315-
assert!(obligations.is_empty());
316-
*obligations = leftover_predicates;
311+
// Save all the obligations that are not for CoerceUnsized or Unsize.
312+
for obligation in leftover_predicates {
313+
self.fcx.register_predicate(obligation);
314+
}
317315

318316
let adjustment = AutoDerefRef {
319317
autoderefs: if reborrow.is_some() { 1 } else { 0 },
@@ -395,8 +393,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
395393

396394
// Check that the types which they point at are compatible.
397395
let a_unsafe = self.tcx().mk_ptr(ty::TypeAndMut{ mutbl: mutbl_b, ty: mt_a.ty });
398-
try!(self.subtype(a_unsafe, b));
399-
try!(coerce_mutbls(mt_a.mutbl, mutbl_b));
396+
try!(self.fcx.infcx().commit_if_ok(|_| {
397+
try!(self.subtype(a_unsafe, b));
398+
coerce_mutbls(mt_a.mutbl, mutbl_b)
399+
}));
400400

401401
// Although references and unsafe ptrs have the same
402402
// representation, we still register an AutoDerefRef so that
@@ -419,29 +419,12 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
419419
b: Ty<'tcx>)
420420
-> RelateResult<'tcx, ()> {
421421
debug!("mk_assignty({:?} -> {:?})", a, b);
422-
let mut unsizing_obligations = vec![];
423-
let adjustment = try!(indent(|| {
424-
fcx.infcx().commit_if_ok(|_| {
425-
let coerce = Coerce {
426-
fcx: fcx,
427-
origin: infer::ExprAssignable(expr.span),
428-
unsizing_obligations: RefCell::new(vec![])
429-
};
430-
let adjustment = try!(coerce.coerce(expr, a, b));
431-
unsizing_obligations = coerce.unsizing_obligations.into_inner();
432-
Ok(adjustment)
433-
})
434-
}));
435-
436-
if let Some(AdjustDerefRef(auto)) = adjustment {
437-
if auto.unsize.is_some() {
438-
for obligation in unsizing_obligations {
439-
fcx.register_predicate(obligation);
440-
}
441-
}
442-
}
422+
let coerce = Coerce {
423+
fcx: fcx,
424+
origin: infer::ExprAssignable(expr.span)
425+
};
443426

444-
if let Some(adjustment) = adjustment {
427+
if let Some(adjustment) = try!(coerce.coerce(expr, a, b)) {
445428
debug!("Success, coerced with {:?}", adjustment);
446429
fcx.write_adjustment(expr.id, adjustment);
447430
}

src/test/compile-fail/destructure-trait-ref.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn main() {
3535
// n == m
3636
let &x = &1isize as &T; //~ ERROR type `&T` cannot be dereferenced
3737
let &&x = &(&1isize as &T); //~ ERROR type `&T` cannot be dereferenced
38-
let box x = box 1isize as Box<T>; //~ ERROR the trait `core::marker::Sized` is not implemented
38+
let box x = box 1isize as Box<T>; //~ ERROR type `Box<T>` cannot be dereferenced
3939

4040
// n > m
4141
let &&x = &1isize as &T;

0 commit comments

Comments
 (0)