@@ -15,7 +15,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt};
15
15
use rustc_infer:: traits:: Obligation ;
16
16
use rustc_middle:: ty:: adjustment:: CoerceUnsizedInfo ;
17
17
use rustc_middle:: ty:: { self , suggest_constraining_type_params, Ty , TyCtxt , TypeVisitableExt } ;
18
- use rustc_span:: Span ;
18
+ use rustc_span:: { Span , DUMMY_SP } ;
19
19
use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt ;
20
20
use rustc_trait_selection:: traits:: misc:: {
21
21
type_allowed_to_implement_const_param_ty, type_allowed_to_implement_copy,
@@ -25,13 +25,14 @@ use rustc_trait_selection::traits::ObligationCtxt;
25
25
use rustc_trait_selection:: traits:: { self , ObligationCause } ;
26
26
use std:: collections:: BTreeMap ;
27
27
28
- pub fn check_trait (
29
- tcx : TyCtxt < ' _ > ,
28
+ pub fn check_trait < ' tcx > (
29
+ tcx : TyCtxt < ' tcx > ,
30
30
trait_def_id : DefId ,
31
31
impl_def_id : LocalDefId ,
32
+ impl_header : ty:: ImplTraitHeader < ' tcx > ,
32
33
) -> Result < ( ) , ErrorGuaranteed > {
33
34
let lang_items = tcx. lang_items ( ) ;
34
- let checker = Checker { tcx, trait_def_id, impl_def_id } ;
35
+ let checker = Checker { tcx, trait_def_id, impl_def_id, impl_header } ;
35
36
let mut res = checker. check ( lang_items. drop_trait ( ) , visit_implementation_of_drop) ;
36
37
res = res. and ( checker. check ( lang_items. copy_trait ( ) , visit_implementation_of_copy) ) ;
37
38
res = res. and (
@@ -50,24 +51,25 @@ struct Checker<'tcx> {
50
51
tcx : TyCtxt < ' tcx > ,
51
52
trait_def_id : DefId ,
52
53
impl_def_id : LocalDefId ,
54
+ impl_header : ty:: ImplTraitHeader < ' tcx > ,
53
55
}
54
56
55
57
impl < ' tcx > Checker < ' tcx > {
56
58
fn check (
57
59
& self ,
58
60
trait_def_id : Option < DefId > ,
59
- f : impl FnOnce ( TyCtxt < ' tcx > , LocalDefId ) -> Result < ( ) , ErrorGuaranteed > ,
61
+ f : impl FnOnce ( & Self ) -> Result < ( ) , ErrorGuaranteed > ,
60
62
) -> Result < ( ) , ErrorGuaranteed > {
61
- if Some ( self . trait_def_id ) == trait_def_id { f ( self . tcx , self . impl_def_id ) } else { Ok ( ( ) ) }
63
+ if Some ( self . trait_def_id ) == trait_def_id { f ( self ) } else { Ok ( ( ) ) }
62
64
}
63
65
}
64
66
65
- fn visit_implementation_of_drop (
66
- tcx : TyCtxt < ' _ > ,
67
- impl_did : LocalDefId ,
68
- ) -> Result < ( ) , ErrorGuaranteed > {
67
+ fn visit_implementation_of_drop ( checker : & Checker < ' _ > ) -> Result < ( ) , ErrorGuaranteed > {
68
+ let tcx = checker . tcx ;
69
+ let header = checker . impl_header ;
70
+ let impl_did = checker . impl_def_id ;
69
71
// Destructors only work on local ADT types.
70
- match tcx . type_of ( impl_did ) . instantiate_identity ( ) . kind ( ) {
72
+ match header . trait_ref . self_ty ( ) . kind ( ) {
71
73
ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => return Ok ( ( ) ) ,
72
74
ty:: Error ( _) => return Ok ( ( ) ) ,
73
75
_ => { }
@@ -78,70 +80,72 @@ fn visit_implementation_of_drop(
78
80
Err ( tcx. dcx ( ) . emit_err ( errors:: DropImplOnWrongItem { span : impl_. self_ty . span } ) )
79
81
}
80
82
81
- fn visit_implementation_of_copy (
82
- tcx : TyCtxt < ' _ > ,
83
- impl_did : LocalDefId ,
84
- ) -> Result < ( ) , ErrorGuaranteed > {
83
+ fn visit_implementation_of_copy ( checker : & Checker < ' _ > ) -> Result < ( ) , ErrorGuaranteed > {
84
+ let tcx = checker . tcx ;
85
+ let impl_header = checker . impl_header ;
86
+ let impl_did = checker . impl_def_id ;
85
87
debug ! ( "visit_implementation_of_copy: impl_did={:?}" , impl_did) ;
86
88
87
- let self_type = tcx . type_of ( impl_did ) . instantiate_identity ( ) ;
89
+ let self_type = impl_header . trait_ref . self_ty ( ) ;
88
90
debug ! ( "visit_implementation_of_copy: self_type={:?} (bound)" , self_type) ;
89
91
90
92
let param_env = tcx. param_env ( impl_did) ;
91
93
assert ! ( !self_type. has_escaping_bound_vars( ) ) ;
92
94
93
95
debug ! ( "visit_implementation_of_copy: self_type={:?} (free)" , self_type) ;
94
96
95
- if let ty:: ImplPolarity :: Negative = tcx . impl_polarity ( impl_did ) {
97
+ if let ty:: ImplPolarity :: Negative = impl_header . polarity {
96
98
return Ok ( ( ) ) ;
97
99
}
98
- let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
99
100
100
- let cause = traits:: ObligationCause :: misc ( span , impl_did) ;
101
+ let cause = traits:: ObligationCause :: misc ( DUMMY_SP , impl_did) ;
101
102
match type_allowed_to_implement_copy ( tcx, param_env, self_type, cause) {
102
103
Ok ( ( ) ) => Ok ( ( ) ) ,
103
104
Err ( CopyImplementationError :: InfringingFields ( fields) ) => {
105
+ let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
104
106
Err ( infringing_fields_error ( tcx, fields, LangItem :: Copy , impl_did, span) )
105
107
}
106
108
Err ( CopyImplementationError :: NotAnAdt ) => {
109
+ let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
107
110
Err ( tcx. dcx ( ) . emit_err ( errors:: CopyImplOnNonAdt { span } ) )
108
111
}
109
112
Err ( CopyImplementationError :: HasDestructor ) => {
113
+ let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
110
114
Err ( tcx. dcx ( ) . emit_err ( errors:: CopyImplOnTypeWithDtor { span } ) )
111
115
}
112
116
}
113
117
}
114
118
115
- fn visit_implementation_of_const_param_ty (
116
- tcx : TyCtxt < ' _ > ,
117
- impl_did : LocalDefId ,
118
- ) -> Result < ( ) , ErrorGuaranteed > {
119
- let self_type = tcx . type_of ( impl_did ) . instantiate_identity ( ) ;
119
+ fn visit_implementation_of_const_param_ty ( checker : & Checker < ' _ > ) -> Result < ( ) , ErrorGuaranteed > {
120
+ let tcx = checker . tcx ;
121
+ let header = checker . impl_header ;
122
+ let impl_did = checker . impl_def_id ;
123
+ let self_type = header . trait_ref . self_ty ( ) ;
120
124
assert ! ( !self_type. has_escaping_bound_vars( ) ) ;
121
125
122
126
let param_env = tcx. param_env ( impl_did) ;
123
127
124
- if let ty:: ImplPolarity :: Negative = tcx . impl_polarity ( impl_did ) {
128
+ if let ty:: ImplPolarity :: Negative = header . polarity {
125
129
return Ok ( ( ) ) ;
126
130
}
127
- let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
128
131
129
- let cause = traits:: ObligationCause :: misc ( span , impl_did) ;
132
+ let cause = traits:: ObligationCause :: misc ( DUMMY_SP , impl_did) ;
130
133
match type_allowed_to_implement_const_param_ty ( tcx, param_env, self_type, cause) {
131
134
Ok ( ( ) ) => Ok ( ( ) ) ,
132
135
Err ( ConstParamTyImplementationError :: InfrigingFields ( fields) ) => {
136
+ let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
133
137
Err ( infringing_fields_error ( tcx, fields, LangItem :: ConstParamTy , impl_did, span) )
134
138
}
135
139
Err ( ConstParamTyImplementationError :: NotAnAdtOrBuiltinAllowed ) => {
140
+ let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
136
141
Err ( tcx. dcx ( ) . emit_err ( errors:: ConstParamTyImplOnNonAdt { span } ) )
137
142
}
138
143
}
139
144
}
140
145
141
- fn visit_implementation_of_coerce_unsized (
142
- tcx : TyCtxt < ' _ > ,
143
- impl_did : LocalDefId ,
144
- ) -> Result < ( ) , ErrorGuaranteed > {
146
+ fn visit_implementation_of_coerce_unsized ( checker : & Checker < ' _ > ) -> Result < ( ) , ErrorGuaranteed > {
147
+ let tcx = checker. tcx ;
148
+ let impl_did = checker. impl_def_id ;
145
149
debug ! ( "visit_implementation_of_coerce_unsized: impl_did={:?}" , impl_did) ;
146
150
147
151
// Just compute this for the side-effects, in particular reporting
@@ -151,20 +155,20 @@ fn visit_implementation_of_coerce_unsized(
151
155
tcx. at ( span) . ensure ( ) . coerce_unsized_info ( impl_did)
152
156
}
153
157
154
- fn visit_implementation_of_dispatch_from_dyn (
155
- tcx : TyCtxt < ' _ > ,
156
- impl_did : LocalDefId ,
157
- ) -> Result < ( ) , ErrorGuaranteed > {
158
+ fn visit_implementation_of_dispatch_from_dyn ( checker : & Checker < ' _ > ) -> Result < ( ) , ErrorGuaranteed > {
159
+ let tcx = checker. tcx ;
160
+ let header = checker. impl_header ;
161
+ let impl_did = checker. impl_def_id ;
162
+ let trait_ref = header. trait_ref ;
158
163
debug ! ( "visit_implementation_of_dispatch_from_dyn: impl_did={:?}" , impl_did) ;
159
164
160
165
let span = tcx. def_span ( impl_did) ;
161
166
162
167
let dispatch_from_dyn_trait = tcx. require_lang_item ( LangItem :: DispatchFromDyn , Some ( span) ) ;
163
168
164
- let source = tcx . type_of ( impl_did ) . instantiate_identity ( ) ;
169
+ let source = trait_ref . self_ty ( ) ;
165
170
assert ! ( !source. has_escaping_bound_vars( ) ) ;
166
171
let target = {
167
- let trait_ref = tcx. impl_trait_ref ( impl_did) . unwrap ( ) . instantiate_identity ( ) ;
168
172
assert_eq ! ( trait_ref. def_id, dispatch_from_dyn_trait) ;
169
173
170
174
trait_ref. args . type_at ( 1 )
0 commit comments