@@ -14,8 +14,9 @@ use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
14
14
use rustc_middle:: ty:: fold:: TypeFoldable ;
15
15
use rustc_middle:: ty:: subst:: GenericArgKind ;
16
16
use rustc_middle:: ty:: util:: { Discr , IntTypeExt , Representability } ;
17
- use rustc_middle:: ty:: { self , RegionKind , ToPredicate , Ty , TyCtxt } ;
17
+ use rustc_middle:: ty:: { self , ParamEnv , RegionKind , ToPredicate , Ty , TyCtxt } ;
18
18
use rustc_session:: config:: EntryFnType ;
19
+ use rustc_session:: lint:: builtin:: UNINHABITED_STATIC ;
19
20
use rustc_span:: symbol:: sym;
20
21
use rustc_span:: { self , MultiSpan , Span } ;
21
22
use rustc_target:: spec:: abi:: Abi ;
@@ -338,7 +339,7 @@ pub(super) fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
338
339
check_packed ( tcx, span, def) ;
339
340
}
340
341
341
- pub ( super ) fn check_union ( tcx : TyCtxt < ' _ > , id : hir:: HirId , span : Span ) {
342
+ fn check_union ( tcx : TyCtxt < ' _ > , id : hir:: HirId , span : Span ) {
342
343
let def_id = tcx. hir ( ) . local_def_id ( id) ;
343
344
let def = tcx. adt_def ( def_id) ;
344
345
def. destructor ( tcx) ; // force the destructor to be evaluated
@@ -349,7 +350,7 @@ pub(super) fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
349
350
}
350
351
351
352
/// Check that the fields of the `union` do not need dropping.
352
- pub ( super ) fn check_union_fields ( tcx : TyCtxt < ' _ > , span : Span , item_def_id : LocalDefId ) -> bool {
353
+ fn check_union_fields ( tcx : TyCtxt < ' _ > , span : Span , item_def_id : LocalDefId ) -> bool {
353
354
let item_type = tcx. type_of ( item_def_id) ;
354
355
if let ty:: Adt ( def, substs) = item_type. kind ( ) {
355
356
assert ! ( def. is_union( ) ) ;
@@ -377,6 +378,36 @@ pub(super) fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: Local
377
378
true
378
379
}
379
380
381
+ /// Check that a `static` is inhabited.
382
+ fn check_static_inhabited < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId , span : Span ) {
383
+ // Make sure statics are inhabited.
384
+ // Other parts of the compiler assume that there are no uninhabited places. In principle it
385
+ // would be enough to check this for `extern` statics, as statics with an initializer will
386
+ // have UB during initialization if they are uninhabited, but there also seems to be no good
387
+ // reason to allow any statics to be uninhabited.
388
+ let ty = tcx. type_of ( def_id) ;
389
+ let layout = match tcx. layout_of ( ParamEnv :: reveal_all ( ) . and ( ty) ) {
390
+ Ok ( l) => l,
391
+ Err ( _) => {
392
+ // Generic statics are rejected, but we still reach this case.
393
+ tcx. sess . delay_span_bug ( span, "generic static must be rejected" ) ;
394
+ return ;
395
+ }
396
+ } ;
397
+ if layout. abi . is_uninhabited ( ) {
398
+ tcx. struct_span_lint_hir (
399
+ UNINHABITED_STATIC ,
400
+ tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ,
401
+ span,
402
+ |lint| {
403
+ lint. build ( "static of uninhabited type" )
404
+ . note ( "uninhabited statics cannot be initialized, and any access would be an immediate error" )
405
+ . emit ( ) ;
406
+ } ,
407
+ ) ;
408
+ }
409
+ }
410
+
380
411
/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
381
412
/// projections that would result in "inheriting lifetimes".
382
413
pub ( super ) fn check_opaque < ' tcx > (
@@ -609,6 +640,7 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
609
640
let def_id = tcx. hir ( ) . local_def_id ( it. hir_id ) ;
610
641
tcx. ensure ( ) . typeck ( def_id) ;
611
642
maybe_check_static_with_link_section ( tcx, def_id, it. span ) ;
643
+ check_static_inhabited ( tcx, def_id, it. span ) ;
612
644
}
613
645
hir:: ItemKind :: Const ( ..) => {
614
646
tcx. ensure ( ) . typeck ( tcx. hir ( ) . local_def_id ( it. hir_id ) ) ;
@@ -691,7 +723,8 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
691
723
}
692
724
} else {
693
725
for item in m. items {
694
- let generics = tcx. generics_of ( tcx. hir ( ) . local_def_id ( item. hir_id ) ) ;
726
+ let def_id = tcx. hir ( ) . local_def_id ( item. hir_id ) ;
727
+ let generics = tcx. generics_of ( def_id) ;
695
728
let own_counts = generics. own_counts ( ) ;
696
729
if generics. params . len ( ) - own_counts. lifetimes != 0 {
697
730
let ( kinds, kinds_pl, egs) = match ( own_counts. types , own_counts. consts ) {
@@ -722,8 +755,14 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
722
755
. emit ( ) ;
723
756
}
724
757
725
- if let hir:: ForeignItemKind :: Fn ( ref fn_decl, _, _) = item. kind {
726
- require_c_abi_if_c_variadic ( tcx, fn_decl, m. abi , item. span ) ;
758
+ match item. kind {
759
+ hir:: ForeignItemKind :: Fn ( ref fn_decl, _, _) => {
760
+ require_c_abi_if_c_variadic ( tcx, fn_decl, m. abi , item. span ) ;
761
+ }
762
+ hir:: ForeignItemKind :: Static ( ..) => {
763
+ check_static_inhabited ( tcx, def_id, item. span ) ;
764
+ }
765
+ _ => { }
727
766
}
728
767
}
729
768
}
0 commit comments