@@ -18,6 +18,7 @@ use rustc::traits::{self, ObligationCause, Reveal};
1818use rustc:: ty:: { self , Ty , TyCtxt } ;
1919use rustc:: ty:: ParameterEnvironment ;
2020use rustc:: ty:: TypeFoldable ;
21+ use rustc:: ty:: adjustment:: CoerceUnsizedInfo ;
2122use rustc:: ty:: subst:: Subst ;
2223use rustc:: ty:: util:: CopyImplementationError ;
2324use rustc:: infer;
@@ -159,28 +160,41 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
159160}
160161
161162fn visit_implementation_of_coerce_unsized < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
162- coerce_unsized_trait : DefId ,
163+ _ : DefId ,
163164 impl_did : DefId ) {
164165 debug ! ( "visit_implementation_of_coerce_unsized: impl_did={:?}" ,
165166 impl_did) ;
166167
168+ // Just compute this for the side-effects, in particular reporting
169+ // errors; other parts of the code may demand it for the info of
170+ // course.
171+ if impl_did. is_local ( ) {
172+ let span = tcx. def_span ( impl_did) ;
173+ ty:: queries:: coerce_unsized_info:: get ( tcx, span, impl_did) ;
174+ }
175+ }
176+
177+ pub fn coerce_unsized_info < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
178+ impl_did : DefId )
179+ -> CoerceUnsizedInfo {
180+ debug ! ( "compute_coerce_unsized_info(impl_did={:?})" , impl_did) ;
181+ let coerce_unsized_trait = tcx. lang_items . coerce_unsized_trait ( ) . unwrap ( ) ;
182+
167183 let unsize_trait = match tcx. lang_items . require ( UnsizeTraitLangItem ) {
168184 Ok ( id) => id,
169185 Err ( err) => {
170186 tcx. sess . fatal ( & format ! ( "`CoerceUnsized` implementation {}" , err) ) ;
171187 }
172188 } ;
173189
174- let impl_node_id = if let Some ( n) = tcx. hir . as_local_node_id ( impl_did) {
175- n
176- } else {
177- debug ! ( "visit_implementation_of_coerce_unsized(): impl not \
178- in this crate") ;
179- return ;
180- } ;
190+ // this provider should only get invoked for local def-ids
191+ let impl_node_id = tcx. hir . as_local_node_id ( impl_did) . unwrap_or_else ( || {
192+ bug ! ( "coerce_unsized_info: invoked for non-local def-id {:?}" , impl_did)
193+ } ) ;
181194
182195 let source = tcx. item_type ( impl_did) ;
183196 let trait_ref = tcx. impl_trait_ref ( impl_did) . unwrap ( ) ;
197+ assert_eq ! ( trait_ref. def_id, coerce_unsized_trait) ;
184198 let target = trait_ref. substs . type_at ( 1 ) ;
185199 debug ! ( "visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)" ,
186200 source,
@@ -192,6 +206,8 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
192206 let target = target. subst ( tcx, & param_env. free_substs ) ;
193207 assert ! ( !source. has_escaping_regions( ) ) ;
194208
209+ let err_info = CoerceUnsizedInfo { custom_kind : None } ;
210+
195211 debug ! ( "visit_implementation_of_coerce_unsized: {:?} -> {:?} (free)" ,
196212 source,
197213 target) ;
@@ -234,7 +250,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
234250 definition; expected {}, found {}",
235251 source_path,
236252 target_path) ;
237- return ;
253+ return err_info ;
238254 }
239255
240256 let fields = & def_a. struct_variant ( ) . fields ;
@@ -268,7 +284,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
268284 "the trait `CoerceUnsized` may only be implemented \
269285 for a coercion between structures with one field \
270286 being coerced, none found") ;
271- return ;
287+ return err_info ;
272288 } else if diff_fields. len ( ) > 1 {
273289 let item = tcx. hir . expect_item ( impl_node_id) ;
274290 let span = if let ItemImpl ( .., Some ( ref t) , _, _) = item. node {
@@ -295,7 +311,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
295311 . join( ", " ) ) ) ;
296312 err. span_label ( span, & format ! ( "requires multiple coercions" ) ) ;
297313 err. emit ( ) ;
298- return ;
314+ return err_info ;
299315 }
300316
301317 let ( i, a, b) = diff_fields[ 0 ] ;
@@ -309,7 +325,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
309325 E0376 ,
310326 "the trait `CoerceUnsized` may only be implemented \
311327 for a coercion between structures") ;
312- return ;
328+ return err_info ;
313329 }
314330 } ;
315331
@@ -331,8 +347,8 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
331347 . caller_bounds ) ;
332348 infcx. resolve_regions_and_report_errors ( & free_regions, impl_node_id) ;
333349
334- if let Some ( kind ) = kind {
335- tcx . maps . custom_coerce_unsized_kind . borrow_mut ( ) . insert ( impl_did , kind) ;
350+ CoerceUnsizedInfo {
351+ custom_kind : kind
336352 }
337- } ) ;
353+ } )
338354}
0 commit comments