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