fix treatment of parameters and associated types

This commit is contained in:
Niko Matsakis 2015-02-20 05:16:59 -05:00 committed by Flavio Percoco
parent 1cc5a87c08
commit 640000a7c0
3 changed files with 96 additions and 17 deletions

View file

@ -1142,27 +1142,49 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
});
}
if ty::trait_has_default_impl(self.tcx(), def_id) {
match self_ty.sty {
ty::ty_trait(..) => {},
ty::ty_trait(..) |
ty::ty_param(..) |
ty::ty_projection(..) => {
// In these cases, we don't know what the actual
// type is. Therefore, we cannot break it down
// into its constituent types. So we don't
// consider the `..` impl but instead just add no
// candidates: this means that typeck will only
// succeed if there is another reason to believe
// that this obligation holds. That could be a
// where-clause or, in the case of an object type,
// it could be that the object type lists the
// trait (e.g. `Foo+Send : Send`). See
// `compile-fail/typeck-default-trait-impl-send-param.rs`
// for an example of a test case that exercises
// this path.
}
ty::ty_infer(ty::TyVar(_)) => {
// the defaulted impl might apply, we don't know
if ty::trait_has_default_impl(self.tcx(), def_id) {
candidates.ambiguous = true;
}
}
_ => {
if ty::trait_has_default_impl(self.tcx(), def_id) {
match self.constituent_types_for_ty(self_ty) {
Some(_) => {
if self.constituent_types_for_ty(self_ty).is_some() {
candidates.vec.push(DefaultImplCandidate(def_id.clone()))
}
None => {
} else {
// We don't yet know what the constituent
// types are. So call it ambiguous for now,
// though this is a bit stronger than
// necessary: that is, we know that the
// defaulted impl applies, but we can't
// process the confirmation step without
// knowing the constituent types. (Anyway, in
// the particular case of defaulted impls, it
// doesn't really matter much either way,
// since we won't be aiding inference by
// processing the confirmation step.)
candidates.ambiguous = true;
}
}
}
}
}
Ok(())
}
@ -1632,6 +1654,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
/// For default impls, we need to break apart a type into its
/// "constituent types" -- meaning, the types that it contains.
///
/// Here are some (simple) examples:
///
/// ```
/// (i32, u32) -> [i32, u32]
/// Foo where struct Foo { x: i32, y: u32 } -> [i32, u32]
/// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
/// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
/// ```
fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Option<Vec<Ty<'tcx>>> {
match t.sty {
ty::ty_uint(_) |
@ -1641,7 +1674,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::ty_bare_fn(..) |
ty::ty_str |
ty::ty_err |
ty::ty_param(..) |
ty::ty_infer(ty::IntVar(_)) |
ty::ty_infer(ty::FloatVar(_)) |
ty::ty_char => {
@ -1649,8 +1681,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
ty::ty_trait(..) |
ty::ty_param(..) |
ty::ty_projection(..) |
ty::ty_infer(_) => {
ty::ty_infer(ty::TyVar(_)) => {
self.tcx().sess.bug(
&format!(
"asked to assemble constituent types of unexpected type: {}",

View file

@ -0,0 +1,25 @@
// 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.
// Test that we do not consider associated types to be sendable without
// some applicable trait bound (and we don't ICE).
trait Trait {
type AssocType;
fn dummy(&self) { }
}
fn bar<T:Trait+Send>() {
is_send::<T::AssocType>(); //~ ERROR not implemented
}
fn is_send<T:Send>() {
}
fn main() { }

View file

@ -0,0 +1,21 @@
// 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.
// Test that we do not consider parameter types to be sendable without
// an explicit trait bound.
fn foo<T>() {
is_send::<T>() //~ ERROR not implemented
}
fn is_send<T:Send>() {
}
fn main() { }