rustc: Suppress derived pattern-match-checking errors
typeck::check::_match wasn't suppressing derived errors properly. Fixed it.
This commit is contained in:
parent
9f03d45c56
commit
edc11a9f09
@ -175,11 +175,18 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path,
|
||||
kind_name = "structure";
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_fatal(
|
||||
pat.span,
|
||||
fmt!("mismatched types: expected `%s` but found enum or \
|
||||
structure",
|
||||
fcx.infcx().ty_to_str(expected)));
|
||||
let resolved_expected =
|
||||
fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
|
||||
fcx.infcx().type_error_message_str(pat.span,
|
||||
|actual| {
|
||||
fmt!("mismatched types: expected `%s` but found %s",
|
||||
resolved_expected, actual)},
|
||||
~"an enum or structure pattern",
|
||||
None);
|
||||
fcx.write_error(pat.id);
|
||||
kind_name = "[error]";
|
||||
arg_types = (copy subpats).get_or_default(~[]).map(|_|
|
||||
ty::mk_err());
|
||||
}
|
||||
}
|
||||
|
||||
@ -486,74 +493,44 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
|
||||
}
|
||||
ast::pat_tup(ref elts) => {
|
||||
let s = structure_of(fcx, pat.span, expected);
|
||||
let ex_elts = match s {
|
||||
ty::ty_tup(ref elts) => elts,
|
||||
_ => {
|
||||
tcx.sess.span_fatal
|
||||
(pat.span,
|
||||
fmt!("mismatched types: expected `%s`, found tuple",
|
||||
fcx.infcx().ty_to_str(expected)));
|
||||
}
|
||||
};
|
||||
let e_count = elts.len();
|
||||
if e_count != ex_elts.len() {
|
||||
tcx.sess.span_fatal
|
||||
(pat.span, fmt!("mismatched types: expected a tuple \
|
||||
with %u fields, found one with %u \
|
||||
fields", ex_elts.len(), e_count));
|
||||
match s {
|
||||
ty::ty_tup(ref ex_elts) if e_count == ex_elts.len() => {
|
||||
for elts.eachi |i, elt| {
|
||||
check_pat(pcx, *elt, ex_elts[i]);
|
||||
}
|
||||
fcx.write_ty(pat.id, expected);
|
||||
}
|
||||
_ => {
|
||||
for elts.each |elt| {
|
||||
check_pat(pcx, *elt, ty::mk_err());
|
||||
}
|
||||
let actual = ty::mk_tup(tcx, elts.map(|pat_var| {
|
||||
fcx.node_ty(pat_var.id)
|
||||
}));
|
||||
// use terr_tuple_size if both types are tuples
|
||||
let type_error = match s {
|
||||
ty::ty_tup(ref ex_elts) =>
|
||||
ty::terr_tuple_size(ty::expected_found{expected: ex_elts.len(),
|
||||
found: e_count}),
|
||||
_ => ty::terr_mismatch
|
||||
};
|
||||
fcx.infcx().report_mismatched_types(pat.span,
|
||||
expected,
|
||||
actual,
|
||||
&type_error);
|
||||
fcx.write_error(pat.id);
|
||||
}
|
||||
}
|
||||
let mut i = 0u;
|
||||
for elts.each |elt| {
|
||||
check_pat(pcx, *elt, ex_elts[i]);
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
fcx.write_ty(pat.id, expected);
|
||||
}
|
||||
ast::pat_box(inner) => {
|
||||
match structure_of(fcx, pat.span, expected) {
|
||||
ty::ty_box(e_inner) => {
|
||||
check_pat(pcx, inner, e_inner.ty);
|
||||
fcx.write_ty(pat.id, expected);
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_fatal(
|
||||
pat.span,
|
||||
~"mismatched types: expected `" +
|
||||
fcx.infcx().ty_to_str(expected) +
|
||||
~"` found box");
|
||||
}
|
||||
}
|
||||
check_pointer_pat(pcx, At, inner, pat.id, pat.span, expected);
|
||||
}
|
||||
ast::pat_uniq(inner) => {
|
||||
match structure_of(fcx, pat.span, expected) {
|
||||
ty::ty_uniq(e_inner) => {
|
||||
check_pat(pcx, inner, e_inner.ty);
|
||||
fcx.write_ty(pat.id, expected);
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_fatal(
|
||||
pat.span,
|
||||
~"mismatched types: expected `" +
|
||||
fcx.infcx().ty_to_str(expected) +
|
||||
~"` found uniq");
|
||||
}
|
||||
}
|
||||
check_pointer_pat(pcx, Uniq, inner, pat.id, pat.span, expected);
|
||||
}
|
||||
ast::pat_region(inner) => {
|
||||
match structure_of(fcx, pat.span, expected) {
|
||||
ty::ty_rptr(_, e_inner) => {
|
||||
check_pat(pcx, inner, e_inner.ty);
|
||||
fcx.write_ty(pat.id, expected);
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_fatal(
|
||||
pat.span,
|
||||
~"mismatched types: expected `" +
|
||||
fcx.infcx().ty_to_str(expected) +
|
||||
~"` found borrowed pointer");
|
||||
}
|
||||
}
|
||||
check_pointer_pat(pcx, Borrowed, inner, pat.id, pat.span, expected);
|
||||
}
|
||||
ast::pat_vec(ref before, slice, ref after) => {
|
||||
let default_region_var =
|
||||
@ -577,11 +554,25 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
|
||||
(mt, default_region_var)
|
||||
},
|
||||
_ => {
|
||||
tcx.sess.span_fatal(
|
||||
pat.span,
|
||||
fmt!("mismatched type: expected `%s` but found vector",
|
||||
fcx.infcx().ty_to_str(expected))
|
||||
);
|
||||
for before.each |&elt| {
|
||||
check_pat(pcx, elt, ty::mk_err());
|
||||
}
|
||||
for slice.each |&elt| {
|
||||
check_pat(pcx, elt, ty::mk_err());
|
||||
}
|
||||
for after.each |&elt| {
|
||||
check_pat(pcx, elt, ty::mk_err());
|
||||
}
|
||||
let resolved_expected =
|
||||
fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
|
||||
fcx.infcx().type_error_message_str(pat.span,
|
||||
|actual| {
|
||||
fmt!("mismatched types: expected `%s` but found %s",
|
||||
resolved_expected, actual)},
|
||||
~"a vector pattern",
|
||||
None);
|
||||
fcx.write_error(pat.id);
|
||||
return;
|
||||
}
|
||||
};
|
||||
for before.each |elt| {
|
||||
@ -605,3 +596,46 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check @, ~ and & patterns
|
||||
pub fn check_pointer_pat(pcx: &pat_ctxt,
|
||||
pointer_kind: PointerKind,
|
||||
inner: @ast::pat,
|
||||
pat_id: ast::node_id,
|
||||
span: span,
|
||||
expected: ty::t) {
|
||||
let fcx = pcx.fcx;
|
||||
let check_inner: &fn(ty::mt) = |e_inner| {
|
||||
check_pat(pcx, inner, e_inner.ty);
|
||||
fcx.write_ty(pat_id, expected);
|
||||
};
|
||||
match structure_of(fcx, span, expected) {
|
||||
ty::ty_box(e_inner) if pointer_kind == At => {
|
||||
check_inner(e_inner);
|
||||
}
|
||||
ty::ty_uniq(e_inner) if pointer_kind == Uniq => {
|
||||
check_inner(e_inner);
|
||||
}
|
||||
ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed => {
|
||||
check_inner(e_inner);
|
||||
}
|
||||
_ => {
|
||||
check_pat(pcx, inner, ty::mk_err());
|
||||
let resolved_expected =
|
||||
fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
|
||||
fcx.infcx().type_error_message_str(span, |actual| {
|
||||
fmt!("mismatched types: expected `%s` but found %s",
|
||||
resolved_expected, actual)},
|
||||
fmt!("an %s pattern", match pointer_kind {
|
||||
At => "@-box",
|
||||
Uniq => "~-box",
|
||||
Borrowed => "&-pointer"
|
||||
}),
|
||||
None);
|
||||
fcx.write_error(pat_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
enum PointerKind { At, Uniq, Borrowed }
|
||||
|
||||
|
@ -749,6 +749,19 @@ pub impl InferCtxt {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn type_error_message_str(@mut self, sp: span, mk_msg: &fn(~str) -> ~str,
|
||||
actual_ty: ~str, err: Option<&ty::type_err>) {
|
||||
let error_str = err.map_default(~"", |t_err|
|
||||
fmt!(" (%s)",
|
||||
ty::type_err_to_str(self.tcx, *t_err)));
|
||||
self.tcx.sess.span_err(sp,
|
||||
fmt!("%s%s", mk_msg(actual_ty), error_str));
|
||||
for err.each |err| {
|
||||
ty::note_and_explain_type_err(self.tcx, *err)
|
||||
}
|
||||
}
|
||||
|
||||
fn type_error_message(@mut self, sp: span, mk_msg: &fn(~str) -> ~str,
|
||||
actual_ty: ty::t, err: Option<&ty::type_err>) {
|
||||
let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
|
||||
@ -757,15 +770,9 @@ pub impl InferCtxt {
|
||||
if ty::type_is_error(actual_ty) {
|
||||
return;
|
||||
}
|
||||
let error_str = err.map_default(~"", |t_err|
|
||||
fmt!(" (%s)",
|
||||
ty::type_err_to_str(self.tcx, *t_err)));
|
||||
self.tcx.sess.span_err(sp,
|
||||
fmt!("%s%s", mk_msg(self.ty_to_str(actual_ty)),
|
||||
error_str));
|
||||
for err.each |err| {
|
||||
ty::note_and_explain_type_err(self.tcx, *err)
|
||||
}
|
||||
|
||||
self.type_error_message_str(sp, mk_msg, self.ty_to_str(actual_ty),
|
||||
err);
|
||||
}
|
||||
|
||||
fn report_mismatched_types(@mut self, sp: span, e: ty::t, a: ty::t,
|
||||
|
44
src/test/compile-fail/issue-5100.rs
Normal file
44
src/test/compile-fail/issue-5100.rs
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
enum A { B, C }
|
||||
|
||||
fn main() {
|
||||
match (true, false) {
|
||||
B => (), //~ ERROR expected `(bool,bool)` but found an enum or structure pattern
|
||||
_ => ()
|
||||
}
|
||||
|
||||
match (true, false) {
|
||||
(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)
|
||||
}
|
||||
|
||||
match (true, false) {
|
||||
@(true, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found an @-box pattern
|
||||
}
|
||||
|
||||
match (true, false) {
|
||||
~(true, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found a ~-box pattern
|
||||
}
|
||||
|
||||
match (true, false) {
|
||||
&(true, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found an &-pointer pattern
|
||||
}
|
||||
|
||||
|
||||
let v = [('a', 'b') //~ ERROR expected function but found `(char,char)`
|
||||
('c', 'd'),
|
||||
('e', 'f')];
|
||||
|
||||
for v.each |&(x,y)| {} // should be OK
|
||||
|
||||
// Make sure none of the errors above were fatal
|
||||
let x: char = true; //~ ERROR expected `char` but found `bool`
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user