From 8eb12d91aaf95432ca73bda429af04e0710c984d Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Sat, 16 Jul 2016 19:38:17 +0300 Subject: [PATCH] remove rustc_typeck::same_type_err --- src/librustc/infer/error_reporting.rs | 10 +++ src/librustc/infer/mod.rs | 64 ++++++++++++++++++- src/librustc/ty/structural_impls.rs | 13 ++++ src/librustc_typeck/check/_match.rs | 10 +-- src/librustc_typeck/check/demand.rs | 12 ---- src/librustc_typeck/check/intrinsic.rs | 6 +- src/librustc_typeck/check/wfcheck.rs | 3 +- src/librustc_typeck/diagnostics.rs | 2 + src/librustc_typeck/lib.rs | 36 ++++------- src/test/compile-fail/issue-26194.rs | 2 +- src/test/compile-fail/match-range-fail.rs | 5 +- .../compile-fail/ufcs-explicit-self-bad.rs | 6 +- 12 files changed, 114 insertions(+), 55 deletions(-) diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 96ecad629f543..a0fa188c4f809 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -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) { diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index fc5625036ae40..dc262e61dd018 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -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>(&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>(&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>(&self, visitor: &mut V) -> bool { + self.origin.visit_with(visitor) || self.values.visit_with(visitor) + } +} diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 1e2920ca87ea6..16a54c20925de 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -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 { + 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>(&self, visitor: &mut V) -> bool { + self.expected.visit_with(visitor) || self.found.visit_with(visitor) + } +} diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index e90b32cd5dfc0..aae6e3ad36dfe 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -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); diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index eeebd6a7f626b..c1f415b3c028a 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -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 - } - } } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 5a3268e9e447b..8a53c59b4c7fa 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -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); } } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index d101381e2565c..2d44a85f9af4b 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -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, diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 8769bc1a32b50..683328f4eb4a0 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -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 diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 84452589dfda3..3b2d02dc861c4 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -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, diff --git a/src/test/compile-fail/issue-26194.rs b/src/test/compile-fail/issue-26194.rs index ef91188c5d166..1bc0a4f965219 100644 --- a/src/test/compile-fail/issue-26194.rs +++ b/src/test/compile-fail/issue-26194.rs @@ -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(); } diff --git a/src/test/compile-fail/match-range-fail.rs b/src/test/compile-fail/match-range-fail.rs index 526aa83dec7fd..2c4c256302186 100644 --- a/src/test/compile-fail/match-range-fail.rs +++ b/src/test/compile-fail/match-range-fail.rs @@ -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` } diff --git a/src/test/compile-fail/ufcs-explicit-self-bad.rs b/src/test/compile-fail/ufcs-explicit-self-bad.rs index f14a3505cdeb4..e997cf47c7333 100644 --- a/src/test/compile-fail/ufcs-explicit-self-bad.rs +++ b/src/test/compile-fail/ufcs-explicit-self-bad.rs @@ -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 { } impl Bar { - fn foo(self: Bar, x: isize) -> isize { //~ ERROR mismatched method receiver + fn foo(self: Bar, x: isize) -> isize { //~ ERROR mismatched types x } - fn bar(self: &Bar, x: isize) -> isize { //~ ERROR mismatched method receiver + fn bar(self: &Bar, x: isize) -> isize { //~ ERROR mismatched types x } }