Skip to content

Commit

Permalink
check built-in types for well-formedness
Browse files Browse the repository at this point in the history
  • Loading branch information
Ariel Ben-Yehuda committed Jul 9, 2015
1 parent efc3143 commit 0f08261
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 14 deletions.
34 changes: 24 additions & 10 deletions src/librustc_typeck/check/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand All @@ -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
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
23 changes: 23 additions & 0 deletions src/test/compile-fail/issue-24957.rs
Original file line number Diff line number Diff line change
@@ -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 <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.

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()
{
}
3 changes: 0 additions & 3 deletions src/test/compile-fail/unsized6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,10 @@ trait T {}

fn f1<X: ?Sized>(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: ?Sized + T>(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<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
Expand Down
36 changes: 36 additions & 0 deletions src/test/compile-fail/wf-non-well-formed.rs
Original file line number Diff line number Diff line change
@@ -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 <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.

// Check that we catch attempts to create non-well-formed types

struct Bad<T:?Sized+'static, U:?Sized> {
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: Tr>(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() {}
18 changes: 18 additions & 0 deletions src/test/compile-fail/wf-specific-sized-where-clause.rs
Original file line number Diff line number Diff line change
@@ -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 <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.

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() {}

0 comments on commit 0f08261

Please sign in to comment.