From f1520ea0cfa2a96731475cea221cd9ab70cf5588 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 24 Jul 2014 13:52:47 -0700 Subject: [PATCH] librustc: Check built-in trait bounds on implementations when direct method calls are involved. This breaks code like: impl Foo for T { ... } fn take_param(foo: &T) { ... } fn main() { let x = box 3i; // note no `Copy` bound take_param(&x); } Change this code to not contain a type error. For example: impl Foo for T { ... } fn take_param(foo: &T) { ... } fn main() { let x = 3i; // satisfies `Copy` bound take_param(&x); } Closes #15860. [breaking-change] --- src/libcore/any.rs | 2 +- src/librustc/middle/kind.rs | 11 ++++++++- .../compile-fail/kindck-impl-type-params-2.rs | 23 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/kindck-impl-type-params-2.rs diff --git a/src/libcore/any.rs b/src/libcore/any.rs index e0ac20d2fbf42..297da495799e7 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -55,7 +55,7 @@ //! } //! //! // This function wants to log its parameter out prior to doing work with it. -//! fn do_work(value: &T) { +//! fn do_work(value: &T) { //! log(value); //! // ...do some other work //! } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 517bdcbff962e..e2e3081eb2d16 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -324,7 +324,8 @@ pub fn check_expr(cx: &mut Context, e: &Expr) { fn check_bounds_on_type_parameters(cx: &mut Context, e: &Expr) { let method_map = cx.tcx.method_map.borrow(); - let method = method_map.find(&typeck::MethodCall::expr(e.id)); + let method_call = typeck::MethodCall::expr(e.id); + let method = method_map.find(&method_call); // Find the values that were provided (if any) let item_substs = cx.tcx.item_substs.borrow(); @@ -393,6 +394,14 @@ fn check_bounds_on_type_parameters(cx: &mut Context, e: &Expr) { type_param_def.space, type_param_def.index, ty.repr(cx.tcx)); check_typaram_bounds(cx, e.span, ty, type_param_def) } + + // Check the vtable. + let vtable_map = cx.tcx.vtable_map.borrow(); + let vtable_res = match vtable_map.find(&method_call) { + None => return, + Some(vtable_res) => vtable_res, + }; + check_type_parameter_bounds_in_vtable_result(cx, e.span, vtable_res); } fn check_type_parameter_bounds_in_vtable_result( diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs new file mode 100644 index 0000000000000..a034e252d31dc --- /dev/null +++ b/src/test/compile-fail/kindck-impl-type-params-2.rs @@ -0,0 +1,23 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo { +} + +impl Foo for T { +} + +fn take_param(foo: &T) { } + +fn main() { + let x = box 3i; + take_param(&x); + //~^ ERROR instantiating a type parameter with an incompatible type +}