From 2a8a2893f6ee36491d6cd64261a7822b30c67449 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Fri, 22 May 2015 16:02:24 +0300 Subject: [PATCH] Check the types of extern items Fixes #25637. --- src/librustc_typeck/check/regionck.rs | 6 ++-- src/librustc_typeck/check/wf.rs | 44 +++++++++++++++------------ src/test/compile-fail/issue-25637.rs | 22 ++++++++++++++ 3 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 src/test/compile-fail/issue-25637.rs diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 090d111b62b89..3d371d7acb216 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -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(); } diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 347c323cc567c..45bd4ea088551 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -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| { @@ -133,32 +133,32 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { } } - fn with_fcx(&mut self, item: &ast::Item, mut f: F) where + fn with_fcx(&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(&mut self, item: &ast::Item, mut lookup_fields: F) where F: for<'fcx> FnMut(&FnCtxt<'fcx, 'tcx>) -> Vec>, { - 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, @@ -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); @@ -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, @@ -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) { diff --git a/src/test/compile-fail/issue-25637.rs b/src/test/compile-fail/issue-25637.rs new file mode 100644 index 0000000000000..99eea3154fb50 --- /dev/null +++ b/src/test/compile-fail/issue-25637.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern { + fn foo(x: Option); + //~^ 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() {}