@@ -56,7 +56,6 @@ use middle::resolve_lifetime;
56
56
use middle:: infer;
57
57
use middle:: stability;
58
58
use middle:: subst:: { mod, Subst , Substs , VecPerParamSpace } ;
59
- use middle:: traits:: ObligationCause ;
60
59
use middle:: traits;
61
60
use middle:: ty;
62
61
use middle:: ty_fold:: { mod, TypeFoldable , TypeFolder } ;
@@ -65,7 +64,7 @@ use util::ppaux::{trait_store_to_string, ty_to_string};
65
64
use util:: ppaux:: { Repr , UserString } ;
66
65
use util:: common:: { indenter, memoized, ErrorReported } ;
67
66
use util:: nodemap:: { NodeMap , NodeSet , DefIdMap , DefIdSet } ;
68
- use util:: nodemap:: { FnvHashMap , FnvHashSet } ;
67
+ use util:: nodemap:: { FnvHashMap } ;
69
68
70
69
use arena:: TypedArena ;
71
70
use std:: borrow:: BorrowFrom ;
@@ -80,13 +79,13 @@ use collections::enum_set::{EnumSet, CLike};
80
79
use std:: collections:: { HashMap , HashSet } ;
81
80
use std:: collections:: hash_map:: Entry :: { Occupied , Vacant } ;
82
81
use syntax:: abi;
83
- use syntax:: ast:: { CrateNum , DefId , DUMMY_NODE_ID , Ident , ItemTrait , LOCAL_CRATE } ;
82
+ use syntax:: ast:: { CrateNum , DefId , Ident , ItemTrait , LOCAL_CRATE } ;
84
83
use syntax:: ast:: { MutImmutable , MutMutable , Name , NamedField , NodeId } ;
85
84
use syntax:: ast:: { Onceness , StmtExpr , StmtSemi , StructField , UnnamedField } ;
86
85
use syntax:: ast:: { Visibility } ;
87
86
use syntax:: ast_util:: { mod, is_local, lit_is_str, local_def, PostExpansionMethod } ;
88
87
use syntax:: attr:: { mod, AttrMetaMethods } ;
89
- use syntax:: codemap:: { DUMMY_SP , Span } ;
88
+ use syntax:: codemap:: Span ;
90
89
use syntax:: parse:: token:: { mod, InternedString } ;
91
90
use syntax:: { ast, ast_map} ;
92
91
@@ -756,8 +755,15 @@ pub struct ctxt<'tcx> {
756
755
/// Caches the representation hints for struct definitions.
757
756
pub repr_hint_cache : RefCell < DefIdMap < Rc < Vec < attr:: ReprAttr > > > > ,
758
757
759
- /// Caches whether types move by default.
760
- pub type_moves_by_default_cache : RefCell < HashMap < Ty < ' tcx > , bool > > ,
758
+ /// Caches whether types are known to impl Copy. Note that type
759
+ /// parameters are never placed into this cache, because their
760
+ /// results are dependent on the parameter environment.
761
+ pub type_impls_copy_cache : RefCell < HashMap < Ty < ' tcx > , bool > > ,
762
+
763
+ /// Caches whether types are known to impl Sized. Note that type
764
+ /// parameters are never placed into this cache, because their
765
+ /// results are dependent on the parameter environment.
766
+ pub type_impls_sized_cache : RefCell < HashMap < Ty < ' tcx > , bool > > ,
761
767
}
762
768
763
769
// Flags that we track on types. These flags are propagated upwards
@@ -2040,7 +2046,8 @@ pub fn mk_ctxt<'tcx>(s: Session,
2040
2046
associated_types : RefCell :: new ( DefIdMap :: new ( ) ) ,
2041
2047
selection_cache : traits:: SelectionCache :: new ( ) ,
2042
2048
repr_hint_cache : RefCell :: new ( DefIdMap :: new ( ) ) ,
2043
- type_moves_by_default_cache : RefCell :: new ( HashMap :: new ( ) ) ,
2049
+ type_impls_copy_cache : RefCell :: new ( HashMap :: new ( ) ) ,
2050
+ type_impls_sized_cache : RefCell :: new ( HashMap :: new ( ) ) ,
2044
2051
}
2045
2052
}
2046
2053
@@ -2657,14 +2664,6 @@ pub fn type_is_unique(ty: Ty) -> bool {
2657
2664
}
2658
2665
}
2659
2666
2660
- pub fn type_is_fat_ptr < ' tcx > ( cx : & ctxt < ' tcx > , ty : Ty < ' tcx > ) -> bool {
2661
- match ty. sty {
2662
- ty_ptr( mt { ty, ..} ) | ty_rptr( _, mt { ty, ..} )
2663
- | ty_uniq( ty) if !type_is_sized ( cx, ty) => true ,
2664
- _ => false ,
2665
- }
2666
- }
2667
-
2668
2667
/*
2669
2668
A scalar type is one that denotes an atomic datum, with no sub-components.
2670
2669
(A ty_ptr is scalar because it represents a non-managed pointer, so its
@@ -3154,45 +3153,58 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
3154
3153
}
3155
3154
}
3156
3155
3157
- pub fn type_moves_by_default < ' tcx > ( cx : & ctxt < ' tcx > ,
3158
- ty : Ty < ' tcx > ,
3159
- param_env : & ParameterEnvironment < ' tcx > )
3160
- -> bool
3156
+ fn type_impls_bound < ' tcx > ( cx : & ctxt < ' tcx > ,
3157
+ cache : & RefCell < HashMap < Ty < ' tcx > , bool > > ,
3158
+ param_env : & ParameterEnvironment < ' tcx > ,
3159
+ ty : Ty < ' tcx > ,
3160
+ bound : ty:: BuiltinBound )
3161
+ -> bool
3161
3162
{
3163
+ assert ! ( !ty:: type_needs_infer( ty) ) ;
3164
+
3162
3165
if !type_has_params ( ty) && !type_has_self ( ty) {
3163
- match cx . type_moves_by_default_cache . borrow ( ) . get ( & ty) {
3166
+ match cache . borrow ( ) . get ( & ty) {
3164
3167
None => { }
3165
3168
Some ( & result) => {
3166
- debug ! ( "determined whether {} moves by default (cached): {} " ,
3169
+ debug ! ( "type_impls_bound({}, {}) = {} (cached)" ,
3167
3170
ty_to_string( cx, ty) ,
3171
+ bound,
3168
3172
result) ;
3169
3173
return result
3170
3174
}
3171
3175
}
3172
3176
}
3173
3177
3174
3178
let infcx = infer:: new_infer_ctxt ( cx) ;
3175
- let mut fulfill_cx = traits:: FulfillmentContext :: new ( ) ;
3179
+ let is_impld = traits:: type_known_to_meet_builtin_bound ( & infcx , param_env , ty , bound ) ;
3176
3180
3177
- // we can use dummy values here because we won't report any errors
3178
- // that result nor will we pay any mind to region obligations that arise
3179
- // (there shouldn't really be any anyhow)
3180
- let cause = ObligationCause :: misc ( DUMMY_SP , DUMMY_NODE_ID ) ;
3181
+ debug ! ( "type_impls_bound({}, {}) = {}" ,
3182
+ ty_to_string ( cx , ty ) ,
3183
+ bound ,
3184
+ is_impld ) ;
3181
3185
3182
- fulfill_cx. register_builtin_bound ( cx, ty, ty:: BoundCopy , cause) ;
3186
+ if !type_has_params ( ty) && !type_has_self ( ty) {
3187
+ let old_value = cache. borrow_mut ( ) . insert ( ty, is_impld) ;
3188
+ assert ! ( old_value. is_none( ) ) ;
3189
+ }
3183
3190
3184
- // Note: we only assuming something is `Copy` if we can
3185
- // *definitively* show that it implements `Copy`. Otherwise,
3186
- // assume it is move; linear is always ok.
3187
- let is_copy = fulfill_cx. select_all_or_error ( & infcx, param_env, cx) . is_ok ( ) ;
3188
- let is_move = !is_copy;
3191
+ is_impld
3192
+ }
3189
3193
3190
- debug ! ( "determined whether {} moves by default: {}" ,
3191
- ty_to_string( cx, ty) ,
3192
- is_move) ;
3194
+ pub fn type_moves_by_default < ' tcx > ( cx : & ctxt < ' tcx > ,
3195
+ ty : Ty < ' tcx > ,
3196
+ param_env : & ParameterEnvironment < ' tcx > )
3197
+ -> bool
3198
+ {
3199
+ !type_impls_bound ( cx, & cx. type_impls_copy_cache , param_env, ty, ty:: BoundCopy )
3200
+ }
3193
3201
3194
- cx. type_moves_by_default_cache . borrow_mut ( ) . insert ( ty, is_move) ;
3195
- is_move
3202
+ pub fn type_is_sized < ' tcx > ( cx : & ctxt < ' tcx > ,
3203
+ ty : Ty < ' tcx > ,
3204
+ param_env : & ParameterEnvironment < ' tcx > )
3205
+ -> bool
3206
+ {
3207
+ type_impls_bound ( cx, & cx. type_impls_sized_cache , param_env, ty, ty:: BoundSized )
3196
3208
}
3197
3209
3198
3210
pub fn is_ffi_safe < ' tcx > ( cx : & ctxt < ' tcx > , ty : Ty < ' tcx > ) -> bool {
@@ -3564,40 +3576,6 @@ pub fn type_is_machine(ty: Ty) -> bool {
3564
3576
}
3565
3577
}
3566
3578
3567
- // Is the type's representation size known at compile time?
3568
- pub fn type_is_sized < ' tcx > ( cx : & ctxt < ' tcx > , ty : Ty < ' tcx > ) -> bool {
3569
- type_contents ( cx, ty) . is_sized ( cx)
3570
- }
3571
-
3572
- pub fn lltype_is_sized < ' tcx > ( cx : & ctxt < ' tcx > , ty : Ty < ' tcx > ) -> bool {
3573
- match ty. sty {
3574
- ty_open( _) => true ,
3575
- _ => type_contents ( cx, ty) . is_sized ( cx)
3576
- }
3577
- }
3578
-
3579
- // Return the smallest part of `ty` which is unsized. Fails if `ty` is sized.
3580
- // 'Smallest' here means component of the static representation of the type; not
3581
- // the size of an object at runtime.
3582
- pub fn unsized_part_of_type < ' tcx > ( cx : & ctxt < ' tcx > , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
3583
- match ty. sty {
3584
- ty_str | ty_trait( ..) | ty_vec( ..) => ty,
3585
- ty_struct( def_id, ref substs) => {
3586
- let unsized_fields: Vec < _ > = struct_fields ( cx, def_id, substs) . iter ( )
3587
- . map ( |f| f. mt . ty ) . filter ( |ty| !type_is_sized ( cx, * ty) ) . collect ( ) ;
3588
- // Exactly one of the fields must be unsized.
3589
- assert ! ( unsized_fields. len( ) == 1 ) ;
3590
-
3591
- unsized_part_of_type ( cx, unsized_fields[ 0 ] )
3592
- }
3593
- _ => {
3594
- assert ! ( type_is_sized( cx, ty) ,
3595
- "unsized_part_of_type failed even though ty is unsized" ) ;
3596
- panic ! ( "called unsized_part_of_type with sized ty" ) ;
3597
- }
3598
- }
3599
- }
3600
-
3601
3579
// Whether a type is enum like, that is an enum type with only nullary
3602
3580
// constructors
3603
3581
pub fn type_is_c_like_enum ( cx : & ctxt , ty : Ty ) -> bool {
0 commit comments