remove rustc_typeck::same_type_err
This commit is contained in:
parent
b2422ab806
commit
8eb12d91aa
12 changed files with 114 additions and 55 deletions
|
@ -554,6 +554,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
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);
|
||||
|
@ -1643,6 +1644,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
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) {
|
||||
|
|
|
@ -32,7 +32,7 @@ use ty::adjustment;
|
|||
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};
|
||||
|
@ -219,6 +219,15 @@ pub enum TypeOrigin {
|
|||
|
||||
// `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 {
|
||||
|
@ -238,6 +247,9 @@ 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",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1791,6 +1803,9 @@ impl TypeOrigin {
|
|||
TypeOrigin::IfExpressionWithNoElse(span) => span,
|
||||
TypeOrigin::RangeExpression(span) => span,
|
||||
TypeOrigin::EquatePredicate(span) => span,
|
||||
TypeOrigin::MainFunctionType(span) => span,
|
||||
TypeOrigin::StartFunctionType(span) => span,
|
||||
TypeOrigin::IntrinsicType(span) => span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1841,3 +1856,50 @@ impl RegionVariableOrigin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1018,3 +1018,16 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeScheme<'tcx> {
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,15 +103,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
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);
|
||||
|
@ -120,6 +111,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
// 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);
|
||||
|
|
|
@ -54,16 +54,4 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
//! 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};
|
||||
|
@ -56,10 +57,9 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -437,8 +437,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||
|
||||
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,
|
||||
|
|
|
@ -2660,6 +2660,7 @@ For information on the design of the orphan rules, see [RFC 1023].
|
|||
[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:
|
||||
|
@ -2739,6 +2740,7 @@ impl Foo {
|
|||
}
|
||||
```
|
||||
"##,
|
||||
*/
|
||||
|
||||
E0214: r##"
|
||||
A generic type was described using parentheses rather than angle brackets. For
|
||||
|
|
|
@ -186,28 +186,14 @@ fn require_c_abi_if_variadic(tcx: TyCtxt,
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -249,8 +235,11 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
|
|||
})
|
||||
}));
|
||||
|
||||
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,
|
||||
|
@ -298,8 +287,11 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
|
|||
}),
|
||||
}));
|
||||
|
||||
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,
|
||||
|
|
|
@ -12,7 +12,7 @@ struct S(String);
|
|||
|
||||
impl S {
|
||||
fn f(self: *mut S) -> String { self.0 }
|
||||
//~^ ERROR mismatched method receiver
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() { S("".to_owned()).f(); }
|
||||
|
|
|
@ -27,6 +27,7 @@ fn main() {
|
|||
'c' ... 100 => { }
|
||||
_ => { }
|
||||
};
|
||||
//~^^^ ERROR mismatched types in range
|
||||
//~| expected char, found integral variable
|
||||
//~^^^ ERROR mismatched types
|
||||
//~| expected type `_`
|
||||
//~| found type `char`
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ struct Foo {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,10 @@ struct Bar<T> {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue