@@ -14,8 +14,9 @@ use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
1414use rustc_middle:: ty:: fold:: TypeFoldable ;
1515use rustc_middle:: ty:: subst:: GenericArgKind ;
1616use 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 } ;
1818use rustc_session:: config:: EntryFnType ;
19+ use rustc_session:: lint:: builtin:: UNINHABITED_STATIC ;
1920use rustc_span:: symbol:: sym;
2021use rustc_span:: { self , MultiSpan , Span } ;
2122use rustc_target:: spec:: abi:: Abi ;
@@ -338,7 +339,7 @@ pub(super) fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
338339 check_packed ( tcx, span, def) ;
339340}
340341
341- pub ( super ) fn check_union ( tcx : TyCtxt < ' _ > , id : hir:: HirId , span : Span ) {
342+ fn check_union ( tcx : TyCtxt < ' _ > , id : hir:: HirId , span : Span ) {
342343 let def_id = tcx. hir ( ) . local_def_id ( id) ;
343344 let def = tcx. adt_def ( def_id) ;
344345 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) {
349350}
350351
351352/// 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 {
353354 let item_type = tcx. type_of ( item_def_id) ;
354355 if let ty:: Adt ( def, substs) = item_type. kind ( ) {
355356 assert ! ( def. is_union( ) ) ;
@@ -377,6 +378,36 @@ pub(super) fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: Local
377378 true
378379}
379380
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 enugh 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+
380411/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
381412/// projections that would result in "inheriting lifetimes".
382413pub ( super ) fn check_opaque < ' tcx > (
@@ -609,6 +640,7 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
609640 let def_id = tcx. hir ( ) . local_def_id ( it. hir_id ) ;
610641 tcx. ensure ( ) . typeck ( def_id) ;
611642 maybe_check_static_with_link_section ( tcx, def_id, it. span ) ;
643+ check_static_inhabited ( tcx, def_id, it. span ) ;
612644 }
613645 hir:: ItemKind :: Const ( ..) => {
614646 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>) {
691723 }
692724 } else {
693725 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) ;
695728 let own_counts = generics. own_counts ( ) ;
696729 if generics. params . len ( ) - own_counts. lifetimes != 0 {
697730 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>) {
722755 . emit ( ) ;
723756 }
724757
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+ _ => { }
727766 }
728767 }
729768 }
0 commit comments