Skip to content

Commit 412ad9b

Browse files
committed
Allow extern statics with an extern type
Fixes #55239
1 parent 424a749 commit 412ad9b

File tree

2 files changed

+64
-15
lines changed

2 files changed

+64
-15
lines changed

src/librustc_typeck/check/wfcheck.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use constrained_type_params::{identify_constrained_type_params, Parameter};
1313

1414
use hir::def_id::DefId;
1515
use rustc::traits::{self, ObligationCauseCode};
16-
use rustc::ty::{self, Lift, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
16+
use rustc::ty::{self, Lift, Ty, TyCtxt, TyKind, GenericParamDefKind, TypeFoldable};
1717
use rustc::ty::subst::{Subst, Substs};
1818
use rustc::ty::util::ExplicitSelf;
1919
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
119119
check_item_fn(tcx, item);
120120
}
121121
hir::ItemKind::Static(ref ty, ..) => {
122-
check_item_type(tcx, item.id, ty.span);
122+
check_item_type(tcx, item.id, ty.span, false);
123123
}
124124
hir::ItemKind::Const(ref ty, ..) => {
125-
check_item_type(tcx, item.id, ty.span);
125+
check_item_type(tcx, item.id, ty.span, false);
126126
}
127127
hir::ItemKind::ForeignMod(ref module) => for it in module.items.iter() {
128128
if let hir::ForeignItemKind::Static(ref ty, ..) = it.node {
129-
check_item_type(tcx, it.id, ty.span);
129+
check_item_type(tcx, it.id, ty.span, true);
130130
}
131131
},
132132
hir::ItemKind::Struct(ref struct_def, ref ast_generics) => {
@@ -340,23 +340,35 @@ fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
340340
})
341341
}
342342

343-
fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId, ty_span: Span) {
343+
fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
344+
item_id: ast::NodeId,
345+
ty_span: Span,
346+
allow_foreign_ty: bool) {
344347
debug!("check_item_type: {:?}", item_id);
345348

346349
for_id(tcx, item_id, ty_span).with_fcx(|fcx, _this| {
347350
let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item_id));
348351
let item_ty = fcx.normalize_associated_types_in(ty_span, &ty);
349352

350-
fcx.register_wf_obligation(item_ty, ty_span, ObligationCauseCode::MiscObligation);
351-
fcx.register_bound(
352-
item_ty,
353-
fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
354-
traits::ObligationCause::new(
355-
ty_span,
356-
fcx.body_id,
357-
traits::MiscObligation,
358-
),
359-
);
353+
let mut allow_unsized = false;
354+
if allow_foreign_ty {
355+
if let TyKind::Foreign(_) = tcx.struct_tail(item_ty).sty {
356+
allow_unsized = true;
357+
}
358+
}
359+
360+
if !allow_unsized {
361+
fcx.register_wf_obligation(item_ty, ty_span, ObligationCauseCode::MiscObligation);
362+
fcx.register_bound(
363+
item_ty,
364+
fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
365+
traits::ObligationCause::new(
366+
ty_span,
367+
fcx.body_id,
368+
traits::MiscObligation,
369+
),
370+
);
371+
}
360372

361373
vec![] // no implied bounds in a const etc
362374
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-pass
12+
#![feature(extern_types)]
13+
14+
pub mod a {
15+
extern "C" {
16+
pub type StartFn;
17+
pub static start: StartFn;
18+
}
19+
}
20+
21+
pub mod b {
22+
#[repr(transparent)]
23+
pub struct TransparentType(::a::StartFn);
24+
extern "C" {
25+
pub static start: TransparentType;
26+
}
27+
}
28+
29+
pub mod c {
30+
#[repr(C)]
31+
pub struct CType(u32, ::b::TransparentType);
32+
extern "C" {
33+
pub static start: CType;
34+
}
35+
}
36+
37+
fn main() {}

0 commit comments

Comments
 (0)