Skip to content

Commit 2a8a289

Browse files
committed
Check the types of extern items
Fixes rust-lang#25637.
1 parent 6929069 commit 2a8a289

File tree

3 files changed

+49
-23
lines changed

3 files changed

+49
-23
lines changed

src/librustc_typeck/check/regionck.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,11 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
122122
rcx.resolve_regions_and_report_errors();
123123
}
124124

125-
pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) {
126-
let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id));
125+
pub fn regionck_item(fcx: &FnCtxt, id: ast::NodeId) {
126+
let mut rcx = Rcx::new(fcx, RepeatingScope(id), id, Subject(id));
127127
let tcx = fcx.tcx();
128128
rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds);
129-
rcx.visit_region_obligations(item.id);
129+
rcx.visit_region_obligations(id);
130130
rcx.resolve_regions_and_report_errors();
131131
}
132132

src/librustc_typeck/check/wf.rs

+24-20
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
9494
}
9595
}
9696
ast::ItemFn(..) => {
97-
self.check_item_type(item);
97+
self.check_item_type(item.span, item.id);
9898
}
9999
ast::ItemStatic(..) => {
100-
self.check_item_type(item);
100+
self.check_item_type(item.span, item.id);
101101
}
102102
ast::ItemConst(..) => {
103-
self.check_item_type(item);
103+
self.check_item_type(item.span, item.id);
104104
}
105105
ast::ItemStruct(ref struct_def, ref ast_generics) => {
106106
self.check_type_defn(item, |fcx| {
@@ -133,32 +133,32 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
133133
}
134134
}
135135

136-
fn with_fcx<F>(&mut self, item: &ast::Item, mut f: F) where
136+
fn with_fcx<F>(&mut self, span: Span, id: ast::NodeId, mut f: F) where
137137
F: for<'fcx> FnMut(&mut CheckTypeWellFormedVisitor<'ccx, 'tcx>, &FnCtxt<'fcx, 'tcx>),
138138
{
139139
let ccx = self.ccx;
140-
let item_def_id = local_def(item.id);
140+
let item_def_id = local_def(id);
141141
let type_scheme = ty::lookup_item_type(ccx.tcx, item_def_id);
142142
let type_predicates = ty::lookup_predicates(ccx.tcx, item_def_id);
143-
reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates);
143+
reject_non_type_param_bounds(ccx.tcx, span, &type_predicates);
144144
let param_env =
145145
ty::construct_parameter_environment(ccx.tcx,
146-
item.span,
146+
span,
147147
&type_scheme.generics,
148148
&type_predicates,
149-
item.id);
149+
id);
150150
let inh = Inherited::new(ccx.tcx, param_env);
151-
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id);
151+
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), id);
152152
f(self, &fcx);
153153
fcx.select_all_obligations_or_error();
154-
regionck::regionck_item(&fcx, item);
154+
regionck::regionck_item(&fcx, id);
155155
}
156156

157157
/// In a type definition, we check that to ensure that the types of the fields are well-formed.
158158
fn check_type_defn<F>(&mut self, item: &ast::Item, mut lookup_fields: F) where
159159
F: for<'fcx> FnMut(&FnCtxt<'fcx, 'tcx>) -> Vec<AdtVariant<'tcx>>,
160160
{
161-
self.with_fcx(item, |this, fcx| {
161+
self.with_fcx(item.span, item.id, |this, fcx| {
162162
let variants = lookup_fields(fcx);
163163
let mut bounds_checker = BoundsChecker::new(fcx,
164164
item.span,
@@ -193,18 +193,17 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
193193
});
194194
}
195195

196-
fn check_item_type(&mut self,
197-
item: &ast::Item)
196+
fn check_item_type(&mut self, span: Span, id: ast::NodeId)
198197
{
199-
self.with_fcx(item, |this, fcx| {
198+
self.with_fcx(span, id, |this, fcx| {
200199
let mut bounds_checker = BoundsChecker::new(fcx,
201-
item.span,
202-
item.id,
200+
span,
201+
id,
203202
Some(&mut this.cache));
204203
debug!("check_item_type at bounds_checker.scope: {:?}", bounds_checker.scope);
205204

206-
let type_scheme = ty::lookup_item_type(fcx.tcx(), local_def(item.id));
207-
let item_ty = fcx.instantiate_type_scheme(item.span,
205+
let type_scheme = ty::lookup_item_type(fcx.tcx(), local_def(id));
206+
let item_ty = fcx.instantiate_type_scheme(span,
208207
&fcx.inh.param_env.free_substs,
209208
&type_scheme.ty);
210209

@@ -215,7 +214,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
215214
fn check_impl(&mut self,
216215
item: &ast::Item)
217216
{
218-
self.with_fcx(item, |this, fcx| {
217+
self.with_fcx(item.span, item.id, |this, fcx| {
219218
let mut bounds_checker = BoundsChecker::new(fcx,
220219
item.span,
221220
item.id,
@@ -426,11 +425,16 @@ fn reject_shadowing_type_parameters<'tcx>(tcx: &ty::ctxt<'tcx>,
426425
}
427426

428427
impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
429-
fn visit_item(&mut self, i: &ast::Item) {
428+
fn visit_item(&mut self, i: &'v ast::Item) {
430429
self.check_item_well_formed(i);
431430
visit::walk_item(self, i);
432431
}
433432

433+
fn visit_foreign_item(&mut self, item: &'v ast::ForeignItem) {
434+
self.check_item_type(item.span, item.id);
435+
visit::walk_foreign_item(self, item);
436+
}
437+
434438
fn visit_fn(&mut self,
435439
fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
436440
b: &'v ast::Block, span: Span, id: ast::NodeId) {

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

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2015 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+
extern {
12+
fn foo(x: Option<str>);
13+
//~^ ERROR the trait `core::marker::Sized` is not implemented
14+
15+
fn foo1(x: &'static Option<[u8]>);
16+
//~^ ERROR the trait `core::marker::Sized` is not implemented
17+
18+
static FOO: &'static [[u16]];
19+
//~^ ERROR the trait `core::marker::Sized` is not implemented
20+
}
21+
22+
fn main() {}

0 commit comments

Comments
 (0)