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};
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) => {
})
}
-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);
- 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,
- ),
- );
+ let mut allow_unsized = false;
+ if allow_foreign_ty {
+ if let TyKind::Foreign(_) = tcx.struct_tail(item_ty).sty {
+ allow_unsized = true;
+ }
+ }
+
+ if !allow_unsized {
+ 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,
+ ),
+ );
+ }
vec![] // no implied bounds in a const etc
});
--- /dev/null
+// 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() {}