@@ -29,6 +29,107 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
29
29
AutoTraitFinder { cx }
30
30
}
31
31
32
+ fn generate_for_trait (
33
+ & mut self ,
34
+ ty : Ty < ' tcx > ,
35
+ trait_def_id : DefId ,
36
+ param_env : ty:: ParamEnv < ' tcx > ,
37
+ param_env_def_id : DefId ,
38
+ f : & auto_trait:: AutoTraitFinder < ' tcx > ,
39
+ // If this is set, show only negative trait implementations, not positive ones.
40
+ discard_positive_impl : bool ,
41
+ ) -> Option < Item > {
42
+ let tcx = self . cx . tcx ;
43
+ let trait_ref = ty:: TraitRef { def_id : trait_def_id, substs : tcx. mk_substs_trait ( ty, & [ ] ) } ;
44
+ if !self . cx . generated_synthetics . borrow_mut ( ) . insert ( ( ty, trait_def_id) ) {
45
+ debug ! ( "get_auto_trait_impl_for({:?}): already generated, aborting" , trait_ref) ;
46
+ return None ;
47
+ }
48
+
49
+ let result = f. find_auto_trait_generics ( ty, param_env, trait_def_id, |infcx, info| {
50
+ let region_data = info. region_data ;
51
+
52
+ let names_map = tcx
53
+ . generics_of ( param_env_def_id)
54
+ . params
55
+ . iter ( )
56
+ . filter_map ( |param| match param. kind {
57
+ ty:: GenericParamDefKind :: Lifetime => Some ( param. name ) ,
58
+ _ => None ,
59
+ } )
60
+ . map ( |name| ( name, Lifetime ( name) ) )
61
+ . collect ( ) ;
62
+ let lifetime_predicates = Self :: handle_lifetimes ( & region_data, & names_map) ;
63
+ let new_generics = self . param_env_to_generics (
64
+ infcx. tcx ,
65
+ param_env_def_id,
66
+ info. full_user_env ,
67
+ lifetime_predicates,
68
+ info. vid_to_region ,
69
+ ) ;
70
+
71
+ debug ! (
72
+ "find_auto_trait_generics(param_env_def_id={:?}, trait_def_id={:?}): \
73
+ finished with {:?}",
74
+ param_env_def_id, trait_def_id, new_generics
75
+ ) ;
76
+
77
+ new_generics
78
+ } ) ;
79
+
80
+ let negative_polarity;
81
+ let new_generics = match result {
82
+ AutoTraitResult :: PositiveImpl ( new_generics) => {
83
+ negative_polarity = false ;
84
+ if discard_positive_impl {
85
+ return None ;
86
+ }
87
+ new_generics
88
+ }
89
+ AutoTraitResult :: NegativeImpl => {
90
+ negative_polarity = true ;
91
+
92
+ // For negative impls, we use the generic params, but *not* the predicates,
93
+ // from the original type. Otherwise, the displayed impl appears to be a
94
+ // conditional negative impl, when it's really unconditional.
95
+ //
96
+ // For example, consider the struct Foo<T: Copy>(*mut T). Using
97
+ // the original predicates in our impl would cause us to generate
98
+ // `impl !Send for Foo<T: Copy>`, which makes it appear that Foo
99
+ // implements Send where T is not copy.
100
+ //
101
+ // Instead, we generate `impl !Send for Foo<T>`, which better
102
+ // expresses the fact that `Foo<T>` never implements `Send`,
103
+ // regardless of the choice of `T`.
104
+ let params = ( tcx. generics_of ( param_env_def_id) , ty:: GenericPredicates :: default ( ) )
105
+ . clean ( self . cx )
106
+ . params ;
107
+
108
+ Generics { params, where_predicates : Vec :: new ( ) }
109
+ }
110
+ AutoTraitResult :: ExplicitImpl => return None ,
111
+ } ;
112
+
113
+ Some ( Item {
114
+ source : Span :: dummy ( ) ,
115
+ name : None ,
116
+ attrs : Default :: default ( ) ,
117
+ visibility : Inherited ,
118
+ def_id : self . cx . next_def_id ( param_env_def_id. krate ) ,
119
+ kind : box ImplItem ( Impl {
120
+ unsafety : hir:: Unsafety :: Normal ,
121
+ generics : new_generics,
122
+ provided_trait_methods : Default :: default ( ) ,
123
+ trait_ : Some ( trait_ref. clean ( self . cx ) . get_trait_type ( ) . unwrap ( ) ) ,
124
+ for_ : ty. clean ( self . cx ) ,
125
+ items : Vec :: new ( ) ,
126
+ negative_polarity,
127
+ synthetic : true ,
128
+ blanket_impl : None ,
129
+ } ) ,
130
+ } )
131
+ }
132
+
32
133
// FIXME(eddyb) figure out a better way to pass information about
33
134
// parametrization of `ty` than `param_env_def_id`.
34
135
crate fn get_auto_trait_impls ( & mut self , ty : Ty < ' tcx > , param_env_def_id : DefId ) -> Vec < Item > {
@@ -38,99 +139,22 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
38
139
39
140
debug ! ( "get_auto_trait_impls({:?})" , ty) ;
40
141
let auto_traits: Vec < _ > = self . cx . auto_traits . iter ( ) . cloned ( ) . collect ( ) ;
41
- auto_traits
142
+ let mut auto_traits : Vec < Item > = auto_traits
42
143
. into_iter ( )
43
144
. filter_map ( |trait_def_id| {
44
- let trait_ref =
45
- ty:: TraitRef { def_id : trait_def_id, substs : tcx. mk_substs_trait ( ty, & [ ] ) } ;
46
- if !self . cx . generated_synthetics . borrow_mut ( ) . insert ( ( ty, trait_def_id) ) {
47
- debug ! ( "get_auto_trait_impl_for({:?}): already generated, aborting" , trait_ref) ;
48
- return None ;
49
- }
50
-
51
- let result =
52
- f. find_auto_trait_generics ( ty, param_env, trait_def_id, |infcx, info| {
53
- let region_data = info. region_data ;
54
-
55
- let names_map = tcx
56
- . generics_of ( param_env_def_id)
57
- . params
58
- . iter ( )
59
- . filter_map ( |param| match param. kind {
60
- ty:: GenericParamDefKind :: Lifetime => Some ( param. name ) ,
61
- _ => None ,
62
- } )
63
- . map ( |name| ( name, Lifetime ( name) ) )
64
- . collect ( ) ;
65
- let lifetime_predicates = Self :: handle_lifetimes ( & region_data, & names_map) ;
66
- let new_generics = self . param_env_to_generics (
67
- infcx. tcx ,
68
- param_env_def_id,
69
- info. full_user_env ,
70
- lifetime_predicates,
71
- info. vid_to_region ,
72
- ) ;
73
-
74
- debug ! (
75
- "find_auto_trait_generics(param_env_def_id={:?}, trait_def_id={:?}): \
76
- finished with {:?}",
77
- param_env_def_id, trait_def_id, new_generics
78
- ) ;
79
-
80
- new_generics
81
- } ) ;
82
-
83
- let negative_polarity;
84
- let new_generics = match result {
85
- AutoTraitResult :: PositiveImpl ( new_generics) => {
86
- negative_polarity = false ;
87
- new_generics
88
- }
89
- AutoTraitResult :: NegativeImpl => {
90
- negative_polarity = true ;
91
-
92
- // For negative impls, we use the generic params, but *not* the predicates,
93
- // from the original type. Otherwise, the displayed impl appears to be a
94
- // conditional negative impl, when it's really unconditional.
95
- //
96
- // For example, consider the struct Foo<T: Copy>(*mut T). Using
97
- // the original predicates in our impl would cause us to generate
98
- // `impl !Send for Foo<T: Copy>`, which makes it appear that Foo
99
- // implements Send where T is not copy.
100
- //
101
- // Instead, we generate `impl !Send for Foo<T>`, which better
102
- // expresses the fact that `Foo<T>` never implements `Send`,
103
- // regardless of the choice of `T`.
104
- let params =
105
- ( tcx. generics_of ( param_env_def_id) , ty:: GenericPredicates :: default ( ) )
106
- . clean ( self . cx )
107
- . params ;
108
-
109
- Generics { params, where_predicates : Vec :: new ( ) }
110
- }
111
- AutoTraitResult :: ExplicitImpl => return None ,
112
- } ;
113
-
114
- Some ( Item {
115
- source : Span :: dummy ( ) ,
116
- name : None ,
117
- attrs : Default :: default ( ) ,
118
- visibility : Inherited ,
119
- def_id : self . cx . next_def_id ( param_env_def_id. krate ) ,
120
- kind : box ImplItem ( Impl {
121
- unsafety : hir:: Unsafety :: Normal ,
122
- generics : new_generics,
123
- provided_trait_methods : Default :: default ( ) ,
124
- trait_ : Some ( trait_ref. clean ( self . cx ) . get_trait_type ( ) . unwrap ( ) ) ,
125
- for_ : ty. clean ( self . cx ) ,
126
- items : Vec :: new ( ) ,
127
- negative_polarity,
128
- synthetic : true ,
129
- blanket_impl : None ,
130
- } ) ,
131
- } )
145
+ self . generate_for_trait ( ty, trait_def_id, param_env, param_env_def_id, & f, false )
132
146
} )
133
- . collect ( )
147
+ . collect ( ) ;
148
+ // We are only interested in case the type *doesn't* implement the Sized trait.
149
+ if !ty. is_sized ( self . cx . tcx . at ( rustc_span:: DUMMY_SP ) , param_env) {
150
+ // In case `#![no_core]` is used, `sized_trait` returns nothing.
151
+ if let Some ( item) = self . cx . tcx . lang_items ( ) . sized_trait ( ) . and_then ( |sized_trait_did| {
152
+ self . generate_for_trait ( ty, sized_trait_did, param_env, param_env_def_id, & f, true )
153
+ } ) {
154
+ auto_traits. push ( item) ;
155
+ }
156
+ }
157
+ auto_traits
134
158
}
135
159
136
160
fn get_lifetime ( region : Region < ' _ > , names_map : & FxHashMap < Symbol , Lifetime > ) -> Lifetime {
0 commit comments