@@ -484,6 +484,63 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
484
484
fn_like. asyncness ( )
485
485
}
486
486
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
+
487
544
pub fn provide ( providers : & mut ty:: query:: Providers ) {
488
545
* providers = ty:: query:: Providers {
489
546
asyncness,
@@ -501,6 +558,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
501
558
instance_def_size_estimate,
502
559
issue33140_self_ty,
503
560
impl_defaultness,
561
+ conservative_is_privately_uninhabited : conservative_is_privately_uninhabited_raw,
504
562
..* providers
505
563
} ;
506
564
}
0 commit comments