From 0f082616f8b1e0d3880e9122b4ace7a12daf42aa Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 9 Jul 2015 15:35:52 +0300 Subject: [PATCH] check built-in types for well-formedness Fixes #21111. Fixes #24707. Fixes #24957. Fixes #25388. Fixes #25637. Fixes #26301. --- src/librustc_typeck/check/wf.rs | 34 ++++++++++++------ .../associated-types-coherence-failure.rs | 2 +- src/test/compile-fail/issue-24957.rs | 23 ++++++++++++ src/test/compile-fail/unsized6.rs | 3 -- src/test/compile-fail/wf-non-well-formed.rs | 36 +++++++++++++++++++ .../wf-specific-sized-where-clause.rs | 18 ++++++++++ 6 files changed, 102 insertions(+), 14 deletions(-) create mode 100644 src/test/compile-fail/issue-24957.rs create mode 100644 src/test/compile-fail/wf-non-well-formed.rs create mode 100644 src/test/compile-fail/wf-specific-sized-where-clause.rs diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 05c34ee28a462..929560107ac5d 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -538,6 +538,10 @@ impl<'cx,'tcx> BoundsChecker<'cx,'tcx> { ty.fold_with(self); self.binding_count -= 1; } + + fn cause(&self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> { + traits::ObligationCause::new(self.span, self.fcx.body_id, code) + } } impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> { @@ -574,7 +578,22 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> { None => { } } - match t.sty{ + match t.sty { + ty::TyArray(ety, _) | ty::TySlice(ety) => { + self.fcx.register_builtin_bound(self.fold_ty(ety), + ty::BoundSized, + self.cause(traits::MiscObligation)); + t + } + ty::TyTuple(ref tys) => { + for ty in tys { + self.fcx.register_builtin_bound(self.fold_ty(ty), + ty::BoundSized, + self.cause(traits::MiscObligation) + ); + } + t + } ty::TyStruct(type_id, substs) | ty::TyEnum(type_id, substs) => { let type_predicates = self.fcx.tcx().lookup_predicates(type_id); @@ -583,9 +602,7 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> { if self.binding_count == 0 { self.fcx.add_obligations_for_parameters( - traits::ObligationCause::new(self.span, - self.fcx.body_id, - traits::ItemObligation(type_id)), + self.cause(traits::ItemObligation(type_id)), &bounds); } else { // There are two circumstances in which we ignore @@ -612,20 +629,17 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> { // that will require an RFC. -nmatsakis) let bounds = filter_to_trait_obligations(bounds); self.fcx.add_obligations_for_parameters( - traits::ObligationCause::new(self.span, - self.fcx.body_id, - traits::ItemObligation(type_id)), + self.cause(traits::ItemObligation(type_id)), &bounds); } self.fold_substs(substs); + t } _ => { - super_fold_ty(self, t); + super_fold_ty(self, t) } } - - t // we're not folding to produce a new type, so just return `t` here } } diff --git a/src/test/compile-fail/associated-types-coherence-failure.rs b/src/test/compile-fail/associated-types-coherence-failure.rs index 915cb077787ea..cdec546ea9422 100644 --- a/src/test/compile-fail/associated-types-coherence-failure.rs +++ b/src/test/compile-fail/associated-types-coherence-failure.rs @@ -14,7 +14,7 @@ use std::marker::PhantomData; use std::ops::Deref; -pub struct Cow<'a, B: ?Sized>(PhantomData<(&'a (),B)>); +pub struct Cow<'a, B: ?Sized>(PhantomData<(&'a (),*mut B)>); /// Trait for moving into a `Cow` pub trait IntoCow<'a, B: ?Sized> { diff --git a/src/test/compile-fail/issue-24957.rs b/src/test/compile-fail/issue-24957.rs new file mode 100644 index 0000000000000..e3c5086a2d33f --- /dev/null +++ b/src/test/compile-fail/issue-24957.rs @@ -0,0 +1,23 @@ +// 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. + +pub enum BsonValue { + A([u8]), + B([BsonValue]), //~ ERROR the trait `core::marker::Sized` is not implemented + //~^ ERROR the trait `core::marker::Sized` is not implemented +} + +pub fn set_value(_v:&BsonValue) +{ +} + +fn main() +{ +} diff --git a/src/test/compile-fail/unsized6.rs b/src/test/compile-fail/unsized6.rs index 3f18f359d306e..caf20a06c01db 100644 --- a/src/test/compile-fail/unsized6.rs +++ b/src/test/compile-fail/unsized6.rs @@ -14,13 +14,10 @@ trait T {} fn f1(x: &X) { let _: X; // <-- this is OK, no bindings created, no initializer. - let _: (isize, (X, isize)); // same let y: X; //~ERROR the trait `core::marker::Sized` is not implemented - let y: (isize, (X, isize)); //~ERROR the trait `core::marker::Sized` is not implemented } fn f2(x: &X) { let y: X; //~ERROR the trait `core::marker::Sized` is not implemented - let y: (isize, (X, isize)); //~ERROR the trait `core::marker::Sized` is not implemented } fn f3(x1: Box, x2: Box, x3: Box) { diff --git a/src/test/compile-fail/wf-non-well-formed.rs b/src/test/compile-fail/wf-non-well-formed.rs new file mode 100644 index 0000000000000..3b647451cb5d2 --- /dev/null +++ b/src/test/compile-fail/wf-non-well-formed.rs @@ -0,0 +1,36 @@ +// 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. + +// Check that we catch attempts to create non-well-formed types + +struct Bad { + p1: &'static [T], //~ ERROR the trait `core::marker::Sized` is not implemented + p2: U, //~ ERROR the trait `core::marker::Sized` is not implemented + p3: u32 +} + +trait Tr {} + +struct S(T); + +fn b1() -> &'static [(u8,fn(&'static [S<()>]))] +{} //~^ ERROR the trait `Tr` is not implemented +fn b2() -> &'static [[i8]] +{} //~^ ERROR the trait `core::marker::Sized` is not implemented +fn b3() -> &'static [[u16]; 2] +{} //~^ ERROR the trait `core::marker::Sized` is not implemented +fn b4() -> &'static ([i16],) +{} //~^ ERROR the trait `core::marker::Sized` is not implemented +fn b5() -> &'static (u32,[i32],u32) +{} //~^ ERROR the trait `core::marker::Sized` is not implemented +fn b6() -> &'static (u32,u32,[i64]) +{} //~^ ERROR the trait `core::marker::Sized` is not implemented + +fn main() {} diff --git a/src/test/compile-fail/wf-specific-sized-where-clause.rs b/src/test/compile-fail/wf-specific-sized-where-clause.rs new file mode 100644 index 0000000000000..0856bc99f9342 --- /dev/null +++ b/src/test/compile-fail/wf-specific-sized-where-clause.rs @@ -0,0 +1,18 @@ +// 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. + +struct Wrap<'a, T: ?Sized>(&'a (), T); + +fn foo<'a, T>(_a: for<'s> fn() -> [Wrap<'s, T>]) where Wrap<'a, T>: Sized { + //~^ ERROR mismatched types + //~^^ ERROR mismatched types +} + +fn main() {}