// FIXME(eddyb) #11161 is the original Expr required?
ExprAssignable(Span),
- // Relating trait refs when resolving vtables
- RelateTraitRefs(Span),
-
- // Relating self types when resolving vtables
- RelateSelfType(Span),
-
// Relating trait type parameters to those found in impl etc
RelateOutputImplTypes(Span),
// intrinsic has wrong type
IntrinsicType(Span),
+
+ // method receiver
+ MethodReceiver(Span),
}
impl TypeOrigin {
fn as_failure_str(&self) -> &'static str {
match self {
&TypeOrigin::Misc(_) |
- &TypeOrigin::RelateSelfType(_) |
&TypeOrigin::RelateOutputImplTypes(_) |
&TypeOrigin::ExprAssignable(_) => "mismatched types",
- &TypeOrigin::RelateTraitRefs(_) => "mismatched traits",
&TypeOrigin::MethodCompatCheck(_) => "method not compatible with trait",
&TypeOrigin::MatchExpressionArm(_, _, source) => match source {
hir::MatchSource::IfLetDesugar{..} => "`if let` arms have incompatible types",
&TypeOrigin::MainFunctionType(_) => "main function has wrong type",
&TypeOrigin::StartFunctionType(_) => "start function has wrong type",
&TypeOrigin::IntrinsicType(_) => "intrinsic has wrong type",
+ &TypeOrigin::MethodReceiver(_) => "mismatched method receiver",
}
}
&TypeOrigin::Misc(_) => "types are compatible",
&TypeOrigin::MethodCompatCheck(_) => "method type is compatible with trait",
&TypeOrigin::ExprAssignable(_) => "expression is assignable",
- &TypeOrigin::RelateTraitRefs(_) => "traits are compatible",
- &TypeOrigin::RelateSelfType(_) => "self type matches impl self type",
&TypeOrigin::RelateOutputImplTypes(_) => {
"trait type parameters matches those specified on the impl"
}
&TypeOrigin::MainFunctionType(_) => "`main` function has the correct type",
&TypeOrigin::StartFunctionType(_) => "`start` function has the correct type",
&TypeOrigin::IntrinsicType(_) => "intrinsic has the correct type",
+ &TypeOrigin::MethodReceiver(_) => "method receiver has the correct type",
}
}
}
TypeOrigin::MethodCompatCheck(span) => span,
TypeOrigin::ExprAssignable(span) => span,
TypeOrigin::Misc(span) => span,
- TypeOrigin::RelateTraitRefs(span) => span,
- TypeOrigin::RelateSelfType(span) => span,
TypeOrigin::RelateOutputImplTypes(span) => span,
TypeOrigin::MatchExpressionArm(match_span, _, _) => match_span,
TypeOrigin::IfExpression(span) => span,
TypeOrigin::MainFunctionType(span) => span,
TypeOrigin::StartFunctionType(span) => span,
TypeOrigin::IntrinsicType(span) => span,
+ TypeOrigin::MethodReceiver(span) => span,
}
}
}
diag.span_label(err.span, &message);
}
}
- ConstEvalErrDescription::ExpectedFound { error, expected, found } => {
- if check_old_school() {
- diag.note(&error);
- } else {
- diag.span_label(err.span, &error);
- }
- diag.note(&format!("expected `{}`", expected));
- diag.note(&format!("found `{}`", found));
- }
}
if !primary_span.contains(err.span) {
#[derive(Clone, Debug)]
pub enum ConstEvalErrDescription<'a> {
Simple(Cow<'a, str>),
- ExpectedFound {
- error: Cow<'a, str>,
- expected: Cow<'a, str>,
- found: Cow<'a, str>
- }
}
impl<'a> ConstEvalErrDescription<'a> {
pub fn into_oneline(self) -> Cow<'a, str> {
match self {
ConstEvalErrDescription::Simple(simple) => simple,
- ConstEvalErrDescription::ExpectedFound {
- error,
- expected,
- found
- } => {
- format!("{}: expected `{}`, found `{}`", error, expected, found)
- .into_cow()
- }
}
}
}
the constant evaluator"),
TypeMismatch(ref expected, ref got) => {
- ExpectedFound {
- error: "mismatched types".into_cow(),
- expected: <&str>::into_cow(expected),
- found: got.description().into_cow()
- }
+ simple!("expected {}, found {}", expected, got.description())
},
BadType(ref i) => simple!("value of wrong type: {:?}", i),
ErroneousReferencedConstant(_) => simple!("could not evaluate referenced constant"),
}
pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
- let origin = TypeOrigin::Misc(sp);
+ self.demand_eqtype_with_origin(TypeOrigin::Misc(sp), expected, actual);
+ }
+
+ pub fn demand_eqtype_with_origin(&self,
+ origin: TypeOrigin,
+ expected: Ty<'tcx>,
+ actual: Ty<'tcx>)
+ {
match self.eq_types(false, origin, actual, expected) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
use CrateCtxt;
use hir::def_id::DefId;
use middle::region::{CodeExtent};
+use rustc::infer::TypeOrigin;
use rustc::ty::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt};
}
}
- fn check_trait_or_impl_item(&mut self, item_id: ast::NodeId, span: Span) {
+ fn check_trait_or_impl_item(&mut self,
+ item_id: ast::NodeId,
+ span: Span,
+ sig_if_method: Option<&hir::MethodSig>) {
let code = self.code.clone();
self.for_id(item_id, span).with_fcx(|fcx, this| {
let free_substs = &fcx.parameter_environment.free_substs;
let predicates = fcx.instantiate_bounds(span, free_substs, &method.predicates);
this.check_fn_or_method(fcx, span, &method_ty, &predicates,
free_id_outlive, &mut implied_bounds);
- this.check_method_receiver(fcx, span, &method,
+ let sig_if_method = sig_if_method.expect("bad signature for method");
+ this.check_method_receiver(fcx, sig_if_method, &method,
free_id_outlive, self_ty);
}
ty::TypeTraitItem(assoc_type) => {
fn check_method_receiver<'fcx, 'tcx>(&mut self,
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
- span: Span,
+ method_sig: &hir::MethodSig,
method: &ty::Method<'tcx>,
free_id_outlive: CodeExtent,
self_ty: ty::Ty<'tcx>)
{
// check that the type of the method's receiver matches the
// method's first parameter.
-
- let free_substs = &fcx.parameter_environment.free_substs;
- let fty = fcx.instantiate_type_scheme(span, free_substs, &method.fty);
- let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &fty.sig);
-
- debug!("check_method_receiver({:?},cat={:?},self_ty={:?},sig={:?})",
- method.name, method.explicit_self, self_ty, sig);
+ debug!("check_method_receiver({:?},cat={:?},self_ty={:?})",
+ method.name, method.explicit_self, self_ty);
let rcvr_ty = match method.explicit_self {
ty::ExplicitSelfCategory::Static => return,
}
ty::ExplicitSelfCategory::ByBox => fcx.tcx.mk_box(self_ty)
};
+
+ let span = method_sig.decl.inputs[0].pat.span;
+
+ let free_substs = &fcx.parameter_environment.free_substs;
+ let fty = fcx.instantiate_type_scheme(span, free_substs, &method.fty);
+ let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &fty.sig);
+
+ debug!("check_method_receiver: sig={:?}", sig);
+
let rcvr_ty = fcx.instantiate_type_scheme(span, free_substs, &rcvr_ty);
let rcvr_ty = fcx.tcx.liberate_late_bound_regions(free_id_outlive,
&ty::Binder(rcvr_ty));
debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty);
- fcx.demand_eqtype(span, rcvr_ty, sig.inputs[0]);
+ let origin = TypeOrigin::MethodReceiver(span);
+ fcx.demand_eqtype_with_origin(origin, rcvr_ty, sig.inputs[0]);
}
fn check_variances_for_type_defn(&self,
fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
debug!("visit_trait_item: {:?}", trait_item);
- self.check_trait_or_impl_item(trait_item.id, trait_item.span);
+ let method_sig = match trait_item.node {
+ hir::TraitItem_::MethodTraitItem(ref sig, _) => Some(sig),
+ _ => None
+ };
+ self.check_trait_or_impl_item(trait_item.id, trait_item.span, method_sig);
intravisit::walk_trait_item(self, trait_item)
}
fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) {
debug!("visit_impl_item: {:?}", impl_item);
- self.check_trait_or_impl_item(impl_item.id, impl_item.span);
+ let method_sig = match impl_item.node {
+ hir::ImplItemKind::Method(ref sig, _) => Some(sig),
+ _ => None
+ };
+ self.check_trait_or_impl_item(impl_item.id, impl_item.span, method_sig);
intravisit::walk_impl_item(self, impl_item)
}
}
const A_I8_T
: [u32; (i8::MAX as i8 + 1u8) as usize]
//~^ ERROR constant evaluation error [E0080]
- //~| mismatched types
- //~| expected `i8`
- //~| found `u8`
+ //~| expected i8, found u8
= [0; (i8::MAX as usize) + 1];
Ok2,
OhNo = 0_u8,
//~^ ERROR E0080
- //~| mismatched types
+ //~| expected i8, found u8
}
let x = A::Ok;
Ok2,
OhNo = 0_i8,
//~^ ERROR E0080
- //~| mismatched types
+ //~| expected u8, found i8
}
let x = A::Ok;
Ok2,
OhNo = 0_u16,
//~^ ERROR E0080
- //~| mismatched types
+ //~| expected i16, found u16
}
let x = A::Ok;
Ok2,
OhNo = 0_i16,
//~^ ERROR E0080
- //~| mismatched types
+ //~| expected u16, found i16
}
let x = A::Ok;
Ok2,
OhNo = 0_u32,
//~^ ERROR E0080
- //~| mismatched types
+ //~| expected i32, found u32
}
let x = A::Ok;
Ok2,
OhNo = 0_i32,
//~^ ERROR E0080
- //~| mismatched types
+ //~| expected u32, found i32
}
let x = A::Ok;
Ok2,
OhNo = 0_u64,
//~^ ERROR E0080
- //~| mismatched types
+ //~| expected i64, found u64
}
let x = A::Ok;
Ok2,
OhNo = 0_i64,
//~^ ERROR E0080
- //~| mismatched types
+ //~| expected u64, found i64
}
let x = A::Ok;
}
impl<'a,'b> Foo<'a,'b> {
- fn bar(self: Foo<'b,'a>) {}
- //~^ ERROR mismatched types
+ fn bar(
+ self
+ //~^ ERROR mismatched method receiver
//~| expected type `Foo<'a, 'b>`
//~| found type `Foo<'b, 'a>`
//~| lifetime mismatch
- //~| ERROR mismatched types
+ //~| ERROR mismatched method receiver
//~| expected type `Foo<'a, 'b>`
//~| found type `Foo<'b, 'a>`
//~| lifetime mismatch
+ : Foo<'b,'a>) {}
}
fn main() {}
impl <'a> Foo<'a>{
fn bar(self: &mut Foo) {
- //~^ mismatched types
+ //~^ mismatched method receiver
//~| expected type `&mut Foo<'a>`
//~| found type `&mut Foo<'_>`
//~| lifetime mismatch
- //~| mismatched types
+ //~| mismatched method receiver
//~| expected type `&mut Foo<'a>`
//~| found type `&mut Foo<'_>`
//~| lifetime mismatch
impl S {
fn f(self: *mut S) -> String { self.0 }
- //~^ ERROR mismatched types
+ //~^ ERROR mismatched method receiver
}
fn main() { S("".to_owned()).f(); }
enum Foo {
A = 1i64,
//~^ ERROR constant evaluation error
- //~| expected `isize`
- //~| found `i64`
+ //~| expected isize, found i64
B = 2u8
//~^ ERROR constant evaluation error
- //~| expected `isize`
- //~| found `u8`
+ //~| expected isize, found u8
}
fn main() {}
//~| ERROR expected usize for repeat count, found string literal [E0306]
let f = [0; -4_isize];
//~^ ERROR constant evaluation error
- //~| expected `usize`
- //~| found `isize`
+ //~| expected usize, found isize
//~| ERROR mismatched types
//~| expected usize, found isize
let f = [0_usize; -1_isize];
//~^ ERROR constant evaluation error
- //~| expected `usize`
- //~| found `isize`
+ //~| expected usize, found isize
//~| ERROR mismatched types
//~| expected usize, found isize
struct G {
}
impl Foo {
- fn foo(self: isize, x: isize) -> isize { //~ ERROR mismatched types
+ fn foo(self: isize, x: isize) -> isize { //~ ERROR mismatched method receiver
self.f + x
}
}
}
impl<T> Bar<T> {
- fn foo(self: Bar<isize>, x: isize) -> isize { //~ ERROR mismatched types
+ fn foo(self: Bar<isize>, x: isize) -> isize { //~ ERROR mismatched method receiver
x
}
- fn bar(self: &Bar<usize>, x: isize) -> isize { //~ ERROR mismatched types
+ fn bar(self: &Bar<usize>, x: isize) -> isize { //~ ERROR mismatched method receiver
x
}
}
impl<'a, T> SomeTrait for &'a Bar<T> {
fn dummy1(self: &&'a Bar<T>) { }
- fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched types
- //~^ ERROR mismatched types
+ fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched method receiver
+ //~^ ERROR mismatched method receiver
fn dummy3(self: &&Bar<T>) {}
- //~^ ERROR mismatched types
+ //~^ ERROR mismatched method receiver
//~| expected type `&&'a Bar<T>`
//~| found type `&&Bar<T>`
//~| lifetime mismatch
- //~| ERROR mismatched types
+ //~| ERROR mismatched method receiver
//~| expected type `&&'a Bar<T>`
//~| found type `&&Bar<T>`
//~| lifetime mismatch