Skip to content

Commit 638b394

Browse files
committed
auto merge of #6427 : catamorphism/rust/issue-6319, r=nikomatsakis
r? @nikomatsakis In #6319, several people mentioned they ran into a "computing fictitious type" ICE in trans. This turns out to be because some of my recent changes to typeck::check::_match resulted in type errors getting reported with ty_err as the expected type, which meant the errors were suppressed, and typechecking incorrectly succeeded (since the errors weren't recorded). Changed the error messages in these cases not to use an expected type at all, rather, printing out a string describing the type that was expected (which is what the code originally did). The result is a bit repetitive and the proliferation of error-reporting functions in typeck::infer is a bit annoying, but I thought it was important to fix this now; more cleanup can happen later.
2 parents 36771ef + cdb52c0 commit 638b394

File tree

4 files changed

+84
-49
lines changed

4 files changed

+84
-49
lines changed

src/librustc/middle/typeck/check/_match.rs

+36-38
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,12 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path,
146146
kind_name = "variant";
147147
}
148148
None => {
149-
let resolved_expected =
150-
fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
151-
fcx.infcx().type_error_message_str(pat.span,
152-
|actual| {
149+
fcx.infcx().type_error_message_str_with_expected(pat.span,
150+
|expected, actual| {
151+
expected.map_default(~"", |&e| {
153152
fmt!("mismatched types: expected `%s` but found %s",
154-
resolved_expected, actual)},
155-
~"a structure pattern",
153+
e, actual)})},
154+
Some(expected), ~"a structure pattern",
156155
None);
157156
fcx.write_error(pat.id);
158157
kind_name = "[error]";
@@ -189,13 +188,12 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path,
189188
kind_name = "structure";
190189
}
191190
_ => {
192-
let resolved_expected =
193-
fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
194-
fcx.infcx().type_error_message_str(pat.span,
195-
|actual| {
191+
fcx.infcx().type_error_message_str_with_expected(pat.span,
192+
|expected, actual| {
193+
expected.map_default(~"", |&e| {
196194
fmt!("mismatched types: expected `%s` but found %s",
197-
resolved_expected, actual)},
198-
~"an enum or structure pattern",
195+
e, actual)})},
196+
Some(expected), ~"an enum or structure pattern",
199197
None);
200198
fcx.write_error(pat.id);
201199
kind_name = "[error]";
@@ -508,20 +506,17 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
508506
for elts.each |elt| {
509507
check_pat(pcx, *elt, ty::mk_err());
510508
}
511-
let actual = ty::mk_tup(tcx, elts.map(|pat_var| {
512-
fcx.node_ty(pat_var.id)
513-
}));
514509
// use terr_tuple_size if both types are tuples
515510
let type_error = match s {
516511
ty::ty_tup(ref ex_elts) =>
517512
ty::terr_tuple_size(ty::expected_found{expected: ex_elts.len(),
518513
found: e_count}),
519514
_ => ty::terr_mismatch
520515
};
521-
fcx.infcx().report_mismatched_types(pat.span,
522-
expected,
523-
actual,
524-
&type_error);
516+
fcx.infcx().type_error_message_str_with_expected(pat.span, |expected, actual| {
517+
expected.map_default(~"", |&e| {
518+
fmt!("mismatched types: expected `%s` but found %s",
519+
e, actual)})}, Some(expected), ~"tuple", Some(&type_error));
525520
fcx.write_error(pat.id);
526521
}
527522
}
@@ -566,14 +561,15 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
566561
for after.each |&elt| {
567562
check_pat(pcx, elt, ty::mk_err());
568563
}
569-
let resolved_expected =
570-
fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
571-
fcx.infcx().type_error_message_str(pat.span,
572-
|actual| {
573-
fmt!("mismatched types: expected `%s` but found %s",
574-
resolved_expected, actual)},
575-
~"a vector pattern",
576-
None);
564+
fcx.infcx().type_error_message_str_with_expected(
565+
pat.span,
566+
|expected, actual| {
567+
expected.map_default(~"", |&e| {
568+
fmt!("mismatched types: expected `%s` but found %s",
569+
e, actual)})},
570+
Some(expected),
571+
~"a vector pattern",
572+
None);
577573
fcx.write_error(pat.id);
578574
return;
579575
}
@@ -623,17 +619,19 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
623619
}
624620
_ => {
625621
check_pat(pcx, inner, ty::mk_err());
626-
let resolved_expected =
627-
fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
628-
fcx.infcx().type_error_message_str(span, |actual| {
629-
fmt!("mismatched types: expected `%s` but found %s",
630-
resolved_expected, actual)},
631-
fmt!("%s pattern", match pointer_kind {
632-
Managed => "an @-box",
633-
Owned => "a ~-box",
634-
Borrowed => "an &-pointer"
635-
}),
636-
None);
622+
fcx.infcx().type_error_message_str_with_expected(
623+
span,
624+
|expected, actual| {
625+
expected.map_default(~"", |&e| {
626+
fmt!("mismatched types: expected `%s` but found %s",
627+
e, actual)})},
628+
Some(expected),
629+
fmt!("%s pattern", match pointer_kind {
630+
Managed => "an @-box",
631+
Owned => "a ~-box",
632+
Borrowed => "an &-pointer"
633+
}),
634+
None);
637635
fcx.write_error(pat_id);
638636
}
639637
}

src/librustc/middle/typeck/infer/mod.rs

+33-10
Original file line numberDiff line numberDiff line change
@@ -728,30 +728,53 @@ pub impl InferCtxt {
728728
}
729729
}
730730

731+
fn type_error_message_str(@mut self,
732+
sp: span,
733+
mk_msg: &fn(Option<~str>, ~str) -> ~str,
734+
actual_ty: ~str, err: Option<&ty::type_err>) {
735+
self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
736+
}
737+
738+
fn type_error_message_str_with_expected(@mut self,
739+
sp: span,
740+
mk_msg: &fn(Option<~str>, ~str) -> ~str,
741+
expected_ty: Option<ty::t>, actual_ty: ~str,
742+
err: Option<&ty::type_err>) {
743+
debug!("hi! expected_ty = %?, actual_ty = %s", expected_ty, actual_ty);
731744

732-
fn type_error_message_str(@mut self, sp: span, mk_msg: &fn(~str) -> ~str,
733-
actual_ty: ~str, err: Option<&ty::type_err>) {
734745
let error_str = err.map_default(~"", |t_err|
735746
fmt!(" (%s)",
736747
ty::type_err_to_str(self.tcx, *t_err)));
737-
self.tcx.sess.span_err(sp,
738-
fmt!("%s%s", mk_msg(actual_ty), error_str));
739-
for err.each |err| {
740-
ty::note_and_explain_type_err(self.tcx, *err)
748+
let resolved_expected = expected_ty.map(|&e_ty|
749+
{ self.resolve_type_vars_if_possible(e_ty) });
750+
if !resolved_expected.map_default(false, |&e| { ty::type_is_error(e) }) {
751+
match resolved_expected {
752+
None => self.tcx.sess.span_err(sp,
753+
fmt!("%s%s", mk_msg(None, actual_ty), error_str)),
754+
Some(e) => {
755+
self.tcx.sess.span_err(sp,
756+
fmt!("%s%s", mk_msg(Some(self.ty_to_str(e)), actual_ty), error_str));
757+
}
758+
}
759+
for err.each |err| {
760+
ty::note_and_explain_type_err(self.tcx, *err)
761+
}
741762
}
742763
}
743764

744-
fn type_error_message(@mut self, sp: span, mk_msg: &fn(~str) -> ~str,
745-
actual_ty: ty::t, err: Option<&ty::type_err>) {
765+
fn type_error_message(@mut self,
766+
sp: span,
767+
mk_msg: &fn(~str) -> ~str,
768+
actual_ty: ty::t,
769+
err: Option<&ty::type_err>) {
746770
let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
747771

748772
// Don't report an error if actual type is ty_err.
749773
if ty::type_is_error(actual_ty) {
750774
return;
751775
}
752776

753-
self.type_error_message_str(sp, mk_msg, self.ty_to_str(actual_ty),
754-
err);
777+
self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_str(actual_ty), err);
755778
}
756779

757780
fn report_mismatched_types(@mut self, sp: span, e: ty::t, a: ty::t,

src/test/compile-fail/issue-5100.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn main() {
1717
}
1818

1919
match (true, false) {
20-
(true, false, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found `(bool,bool,bool)` (expected a tuple with 2 elements but found one with 3 elements)
20+
(true, false, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found tuple (expected a tuple with 2 elements but found one with 3 elements)
2121
}
2222

2323
match (true, false) {
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let (x, y) = (); //~ ERROR expected `()` but found tuple (types differ)
13+
return x;
14+
}

0 commit comments

Comments
 (0)