Skip to content

Commit

Permalink
Check the types of extern items
Browse files Browse the repository at this point in the history
Fixes #25637.
  • Loading branch information
arielb1 committed May 22, 2015
1 parent 6929069 commit 2a8a289
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 23 deletions.
6 changes: 3 additions & 3 deletions src/librustc_typeck/check/regionck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
rcx.resolve_regions_and_report_errors();
}

pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) {
let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id));
pub fn regionck_item(fcx: &FnCtxt, id: ast::NodeId) {
let mut rcx = Rcx::new(fcx, RepeatingScope(id), id, Subject(id));
let tcx = fcx.tcx();
rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds);
rcx.visit_region_obligations(item.id);
rcx.visit_region_obligations(id);
rcx.resolve_regions_and_report_errors();
}

Expand Down
44 changes: 24 additions & 20 deletions src/librustc_typeck/check/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
}
}
ast::ItemFn(..) => {
self.check_item_type(item);
self.check_item_type(item.span, item.id);
}
ast::ItemStatic(..) => {
self.check_item_type(item);
self.check_item_type(item.span, item.id);
}
ast::ItemConst(..) => {
self.check_item_type(item);
self.check_item_type(item.span, item.id);
}
ast::ItemStruct(ref struct_def, ref ast_generics) => {
self.check_type_defn(item, |fcx| {
Expand Down Expand Up @@ -133,32 +133,32 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
}
}

fn with_fcx<F>(&mut self, item: &ast::Item, mut f: F) where
fn with_fcx<F>(&mut self, span: Span, id: ast::NodeId, mut f: F) where
F: for<'fcx> FnMut(&mut CheckTypeWellFormedVisitor<'ccx, 'tcx>, &FnCtxt<'fcx, 'tcx>),
{
let ccx = self.ccx;
let item_def_id = local_def(item.id);
let item_def_id = local_def(id);
let type_scheme = ty::lookup_item_type(ccx.tcx, item_def_id);
let type_predicates = ty::lookup_predicates(ccx.tcx, item_def_id);
reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates);
reject_non_type_param_bounds(ccx.tcx, span, &type_predicates);
let param_env =
ty::construct_parameter_environment(ccx.tcx,
item.span,
span,
&type_scheme.generics,
&type_predicates,
item.id);
id);
let inh = Inherited::new(ccx.tcx, param_env);
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id);
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), id);
f(self, &fcx);
fcx.select_all_obligations_or_error();
regionck::regionck_item(&fcx, item);
regionck::regionck_item(&fcx, id);
}

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

fn check_item_type(&mut self,
item: &ast::Item)
fn check_item_type(&mut self, span: Span, id: ast::NodeId)
{
self.with_fcx(item, |this, fcx| {
self.with_fcx(span, id, |this, fcx| {
let mut bounds_checker = BoundsChecker::new(fcx,
item.span,
item.id,
span,
id,
Some(&mut this.cache));
debug!("check_item_type at bounds_checker.scope: {:?}", bounds_checker.scope);

let type_scheme = ty::lookup_item_type(fcx.tcx(), local_def(item.id));
let item_ty = fcx.instantiate_type_scheme(item.span,
let type_scheme = ty::lookup_item_type(fcx.tcx(), local_def(id));
let item_ty = fcx.instantiate_type_scheme(span,
&fcx.inh.param_env.free_substs,
&type_scheme.ty);

Expand All @@ -215,7 +214,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
fn check_impl(&mut self,
item: &ast::Item)
{
self.with_fcx(item, |this, fcx| {
self.with_fcx(item.span, item.id, |this, fcx| {
let mut bounds_checker = BoundsChecker::new(fcx,
item.span,
item.id,
Expand Down Expand Up @@ -426,11 +425,16 @@ fn reject_shadowing_type_parameters<'tcx>(tcx: &ty::ctxt<'tcx>,
}

impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
fn visit_item(&mut self, i: &'v ast::Item) {
self.check_item_well_formed(i);
visit::walk_item(self, i);
}

fn visit_foreign_item(&mut self, item: &'v ast::ForeignItem) {
self.check_item_type(item.span, item.id);
visit::walk_foreign_item(self, item);
}

fn visit_fn(&mut self,
fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, span: Span, id: ast::NodeId) {
Expand Down
22 changes: 22 additions & 0 deletions src/test/compile-fail/issue-25637.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2015 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.

extern {
fn foo(x: Option<str>);
//~^ ERROR the trait `core::marker::Sized` is not implemented

fn foo1(x: &'static Option<[u8]>);
//~^ ERROR the trait `core::marker::Sized` is not implemented

static FOO: &'static [[u16]];
//~^ ERROR the trait `core::marker::Sized` is not implemented
}

fn main() {}

0 comments on commit 2a8a289

Please sign in to comment.