Skip to content

Commit 93e259f

Browse files
committed
Check Sized in wfcheck for externed DSTs, closes rust-lang#36122
1 parent d703622 commit 93e259f

File tree

2 files changed

+65
-17
lines changed

2 files changed

+65
-17
lines changed

src/librustc_typeck/check/wfcheck.rs

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc::util::nodemap::{FxHashSet, FxHashMap};
1919
use rustc::middle::lang_items;
2020

2121
use syntax::ast;
22+
use syntax::ast::NodeId;
2223
use syntax::feature_gate::{self, GateIssue};
2324
use syntax_pos::Span;
2425
use errors::{DiagnosticBuilder, DiagnosticId};
@@ -111,10 +112,10 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def
111112
check_item_fn(tcx, item);
112113
}
113114
hir::ItemStatic(..) => {
114-
check_item_type(tcx, item);
115+
check_item_type(tcx, item.id);
115116
}
116117
hir::ItemConst(..) => {
117-
check_item_type(tcx, item);
118+
check_item_type(tcx, item.id);
118119
}
119120
hir::ItemStruct(ref struct_def, ref ast_generics) => {
120121
check_type_defn(tcx, item, false, |fcx| {
@@ -140,6 +141,17 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def
140141
hir::ItemTrait(..) => {
141142
check_trait(tcx, item);
142143
}
144+
hir::ItemForeignMod(ref foreign_mod) => {
145+
for foreign_item in foreign_mod.items.iter() {
146+
match foreign_item.node {
147+
hir::ForeignItemStatic(..) => {
148+
check_item_type(tcx, foreign_item.id);
149+
check_item_sized(tcx, foreign_item.id);
150+
},
151+
_ => {}
152+
}
153+
}
154+
}
143155
_ => {}
144156
}
145157
}
@@ -208,9 +220,9 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
208220
})
209221
}
210222

211-
fn for_item<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, item: &hir::Item)
223+
fn for_item<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: NodeId)
212224
-> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
213-
for_id(tcx, item.id, item.span)
225+
for_id(tcx, id, tcx.hir.span(id))
214226
}
215227

216228
fn for_id<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId, span: Span)
@@ -229,7 +241,7 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
229241
item: &hir::Item, all_sized: bool, mut lookup_fields: F)
230242
where F: for<'fcx, 'gcx, 'tcx2> FnMut(&FnCtxt<'fcx, 'gcx, 'tcx2>) -> Vec<AdtVariant<'tcx2>>
231243
{
232-
for_item(tcx, item).with_fcx(|fcx, fcx_tcx| {
244+
for_item(tcx, item.id).with_fcx(|fcx, fcx_tcx| {
233245
let variants = lookup_fields(fcx);
234246
let def_id = fcx.tcx.hir.local_def_id(item.id);
235247
let packed = fcx.tcx.adt_def(def_id).repr.packed();
@@ -283,14 +295,14 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
283295

284296
fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
285297
let trait_def_id = tcx.hir.local_def_id(item.id);
286-
for_item(tcx, item).with_fcx(|fcx, _| {
298+
for_item(tcx, item.id).with_fcx(|fcx, _| {
287299
check_where_clauses(tcx, fcx, item.span, trait_def_id);
288300
vec![]
289301
});
290302
}
291303

292304
fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
293-
for_item(tcx, item).with_fcx(|fcx, tcx| {
305+
for_item(tcx, item.id).with_fcx(|fcx, tcx| {
294306
let def_id = fcx.tcx.hir.local_def_id(item.id);
295307
let sig = fcx.tcx.fn_sig(def_id);
296308
let sig = fcx.normalize_associated_types_in(item.span, &sig);
@@ -301,16 +313,34 @@ fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
301313
})
302314
}
303315

316+
pub fn check_item_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: NodeId) {
317+
for_item(tcx, id).with_fcx(|fcx, _this| {
318+
let span = tcx.hir.span(id);
319+
let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(id));
320+
let item_ty = fcx.normalize_associated_types_in(span, &ty);
321+
322+
fcx.register_bound(
323+
item_ty,
324+
fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
325+
traits::ObligationCause::new(span,
326+
fcx.body_id,
327+
traits::SizedReturnType
328+
)
329+
);
330+
331+
vec![] // no implied bounds in a const etc
332+
});
333+
}
334+
304335
fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
305-
item: &hir::Item)
336+
id: NodeId)
306337
{
307-
debug!("check_item_type: {:?}", item);
338+
for_item(tcx, id).with_fcx(|fcx, _this| {
339+
let span = tcx.hir.span(id);
340+
let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(id));
341+
let item_ty = fcx.normalize_associated_types_in(span, &ty);
308342

309-
for_item(tcx, item).with_fcx(|fcx, _this| {
310-
let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id));
311-
let item_ty = fcx.normalize_associated_types_in(item.span, &ty);
312-
313-
fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation);
343+
fcx.register_wf_obligation(item_ty, span, ObligationCauseCode::MiscObligation);
314344

315345
vec![] // no implied bounds in a const etc
316346
});
@@ -321,9 +351,7 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
321351
ast_self_ty: &hir::Ty,
322352
ast_trait_ref: &Option<hir::TraitRef>)
323353
{
324-
debug!("check_impl: {:?}", item);
325-
326-
for_item(tcx, item).with_fcx(|fcx, tcx| {
354+
for_item(tcx, item.id).with_fcx(|fcx, tcx| {
327355
let item_def_id = fcx.tcx.hir.local_def_id(item.id);
328356

329357
match *ast_trait_ref {

src/test/compile-fail/issue-36122.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
fn main() {
12+
extern "C" {
13+
static symbol: [usize];
14+
//~^ ERROR the trait bound `[usize]: std::marker::Sized` is not satisfied [E0277]
15+
}
16+
17+
unsafe {
18+
println!("{}", symbol[0]);
19+
}
20+
}

0 commit comments

Comments
 (0)