trace: TypeTrace<'tcx>,
terr: &TypeError<'tcx>)
-> DiagnosticBuilder<'tcx> {
+ let trace = self.resolve_type_vars_if_possible(&trace);
let span = trace.origin.span();
let mut err = self.report_type_error(trace, terr);
self.tcx.note_and_explain_type_err(&mut err, terr, span);
TypeOrigin::EquatePredicate(_) => {
"equality where clause is satisfied"
}
+ TypeOrigin::MainFunctionType(_) => {
+ "the `main` function has the correct type"
+ }
+ TypeOrigin::StartFunctionType(_) => {
+ "the `start` function has the correct type"
+ }
+ TypeOrigin::IntrinsicType(_) => {
+ "the intrinsic has the correct type"
+ }
};
match self.values_str(&trace.values) {
use ty::{TyVid, IntVid, FloatVid};
use ty::{self, Ty, TyCtxt};
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
-use ty::fold::TypeFoldable;
+use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::{self, PredicateObligations, ProjectionMode};
use rustc_data_structures::unify::{self, UnificationTable};
// `where a == b`
EquatePredicate(Span),
+
+ // `main` has wrong type
+ MainFunctionType(Span),
+
+ // `start` has wrong type
+ StartFunctionType(Span),
+
+ // intrinsic has wrong type
+ IntrinsicType(Span),
}
impl TypeOrigin {
&TypeOrigin::IfExpressionWithNoElse(_) => "if may be missing an else clause",
&TypeOrigin::RangeExpression(_) => "start and end of range have incompatible types",
&TypeOrigin::EquatePredicate(_) => "equality predicate not satisfied",
+ &TypeOrigin::MainFunctionType(_) => "main function has wrong type",
+ &TypeOrigin::StartFunctionType(_) => "start function has wrong type",
+ &TypeOrigin::IntrinsicType(_) => "intrinsic has wrong type",
}
}
}
TypeOrigin::IfExpressionWithNoElse(span) => span,
TypeOrigin::RangeExpression(span) => span,
TypeOrigin::EquatePredicate(span) => span,
+ TypeOrigin::MainFunctionType(span) => span,
+ TypeOrigin::StartFunctionType(span) => span,
+ TypeOrigin::IntrinsicType(span) => span,
}
}
}
}
}
}
+
+impl<'tcx> TypeFoldable<'tcx> for TypeOrigin {
+ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
+ self.clone()
+ }
+
+ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
+ false
+ }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
+ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+ match *self {
+ ValuePairs::Types(ref ef) => {
+ ValuePairs::Types(ef.fold_with(folder))
+ }
+ ValuePairs::TraitRefs(ref ef) => {
+ ValuePairs::TraitRefs(ef.fold_with(folder))
+ }
+ ValuePairs::PolyTraitRefs(ref ef) => {
+ ValuePairs::PolyTraitRefs(ef.fold_with(folder))
+ }
+ }
+ }
+
+ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+ match *self {
+ ValuePairs::Types(ref ef) => ef.visit_with(visitor),
+ ValuePairs::TraitRefs(ref ef) => ef.visit_with(visitor),
+ ValuePairs::PolyTraitRefs(ref ef) => ef.visit_with(visitor),
+ }
+ }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for TypeTrace<'tcx> {
+ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+ TypeTrace {
+ origin: self.origin.fold_with(folder),
+ values: self.values.fold_with(folder)
+ }
+ }
+
+ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+ self.origin.visit_with(visitor) || self.values.visit_with(visitor)
+ }
+}
self.generics.visit_with(visitor) || self.ty.visit_with(visitor)
}
}
+
+impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
+ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+ ty::error::ExpectedFound {
+ expected: self.expected.fold_with(folder),
+ found: self.found.fold_with(folder),
+ }
+ }
+
+ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+ self.expected.visit_with(visitor) || self.found.visit_with(visitor)
+ }
+}
return;
}
- // Check that the types of the end-points can be unified.
- let types_unify = self.require_same_types(pat.span, rhs_ty, lhs_ty,
- "mismatched types in range");
-
- // It's ok to return without a message as `require_same_types` prints an error.
- if !types_unify {
- return;
- }
-
// Now that we know the types can be unified we find the unified type and use
// it to type the entire expression.
let common_type = self.resolve_type_vars_if_possible(&lhs_ty);
// subtyping doesn't matter here, as the value is some kind of scalar
self.demand_eqtype(pat.span, expected, lhs_ty);
+ self.demand_eqtype(pat.span, expected, rhs_ty);
}
PatKind::Binding(bm, _, ref sub) => {
let typ = self.local_ty(pat.span, pat.id);
self.report_mismatched_types(origin, expected, expr_ty, e);
}
}
-
- pub fn require_same_types(&self, span: Span, t1: Ty<'tcx>, t2: Ty<'tcx>, msg: &str)
- -> bool {
- if let Err(err) = self.eq_types(false, TypeOrigin::Misc(span), t1, t2) {
- let found_ty = self.resolve_type_vars_if_possible(&t1);
- let expected_ty = self.resolve_type_vars_if_possible(&t2);
- ::emit_type_err(self.tcx, span, found_ty, expected_ty, &err, msg);
- false
- } else {
- true
- }
- }
}
//! intrinsics that the compiler exposes.
use intrinsics;
+use rustc::infer::TypeOrigin;
use rustc::ty::subst::{self, Substs};
use rustc::ty::FnSig;
use rustc::ty::{self, Ty};
i_n_tps, n_tps);
} else {
require_same_types(ccx,
- it.span,
+ TypeOrigin::IntrinsicType(it.span),
i_ty.ty,
- fty,
- "intrinsic has wrong type");
+ fty);
}
}
debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty);
- fcx.require_same_types(span, sig.inputs[0], rcvr_ty,
- "mismatched method receiver");
+ fcx.demand_eqtype(span, rcvr_ty, sig.inputs[0]);
}
fn check_variances_for_type_defn(&self,
[RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
"##,
+/*
E0211: r##"
You used a function or type which doesn't fit the requirements for where it was
used. Erroneous code examples:
}
```
"##,
+ */
E0214: r##"
A generic type was described using parentheses rather than angle brackets. For
}
}
-pub fn emit_type_err<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
- span: Span,
- found_ty: Ty<'tcx>,
- expected_ty: Ty<'tcx>,
- terr: &ty::error::TypeError<'tcx>,
- msg: &str) {
- let mut err = struct_span_err!(tcx.sess, span, E0211, "{}", msg);
- err.span_label(span, &terr);
- err.note_expected_found(&"type", &expected_ty, &found_ty);
- tcx.note_and_explain_type_err(&mut err, terr, span);
- err.emit();
-}
-
fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
- span: Span,
+ origin: TypeOrigin,
t1: Ty<'tcx>,
- t2: Ty<'tcx>,
- msg: &str)
+ t2: Ty<'tcx>)
-> bool {
ccx.tcx.infer_ctxt(None, None, ProjectionMode::AnyFinal).enter(|infcx| {
- if let Err(err) = infcx.eq_types(false, TypeOrigin::Misc(span), t1, t2) {
- emit_type_err(infcx.tcx, span, t1, t2, &err, msg);
+ if let Err(err) = infcx.eq_types(false, origin.clone(), t1, t2) {
+ infcx.report_mismatched_types(origin, t1, t2, err);
false
} else {
true
})
}));
- require_same_types(ccx, main_span, main_t, se_ty,
- "main function has wrong type");
+ require_same_types(
+ ccx,
+ TypeOrigin::MainFunctionType(main_span),
+ main_t,
+ se_ty);
}
_ => {
span_bug!(main_span,
}),
}));
- require_same_types(ccx, start_span, start_t, se_ty,
- "start function has wrong type");
+ require_same_types(
+ ccx,
+ TypeOrigin::StartFunctionType(start_span),
+ start_t,
+ se_ty);
}
_ => {
span_bug!(start_span,
impl S {
fn f(self: *mut S) -> String { self.0 }
- //~^ ERROR mismatched method receiver
+ //~^ ERROR mismatched types
}
fn main() { S("".to_owned()).f(); }
'c' ... 100 => { }
_ => { }
};
- //~^^^ ERROR mismatched types in range
- //~| expected char, found integral variable
+ //~^^^ ERROR mismatched types
+ //~| expected type `_`
+ //~| found type `char`
}
}
impl Foo {
- fn foo(self: isize, x: isize) -> isize { //~ ERROR mismatched method receiver
+ fn foo(self: isize, x: isize) -> isize { //~ ERROR mismatched types
self.f + x
}
}
}
impl<T> Bar<T> {
- fn foo(self: Bar<isize>, x: isize) -> isize { //~ ERROR mismatched method receiver
+ fn foo(self: Bar<isize>, x: isize) -> isize { //~ ERROR mismatched types
x
}
- fn bar(self: &Bar<usize>, x: isize) -> isize { //~ ERROR mismatched method receiver
+ fn bar(self: &Bar<usize>, x: isize) -> isize { //~ ERROR mismatched types
x
}
}