Looser restrictions on what can be captured in unbounded traits.
This commit is contained in:
parent
7b968783d7
commit
108739f533
@ -423,7 +423,7 @@ type MonitorMsg = (TestDesc, TestResult);
|
||||
|
||||
fn run_tests(opts: &TestOpts,
|
||||
tests: ~[TestDescAndFn],
|
||||
callback: @fn(e: TestEvent)) {
|
||||
callback: &fn(e: TestEvent)) {
|
||||
|
||||
let filtered_tests = filter_tests(opts, tests);
|
||||
let filtered_descs = filtered_tests.map(|t| copy t.desc);
|
||||
|
@ -293,9 +293,9 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt<Context>)) {
|
||||
expr_cast(source, _) => {
|
||||
check_cast_for_escaping_regions(cx, source, e);
|
||||
match ty::get(ty::expr_ty(cx.tcx, e)).sty {
|
||||
ty::ty_trait(_, _, store, _, bounds) => {
|
||||
ty::ty_trait(_, _, _, _, bounds) => {
|
||||
let source_ty = ty::expr_ty(cx.tcx, source);
|
||||
check_trait_cast_bounds(cx, e.span, source_ty, bounds, store)
|
||||
check_trait_cast_bounds(cx, e.span, source_ty, bounds)
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
@ -391,7 +391,7 @@ pub fn check_freevar_bounds(cx: Context, sp: span, ty: ty::t,
|
||||
}
|
||||
|
||||
pub fn check_trait_cast_bounds(cx: Context, sp: span, ty: ty::t,
|
||||
bounds: ty::BuiltinBounds, store: ty::TraitStore) {
|
||||
bounds: ty::BuiltinBounds) {
|
||||
do check_builtin_bounds(cx, ty, bounds) |missing| {
|
||||
cx.tcx.sess.span_err(sp,
|
||||
fmt!("cannot pack type `%s`, which does not fulfill \
|
||||
@ -399,11 +399,6 @@ pub fn check_trait_cast_bounds(cx: Context, sp: span, ty: ty::t,
|
||||
ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx),
|
||||
bounds.user_string(cx.tcx)));
|
||||
}
|
||||
// FIXME(#3569): Remove this check when the corresponding restriction
|
||||
// is made with type contents.
|
||||
if store == ty::UniqTraitStore && !ty::type_is_owned(cx.tcx, ty) {
|
||||
cx.tcx.sess.span_err(sp, "uniquely-owned trait objects must be sendable");
|
||||
}
|
||||
}
|
||||
|
||||
fn is_nullary_variant(cx: Context, ex: @expr) -> bool {
|
||||
|
@ -2063,20 +2063,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||
TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache)))
|
||||
}
|
||||
|
||||
ty_trait(_, _, UniqTraitStore, _, _bounds) => {
|
||||
// FIXME(#3569): Make this conditional on the trait's bounds.
|
||||
TC_NONCOPY_TRAIT + TC_OWNED_POINTER
|
||||
}
|
||||
|
||||
ty_trait(_, _, BoxTraitStore, mutbl, _bounds) => {
|
||||
match mutbl {
|
||||
ast::m_mutbl => TC_MANAGED + TC_MUTABLE,
|
||||
_ => TC_MANAGED
|
||||
}
|
||||
}
|
||||
|
||||
ty_trait(_, _, RegionTraitStore(r), mutbl, _bounds) => {
|
||||
borrowed_contents(r, mutbl)
|
||||
ty_trait(_, _, store, mutbl, bounds) => {
|
||||
trait_contents(store, mutbl, bounds)
|
||||
}
|
||||
|
||||
ty_rptr(r, mt) => {
|
||||
@ -2278,6 +2266,35 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||
st + rt + ot
|
||||
}
|
||||
|
||||
fn trait_contents(store: TraitStore, mutbl: ast::mutability,
|
||||
bounds: BuiltinBounds) -> TypeContents {
|
||||
let st = match store {
|
||||
UniqTraitStore => TC_OWNED_POINTER,
|
||||
BoxTraitStore => TC_MANAGED,
|
||||
RegionTraitStore(r) => borrowed_contents(r, mutbl),
|
||||
};
|
||||
let mt = match mutbl { ast::m_mutbl => TC_MUTABLE, _ => TC_NONE };
|
||||
// We get additional "special type contents" for each bound that *isn't*
|
||||
// on the trait. So iterate over the inverse of the bounds that are set.
|
||||
// This is like with typarams below, but less "pessimistic" and also
|
||||
// dependent on the trait store.
|
||||
let mut bt = TC_NONE;
|
||||
for (AllBuiltinBounds() - bounds).each |bound| {
|
||||
bt = bt + match bound {
|
||||
BoundCopy if store == UniqTraitStore
|
||||
=> TC_NONCOPY_TRAIT,
|
||||
BoundCopy => TC_NONE, // @Trait/&Trait are copyable either way
|
||||
BoundStatic if bounds.contains_elem(BoundOwned)
|
||||
=> TC_NONE, // Owned bound implies static bound.
|
||||
BoundStatic => TC_BORROWED_POINTER, // Useful for "@Trait:'static"
|
||||
BoundOwned => TC_NON_OWNED,
|
||||
BoundConst => TC_MUTABLE,
|
||||
BoundSized => TC_NONE, // don't care if interior is sized
|
||||
};
|
||||
}
|
||||
st + mt + bt
|
||||
}
|
||||
|
||||
fn type_param_def_to_contents(cx: ctxt,
|
||||
type_param_def: &TypeParameterDef) -> TypeContents
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user