}
}
-/// in various error cases, we just set TyError and return an obligation
-/// that, when fulfilled, will lead to an error.
+/// If we are projecting `<T as Trait>::Item`, but `T: Trait` does not
+/// hold. In various error cases, we cannot generate a valid
+/// normalized projection. Therefore, we create an inference variable
+/// return an associated obligation that, when fulfilled, will lead to
+/// an error.
///
-/// FIXME: the TyError created here can enter the obligation we create,
-/// leading to error messages involving TyError.
+/// Note that we used to return `TyError` here, but that was quite
+/// dubious -- the premise was that an error would *eventually* be
+/// reported, when the obligation was processed. But in general once
+/// you see a `TyError` you are supposed to be able to assume that an
+/// error *has been* reported, so that you can take whatever heuristic
+/// paths you want to take. To make things worse, it was possible for
+/// cycles to arise, where you basically had a setup like `<MyType<$0>
+/// as Trait>::Foo == $0`. Here, normalizing `<MyType<$0> as
+/// Trait>::Foo> to `[type error]` would lead to an obligation of
+/// `<MyType<[type error]> as Trait>::Foo`. We are supposed to report
+/// an error for this obligation, but we legitimately should not,
+/// because it contains `[type error]`. Yuck! (See issue #29857 for
+/// one case where this arose.)
fn normalize_to_error<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
cause: ObligationCause<'tcx>,
let trait_obligation = Obligation { cause: cause,
recursion_depth: depth,
predicate: trait_ref.to_predicate() };
+ let new_value = selcx.infcx().next_ty_var();
Normalized {
- value: selcx.tcx().types.err,
+ value: new_value,
obligations: vec!(trait_obligation)
}
}
t_cast: Ty<'tcx>,
t_expr: Ty<'tcx>,
id: ast::NodeId) {
+ if t_cast.references_error() || t_expr.references_error() {
+ return;
+ }
let tstr = fcx.infcx().ty_to_string(t_cast);
let mut err = fcx.type_error_struct(span, |actual| {
format!("cast to unsized type: `{}` as `{}`", actual, tstr)
--- /dev/null
+// Copyright 2016 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.
+
+// Coherence error results because we do not know whether `T: Foo<P>` or not
+// for the second impl.
+
+use std::marker::PhantomData;
+
+pub trait Foo<P> {}
+
+impl <P, T: Foo<P>> Foo<P> for Option<T> {} //~ ERROR E0119
+
+impl<T, U> Foo<T> for Option<U> { }
+
+fn main() {}
const A_I8_T
: [u32; (i8::MAX as i8 + 1u8) as usize]
//~^ ERROR mismatched types
- //~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
+ //~| ERROR the trait `core::ops::Add<u8>` is not implemented for the type `i8`
= [0; (i8::MAX as usize) + 1];
fn main() {
fn akemi(homura: Homura) {
let Some(ref madoka) = Some(homura.kaname()); //~ ERROR no method named `kaname` found
- madoka.clone(); //~ ERROR the type of this value must be known in this context
+ madoka.clone();
}
fn main() { }
let x = &10 as
&Add;
//~^ ERROR the type parameter `RHS` must be explicitly specified in an object type because its default value `Self` references the type `Self`
- //~^^ ERROR the value of the associated type `Output` (from the trait `core::ops::Add`) must be specified
+ //~| ERROR the value of the associated type `Output` (from the trait `core::ops::Add`) must be specified
}
// except according to those terms.
fn main() {
- "".chars().fold(|_, _| (), ()); //~ ERROR is not implemented for the type `()`
+ "".chars().fold(|_, _| (), ());
+ //~^ ERROR E0277
+ //~| ERROR E0277
}
fn main() {
1.0f64 - 1.0;
- 1.0f64 - 1 //~ ERROR: is not implemented
+ 1.0f64 - 1 //~ ERROR E0277
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+
+#![feature(rustc_attrs)]
+
use std::marker::PhantomData;
pub trait Foo<P> {}
-impl <P, T: Foo<P>> Foo<P> for Option<T> {} //~ ERROR E0119
+impl <P, T: Foo<P>> Foo<P> for Option<T> {}
pub struct Qux<T> (PhantomData<*mut T>);
impl<T: 'static, W: Bar<Output = T>> Foo<*mut T> for W {}
-fn main() {}
+#[rustc_error]
+fn main() {} //~ ERROR compilation successful
let p = Point::new(0.0, 0.0);
//~^ ERROR no associated item named `new` found for type `Point` in the current scope
println!("{}", p.to_string());
- //~^ ERROR the type of this value must be known in this context
}