@@ -481,6 +481,63 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
481
481
fn_like. asyncness ( )
482
482
}
483
483
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
+
484
541
pub fn provide ( providers : & mut ty:: query:: Providers ) {
485
542
* providers = ty:: query:: Providers {
486
543
asyncness,
@@ -498,6 +555,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
498
555
instance_def_size_estimate,
499
556
issue33140_self_ty,
500
557
impl_defaultness,
558
+ conservative_is_privately_uninhabited : conservative_is_privately_uninhabited_raw,
501
559
..* providers
502
560
} ;
503
561
}
0 commit comments