@@ -3,6 +3,7 @@ use rustc_hir as hir;
33use rustc_hir:: LangItem ;
44use rustc_hir:: def:: DefKind ;
55use rustc_index:: bit_set:: DenseBitSet ;
6+ use rustc_infer:: infer:: TyCtxtInferExt ;
67use rustc_middle:: bug;
78use rustc_middle:: query:: Providers ;
89use rustc_middle:: ty:: {
@@ -312,6 +313,61 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> DenseBitSe
312313 unsizing_params
313314}
314315
316+ fn impl_self_is_guaranteed_unsized < ' tcx > ( tcx : TyCtxt < ' tcx > , impl_def_id : DefId ) -> bool {
317+ debug_assert_eq ! ( tcx. def_kind( impl_def_id) , DefKind :: Impl { of_trait: true } ) ;
318+
319+ let infcx = tcx. infer_ctxt ( ) . ignoring_regions ( ) . build ( ty:: TypingMode :: non_body_analysis ( ) ) ;
320+
321+ let ocx = traits:: ObligationCtxt :: new_with_diagnostics ( & infcx) ;
322+ let cause = traits:: ObligationCause :: dummy ( ) ;
323+ let param_env = tcx. param_env ( impl_def_id) ;
324+
325+ let tail = tcx. struct_tail_raw (
326+ tcx. type_of ( impl_def_id) . instantiate_identity ( ) ,
327+ |ty| {
328+ ocx. structurally_normalize_ty ( & cause, param_env, ty) . unwrap_or_else ( |_| {
329+ Ty :: new_error_with_message (
330+ tcx,
331+ tcx. def_span ( impl_def_id) ,
332+ "struct tail should be computable" ,
333+ )
334+ } )
335+ } ,
336+ || ( ) ,
337+ ) ;
338+
339+ match tail. kind ( ) {
340+ ty:: Dynamic ( _, _, ty:: Dyn ) | ty:: Slice ( _) | ty:: Str => true ,
341+ ty:: Bool
342+ | ty:: Char
343+ | ty:: Int ( _)
344+ | ty:: Uint ( _)
345+ | ty:: Float ( _)
346+ | ty:: Adt ( _, _)
347+ | ty:: Foreign ( _)
348+ | ty:: Array ( _, _)
349+ | ty:: Pat ( _, _)
350+ | ty:: RawPtr ( _, _)
351+ | ty:: Ref ( _, _, _)
352+ | ty:: FnDef ( _, _)
353+ | ty:: FnPtr ( _, _)
354+ | ty:: UnsafeBinder ( _)
355+ | ty:: Closure ( _, _)
356+ | ty:: CoroutineClosure ( _, _)
357+ | ty:: Coroutine ( _, _)
358+ | ty:: CoroutineWitness ( _, _)
359+ | ty:: Never
360+ | ty:: Tuple ( _)
361+ | ty:: Alias ( _, _)
362+ | ty:: Param ( _)
363+ | ty:: Bound ( _, _)
364+ | ty:: Placeholder ( _)
365+ | ty:: Infer ( _)
366+ | ty:: Error ( _)
367+ | ty:: Dynamic ( _, _, ty:: DynStar ) => false ,
368+ }
369+ }
370+
315371pub ( crate ) fn provide ( providers : & mut Providers ) {
316372 * providers = Providers {
317373 asyncness,
@@ -320,6 +376,7 @@ pub(crate) fn provide(providers: &mut Providers) {
320376 param_env_normalized_for_post_analysis,
321377 defaultness,
322378 unsizing_params_for_adt,
379+ impl_self_is_guaranteed_unsized,
323380 ..* providers
324381 } ;
325382}
0 commit comments