Skip to content

Commit

Permalink
auto merge of #13228 : dmski/rust/trait-static-bound, r=brson
Browse files Browse the repository at this point in the history
There wasn't a check for builtin bounds when looking up vtables, only for trait bounds. This led to types sometimes implementing traits they shouldn't have been able to.

Closes #10751
  • Loading branch information
bors committed Apr 18, 2014
2 parents c44c7ab + d3f05f4 commit e4b13cf
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 7 deletions.
14 changes: 7 additions & 7 deletions src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ fn check_impl_of_trait(cx: &mut Context, it: &Item, trait_ref: &TraitRef, self_t
// If this trait has builtin-kind supertraits, meet them.
let self_ty: ty::t = ty::node_id_to_type(cx.tcx, it.id);
debug!("checking impl with self type {:?}", ty::get(self_ty).sty);
check_builtin_bounds(cx, self_ty, trait_def.bounds, |missing| {
check_builtin_bounds(cx.tcx, self_ty, trait_def.bounds, |missing| {
cx.tcx.sess.span_err(self_type.span,
format!("the type `{}', which does not fulfill `{}`, cannot implement this \
trait", ty_to_str(cx.tcx, self_ty), missing.user_string(cx.tcx)));
Expand Down Expand Up @@ -357,14 +357,14 @@ fn check_ty(cx: &mut Context, aty: &Ty) {
}

// Calls "any_missing" if any bounds were missing.
pub fn check_builtin_bounds(cx: &Context,
pub fn check_builtin_bounds(tcx: &ty::ctxt,
ty: ty::t,
bounds: ty::BuiltinBounds,
any_missing: |ty::BuiltinBounds|) {
let kind = ty::type_contents(cx.tcx, ty);
let kind = ty::type_contents(tcx, ty);
let mut missing = ty::EmptyBuiltinBounds();
for bound in bounds.iter() {
if !kind.meets_bound(cx.tcx, bound) {
if !kind.meets_bound(tcx, bound) {
missing.add(bound);
}
}
Expand All @@ -377,7 +377,7 @@ pub fn check_typaram_bounds(cx: &Context,
sp: Span,
ty: ty::t,
type_param_def: &ty::TypeParameterDef) {
check_builtin_bounds(cx,
check_builtin_bounds(cx.tcx,
ty,
type_param_def.bounds.builtin_bounds,
|missing| {
Expand All @@ -393,7 +393,7 @@ pub fn check_typaram_bounds(cx: &Context,
pub fn check_freevar_bounds(cx: &Context, sp: Span, ty: ty::t,
bounds: ty::BuiltinBounds, referenced_ty: Option<ty::t>)
{
check_builtin_bounds(cx, ty, bounds, |missing| {
check_builtin_bounds(cx.tcx, ty, bounds, |missing| {
// Will be Some if the freevar is implicitly borrowed (stack closure).
// Emit a less mysterious error message in this case.
match referenced_ty {
Expand All @@ -415,7 +415,7 @@ pub fn check_freevar_bounds(cx: &Context, sp: Span, ty: ty::t,

pub fn check_trait_cast_bounds(cx: &Context, sp: Span, ty: ty::t,
bounds: ty::BuiltinBounds) {
check_builtin_bounds(cx, ty, bounds, |missing| {
check_builtin_bounds(cx.tcx, ty, bounds, |missing| {
cx.tcx.sess.span_err(sp,
format!("cannot pack type `{}`, which does not fulfill \
`{}`, as a trait bounded by {}",
Expand Down
23 changes: 23 additions & 0 deletions src/librustc/middle/typeck/check/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// except according to those terms.


use middle::kind::check_builtin_bounds;
use middle::ty;
use middle::ty::{AutoAddEnv, AutoDerefRef, AutoObject, param_ty};
use middle::ty_fold::TypeFolder;
Expand All @@ -26,6 +27,7 @@ use middle::subst::Subst;
use util::common::indenter;
use util::ppaux;
use util::ppaux::Repr;
use util::ppaux::UserString;

use collections::HashSet;
use std::cell::RefCell;
Expand Down Expand Up @@ -124,6 +126,27 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
is_early: bool) -> vtable_param_res {
let tcx = vcx.tcx();

// FIXME(#13231): this will likely break once opt-in builtin kinds are implemented
if !type_param_bounds.builtin_bounds.is_empty() {
match fixup_ty(vcx, span, ty, is_early) {
Some(fix_ty) => {
check_builtin_bounds(
vcx.tcx(),
fix_ty,
type_param_bounds.builtin_bounds,
|missing: ty::BuiltinBounds| {
vcx.tcx().sess.span_err(
span,
format!("instantiating a type parameter with an incompatible type \
`{}`, which does not fulfill `{}`",
vcx.infcx.ty_to_str(ty),
missing.user_string(tcx)));
});
}
None => {}
}
}

// ty is the value supplied for the type parameter A...
let mut param_result = Vec::new();

Expand Down
47 changes: 47 additions & 0 deletions src/test/compile-fail/issue-10751.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2014 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.

// Test that builtin bounds are checked when searching for an
// implementation of a trait
use std::cell::Cell;

trait A {}
trait B {}
trait C {}
trait D {}
impl<T: 'static> A for T {}
impl<T: Send> B for T {}
impl<T: Copy> C for T {}
impl<T: Share> D for T {}

fn main() {
let a = 3;
let b = &a;
let c = &b as &A; //~ ERROR instantiating a type parameter with an incompatible type `&int`
let d: &A = &b; //~ ERROR instantiating a type parameter with an incompatible type `&int`
let e = &b as &B; //~ ERROR instantiating a type parameter with an incompatible type `&int`
let f: &B = &b; //~ ERROR instantiating a type parameter with an incompatible type `&int`
let g = &~b as &C; //~ ERROR instantiating a type parameter with an incompatible type `~&int`
let h: &C = &~b; //~ ERROR instantiating a type parameter with an incompatible type `~&int`
let i = &Cell::new(b) as &D;
//~^ ERROR instantiating a type parameter with an incompatible type `std::cell::Cell<&int>`
let j: &D = &Cell::new(b);
//~^ ERROR instantiating a type parameter with an incompatible type `std::cell::Cell<&int>`

// These are all ok: int is 'static + Send + Copy + Share
let k: &A = b;
let l: &B = b;
let m: &C = b;
let n: &D = b;
let o = b as &A;
let p = b as &B;
let q = b as &C;
let r = b as &D;
}

0 comments on commit e4b13cf

Please sign in to comment.