Skip to content

Commit efc3143

Browse files
author
Ariel Ben-Yehuda
committed
check extern-items for well-formedness
Fixes rust-lang#25637 this is of course a [breaking-change] to these who relied on it
1 parent 9c3ba76 commit efc3143

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
@@ -121,12 +121,12 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
121121
rcx.resolve_regions_and_report_errors();
122122
}
123123

124-
pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) {
125-
let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id));
124+
pub fn regionck_item(fcx: &FnCtxt, id: ast::NodeId) {
125+
let mut rcx = Rcx::new(fcx, RepeatingScope(id), id, Subject(id));
126126
let tcx = fcx.tcx();
127127
rcx.free_region_map
128128
.relate_free_regions_from_predicates(tcx, &fcx.infcx().parameter_environment.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| {
@@ -132,31 +132,31 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
132132
}
133133
}
134134

135-
fn with_fcx<F>(&mut self, item: &ast::Item, mut f: F) where
135+
fn with_fcx<F>(&mut self, span: Span, id: ast::NodeId, mut f: F) where
136136
F: for<'fcx> FnMut(&mut CheckTypeWellFormedVisitor<'ccx, 'tcx>, &FnCtxt<'fcx, 'tcx>),
137137
{
138138
let ccx = self.ccx;
139-
let item_def_id = local_def(item.id);
139+
let item_def_id = local_def(id);
140140
let type_scheme = ccx.tcx.lookup_item_type(item_def_id);
141141
let type_predicates = ccx.tcx.lookup_predicates(item_def_id);
142-
reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates);
143-
let param_env = ccx.tcx.construct_parameter_environment(item.span,
142+
reject_non_type_param_bounds(ccx.tcx, span, &type_predicates);
143+
let param_env = ccx.tcx.construct_parameter_environment(span,
144144
&type_scheme.generics,
145145
&type_predicates,
146-
item.id);
146+
id);
147147
let tables = RefCell::new(ty::Tables::empty());
148148
let inh = Inherited::new(ccx.tcx, &tables, param_env);
149-
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id);
149+
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), id);
150150
f(self, &fcx);
151151
fcx.select_all_obligations_or_error();
152-
regionck::regionck_item(&fcx, item);
152+
regionck::regionck_item(&fcx, id);
153153
}
154154

155155
/// In a type definition, we check that to ensure that the types of the fields are well-formed.
156156
fn check_type_defn<F>(&mut self, item: &ast::Item, mut lookup_fields: F) where
157157
F: for<'fcx> FnMut(&FnCtxt<'fcx, 'tcx>) -> Vec<AdtVariant<'tcx>>,
158158
{
159-
self.with_fcx(item, |this, fcx| {
159+
self.with_fcx(item.span, item.id, |this, fcx| {
160160
let variants = lookup_fields(fcx);
161161
let mut bounds_checker = BoundsChecker::new(fcx,
162162
item.id,
@@ -190,31 +190,30 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
190190
});
191191
}
192192

193-
fn check_item_type(&mut self,
194-
item: &ast::Item)
193+
fn check_item_type(&mut self, span: Span, id: ast::NodeId)
195194
{
196-
self.with_fcx(item, |this, fcx| {
195+
self.with_fcx(span, id, |this, fcx| {
197196
let mut bounds_checker = BoundsChecker::new(fcx,
198-
item.id,
197+
id,
199198
Some(&mut this.cache));
200199
debug!("check_item_type at bounds_checker.scope: {:?}", bounds_checker.scope);
201200

202-
let type_scheme = fcx.tcx().lookup_item_type(local_def(item.id));
203-
let item_ty = fcx.instantiate_type_scheme(item.span,
201+
let type_scheme = fcx.tcx().lookup_item_type(local_def(id));
202+
let item_ty = fcx.instantiate_type_scheme(span,
204203
&fcx.inh
205204
.infcx
206205
.parameter_environment
207206
.free_substs,
208207
&type_scheme.ty);
209208

210-
bounds_checker.check_traits_in_ty(item_ty, item.span);
209+
bounds_checker.check_traits_in_ty(item_ty, span);
211210
});
212211
}
213212

214213
fn check_impl(&mut self,
215214
item: &ast::Item)
216215
{
217-
self.with_fcx(item, |this, fcx| {
216+
self.with_fcx(item.span, item.id, |this, fcx| {
218217
let mut bounds_checker = BoundsChecker::new(fcx,
219218
item.id,
220219
Some(&mut this.cache));
@@ -428,11 +427,16 @@ fn reject_shadowing_type_parameters<'tcx>(tcx: &ty::ctxt<'tcx>,
428427
}
429428

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

435+
fn visit_foreign_item(&mut self, i: &'v ast::ForeignItem) {
436+
self.check_item_type(i.span, i.id);
437+
visit::walk_foreign_item(self, i);
438+
}
439+
436440
fn visit_fn(&mut self,
437441
fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
438442
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 Option<[u16]>;
19+
//~^ ERROR the trait `core::marker::Sized` is not implemented
20+
}
21+
22+
fn main() {}

0 commit comments

Comments
 (0)