Skip to content

Commit

Permalink
Allow extern statics with an extern type
Browse files Browse the repository at this point in the history
Fixes #55239
  • Loading branch information
mjbshaw committed Oct 22, 2018
1 parent 424a749 commit 412ad9b
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 15 deletions.
42 changes: 27 additions & 15 deletions src/librustc_typeck/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -340,23 +340,35 @@ 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);

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
});
Expand Down
37 changes: 37 additions & 0 deletions src/test/ui/static/static-extern-type.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 412ad9b

Please sign in to comment.