about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-10-28 21:38:12 +0800
committerkennytm <kennytm@gmail.com>2018-10-28 21:38:12 +0800
commitabf7243066775f0709275aee23d3dda80f72c3fe (patch)
treec8dc40c8248ecfc14a0b877fd1976a6e1554b7e6
parentaaa20c61d6cc090b139882a7946dfe89bb3486c1 (diff)
parent5b84550d7c39821704a48b53c8cbe3916ab100b7 (diff)
downloadrust-abf7243066775f0709275aee23d3dda80f72c3fe.tar.gz
rust-abf7243066775f0709275aee23d3dda80f72c3fe.zip
Rollup merge of #55257 - mjbshaw:static, r=oli-obk
Allow extern statics with an extern type

Fixes #55239
-rw-r--r--src/librustc_typeck/check/wfcheck.rs38
-rw-r--r--src/test/ui/static/static-extern-type.rs37
2 files changed, 61 insertions, 14 deletions
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 9990d2ee2b6..ea84e874b1a 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -13,7 +13,7 @@ use constrained_type_params::{identify_constrained_type_params, Parameter};
 
 use hir::def_id::DefId;
 use rustc::traits::{self, ObligationCauseCode};
-use rustc::ty::{self, Lift, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
+use rustc::ty::{self, Lift, Ty, TyCtxt, TyKind, GenericParamDefKind, TypeFoldable};
 use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::util::ExplicitSelf;
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
@@ -119,14 +119,14 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def
             check_item_fn(tcx, item);
         }
         hir::ItemKind::Static(ref ty, ..) => {
-            check_item_type(tcx, item.id, ty.span);
+            check_item_type(tcx, item.id, ty.span, false);
         }
         hir::ItemKind::Const(ref ty, ..) => {
-            check_item_type(tcx, item.id, ty.span);
+            check_item_type(tcx, item.id, ty.span, false);
         }
         hir::ItemKind::ForeignMod(ref module) => for it in module.items.iter() {
             if let hir::ForeignItemKind::Static(ref ty, ..) = it.node {
-                check_item_type(tcx, it.id, ty.span);
+                check_item_type(tcx, it.id, ty.span, true);
             }
         },
         hir::ItemKind::Struct(ref struct_def, ref ast_generics) => {
@@ -340,23 +340,33 @@ fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
     })
 }
 
-fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId, ty_span: Span) {
+fn check_item_type<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    item_id: ast::NodeId,
+    ty_span: Span,
+    allow_foreign_ty: bool,
+) {
     debug!("check_item_type: {:?}", item_id);
 
     for_id(tcx, item_id, ty_span).with_fcx(|fcx, _this| {
         let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item_id));
         let item_ty = fcx.normalize_associated_types_in(ty_span, &ty);
 
+        let mut forbid_unsized = true;
+        if allow_foreign_ty {
+            if let TyKind::Foreign(_) = tcx.struct_tail(item_ty).sty {
+                forbid_unsized = false;
+            }
+        }
+
         fcx.register_wf_obligation(item_ty, ty_span, ObligationCauseCode::MiscObligation);
-        fcx.register_bound(
-            item_ty,
-            fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
-            traits::ObligationCause::new(
-                ty_span,
-                fcx.body_id,
-                traits::MiscObligation,
-            ),
-        );
+        if forbid_unsized {
+            fcx.register_bound(
+                item_ty,
+                fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
+                traits::ObligationCause::new(ty_span, fcx.body_id, traits::MiscObligation),
+            );
+        }
 
         vec![] // no implied bounds in a const etc
     });
diff --git a/src/test/ui/static/static-extern-type.rs b/src/test/ui/static/static-extern-type.rs
new file mode 100644
index 00000000000..72e2853b9f0
--- /dev/null
+++ b/src/test/ui/static/static-extern-type.rs
@@ -0,0 +1,37 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+#![feature(extern_types)]
+
+pub mod a {
+    extern "C" {
+        pub type StartFn;
+        pub static start: StartFn;
+    }
+}
+
+pub mod b {
+    #[repr(transparent)]
+    pub struct TransparentType(::a::StartFn);
+    extern "C" {
+        pub static start: TransparentType;
+    }
+}
+
+pub mod c {
+    #[repr(C)]
+    pub struct CType(u32, ::b::TransparentType);
+    extern "C" {
+        pub static start: CType;
+    }
+}
+
+fn main() {}