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)
}
_ => { }
}
}
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 \
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 {
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) => {
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
{