Looser restrictions on what can be captured in unbounded traits.
This commit is contained in:
parent
7b968783d7
commit
108739f533
3 changed files with 35 additions and 23 deletions
|
@ -423,7 +423,7 @@ type MonitorMsg = (TestDesc, TestResult);
|
||||||
|
|
||||||
fn run_tests(opts: &TestOpts,
|
fn run_tests(opts: &TestOpts,
|
||||||
tests: ~[TestDescAndFn],
|
tests: ~[TestDescAndFn],
|
||||||
callback: @fn(e: TestEvent)) {
|
callback: &fn(e: TestEvent)) {
|
||||||
|
|
||||||
let filtered_tests = filter_tests(opts, tests);
|
let filtered_tests = filter_tests(opts, tests);
|
||||||
let filtered_descs = filtered_tests.map(|t| copy t.desc);
|
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, _) => {
|
expr_cast(source, _) => {
|
||||||
check_cast_for_escaping_regions(cx, source, e);
|
check_cast_for_escaping_regions(cx, source, e);
|
||||||
match ty::get(ty::expr_ty(cx.tcx, e)).sty {
|
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);
|
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,
|
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| {
|
do check_builtin_bounds(cx, ty, bounds) |missing| {
|
||||||
cx.tcx.sess.span_err(sp,
|
cx.tcx.sess.span_err(sp,
|
||||||
fmt!("cannot pack type `%s`, which does not fulfill \
|
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),
|
ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx),
|
||||||
bounds.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 {
|
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)))
|
TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache)))
|
||||||
}
|
}
|
||||||
|
|
||||||
ty_trait(_, _, UniqTraitStore, _, _bounds) => {
|
ty_trait(_, _, store, mutbl, bounds) => {
|
||||||
// FIXME(#3569): Make this conditional on the trait's bounds.
|
trait_contents(store, mutbl, 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_rptr(r, mt) => {
|
ty_rptr(r, mt) => {
|
||||||
|
@ -2278,6 +2266,35 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||||
st + rt + ot
|
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,
|
fn type_param_def_to_contents(cx: ctxt,
|
||||||
type_param_def: &TypeParameterDef) -> TypeContents
|
type_param_def: &TypeParameterDef) -> TypeContents
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue