Skip to content

Commit

Permalink
remove rustc_typeck::same_type_err
Browse files Browse the repository at this point in the history
  • Loading branch information
arielb1 committed Jul 22, 2016
1 parent b2422ab commit 8eb12d9
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 55 deletions.
10 changes: 10 additions & 0 deletions src/librustc/infer/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
64 changes: 63 additions & 1 deletion src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand All @@ -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",
}
}
}
Expand Down Expand Up @@ -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,
}
}
}
Expand Down Expand Up @@ -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)
}
}
13 changes: 13 additions & 0 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
10 changes: 1 addition & 9 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
12 changes: 0 additions & 12 deletions src/librustc_typeck/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
6 changes: 3 additions & 3 deletions src/librustc_typeck/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/librustc_typeck/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -2739,6 +2740,7 @@ impl Foo {
}
```
"##,
*/

E0214: r##"
A generic type was described using parentheses rather than angle brackets. For
Expand Down
36 changes: 14 additions & 22 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-26194.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(); }
5 changes: 3 additions & 2 deletions src/test/compile-fail/match-range-fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`
}
6 changes: 3 additions & 3 deletions src/test/compile-fail/ufcs-explicit-self-bad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand All @@ -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
}
}
Expand Down

0 comments on commit 8eb12d9

Please sign in to comment.