@@ -481,6 +481,63 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
481481 fn_like. asyncness ( )
482482}
483483
484+ /// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead.
485+ #[ instrument( level = "debug" , skip( tcx) ) ]
486+ pub fn conservative_is_privately_uninhabited_raw < ' tcx > (
487+ tcx : TyCtxt < ' tcx > ,
488+ param_env_and : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
489+ ) -> bool {
490+ let ( param_env, ty) = param_env_and. into_parts ( ) ;
491+ match ty. kind ( ) {
492+ ty:: Never => {
493+ debug ! ( "ty::Never =>" ) ;
494+ true
495+ }
496+ ty:: Adt ( def, _) if def. is_union ( ) => {
497+ debug ! ( "ty::Adt(def, _) if def.is_union() =>" ) ;
498+ // For now, `union`s are never considered uninhabited.
499+ false
500+ }
501+ ty:: Adt ( def, substs) => {
502+ debug ! ( "ty::Adt(def, _) if def.is_not_union() =>" ) ;
503+ // Any ADT is uninhabited if either:
504+ // (a) It has no variants (i.e. an empty `enum`);
505+ // (b) Each of its variants (a single one in the case of a `struct`) has at least
506+ // one uninhabited field.
507+ def. variants . iter ( ) . all ( |var| {
508+ var. fields . iter ( ) . any ( |field| {
509+ let ty = tcx. type_of ( field. did ) . subst ( tcx, substs) ;
510+ tcx. conservative_is_privately_uninhabited ( param_env. and ( ty) )
511+ } )
512+ } )
513+ }
514+ ty:: Tuple ( ..) => {
515+ debug ! ( "ty::Tuple(..) =>" ) ;
516+ ty. tuple_fields ( ) . any ( |ty| tcx. conservative_is_privately_uninhabited ( param_env. and ( ty) ) )
517+ }
518+ ty:: Array ( ty, len) => {
519+ debug ! ( "ty::Array(ty, len) =>" ) ;
520+ match len. try_eval_usize ( tcx, param_env) {
521+ Some ( 0 ) | None => false ,
522+ // If the array is definitely non-empty, it's uninhabited if
523+ // the type of its elements is uninhabited.
524+ Some ( 1 ..) => tcx. conservative_is_privately_uninhabited ( param_env. and ( ty) ) ,
525+ }
526+ }
527+ ty:: Ref ( ..) => {
528+ debug ! ( "ty::Ref(..) =>" ) ;
529+ // References to uninitialised memory is valid for any type, including
530+ // uninhabited types, in unsafe code, so we treat all references as
531+ // inhabited.
532+ false
533+ }
534+ _ => {
535+ debug ! ( "_ =>" ) ;
536+ false
537+ }
538+ }
539+ }
540+
484541pub fn provide ( providers : & mut ty:: query:: Providers ) {
485542 * providers = ty:: query:: Providers {
486543 asyncness,
@@ -498,6 +555,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
498555 instance_def_size_estimate,
499556 issue33140_self_ty,
500557 impl_defaultness,
558+ conservative_is_privately_uninhabited : conservative_is_privately_uninhabited_raw,
501559 ..* providers
502560 } ;
503561}
0 commit comments