Always drop var IDs from type variables modulo -Z verbose, per PR discussion
This commit is contained in:
parent
1b79303f49
commit
3db13f4892
@ -62,7 +62,6 @@ time of error detection.
|
||||
use std::collections::HashSet;
|
||||
use middle::def;
|
||||
use middle::subst;
|
||||
use middle::ty_fold::{mod, TypeFoldable};
|
||||
use middle::ty;
|
||||
use middle::ty::{Region, ReFree};
|
||||
use middle::typeck::infer;
|
||||
@ -112,7 +111,7 @@ pub trait ErrorReporting {
|
||||
|
||||
fn values_str(&self, values: &ValuePairs) -> Option<String>;
|
||||
|
||||
fn expected_found_str<T: UserString + Resolvable + HasRemainingTypeVariables>(
|
||||
fn expected_found_str<T: UserString + Resolvable>(
|
||||
&self,
|
||||
exp_found: &ty::expected_found<T>)
|
||||
-> Option<String>;
|
||||
@ -402,7 +401,7 @@ impl<'a, 'tcx> ErrorReporting for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn expected_found_str<T: UserString + Resolvable + HasRemainingTypeVariables>(
|
||||
fn expected_found_str<T: UserString + Resolvable>(
|
||||
&self,
|
||||
exp_found: &ty::expected_found<T>)
|
||||
-> Option<String>
|
||||
@ -417,14 +416,9 @@ impl<'a, 'tcx> ErrorReporting for InferCtxt<'a, 'tcx> {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Only include variable IDs in the diagnostics if there are at least two
|
||||
// present across both types/traits.
|
||||
let should_print_var_ids = expected.remaining_type_variables(self.tcx)
|
||||
.union(&found.remaining_type_variables(self.tcx)).count() > 1;
|
||||
|
||||
Some(format!("expected `{}`, found `{}`",
|
||||
expected.user_string_with_var_ids(self.tcx, should_print_var_ids),
|
||||
found.user_string_with_var_ids(self.tcx, should_print_var_ids)))
|
||||
expected.user_string(self.tcx),
|
||||
found.user_string(self.tcx)))
|
||||
}
|
||||
|
||||
fn report_param_bound_failure(&self,
|
||||
@ -1658,29 +1652,6 @@ pub trait Resolvable {
|
||||
fn contains_error(&self) -> bool;
|
||||
}
|
||||
|
||||
pub trait HasRemainingTypeVariables {
|
||||
fn remaining_type_variables(&self, tcx: &ty::ctxt) -> HashSet<ty::InferTy>;
|
||||
}
|
||||
|
||||
impl<T: TypeFoldable> HasRemainingTypeVariables for T {
|
||||
fn remaining_type_variables(&self, tcx: &ty::ctxt) -> HashSet<ty::InferTy> {
|
||||
let mut vars = HashSet::new();
|
||||
{
|
||||
let mut folder = ty_fold::BottomUpFolder {
|
||||
tcx: tcx,
|
||||
fldop: |t| {
|
||||
if let ty::ty_infer(var) = ty::get(t).sty {
|
||||
vars.insert(var);
|
||||
}
|
||||
t
|
||||
}
|
||||
};
|
||||
self.fold_with(&mut folder);
|
||||
}
|
||||
vars
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolvable for ty::t {
|
||||
fn resolve(&self, infcx: &InferCtxt) -> ty::t {
|
||||
infcx.resolve_type_vars_if_possible(*self)
|
||||
|
@ -43,9 +43,6 @@ pub trait Repr {
|
||||
/// Produces a string suitable for showing to the user.
|
||||
pub trait UserString {
|
||||
fn user_string(&self, tcx: &ctxt) -> String;
|
||||
fn user_string_with_var_ids(&self, tcx: &ctxt, _: bool) -> String {
|
||||
self.user_string(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn note_and_explain_region(cx: &ctxt,
|
||||
@ -231,14 +228,10 @@ pub fn mutability_to_string(m: ast::Mutability) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mt_to_string_with_var_ids(cx: &ctxt, m: &mt, print_var_ids: bool) -> String {
|
||||
pub fn mt_to_string(cx: &ctxt, m: &mt) -> String {
|
||||
format!("{}{}",
|
||||
mutability_to_string(m.mutbl),
|
||||
ty_to_string_with_var_ids(cx, m.ty, print_var_ids))
|
||||
}
|
||||
|
||||
pub fn mt_to_string(cx: &ctxt, m: &mt) -> String {
|
||||
mt_to_string_with_var_ids(cx, m, false)
|
||||
ty_to_string(cx, m.ty))
|
||||
}
|
||||
|
||||
pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String {
|
||||
@ -265,17 +258,11 @@ pub fn trait_ref_to_string(cx: &ctxt, trait_ref: &ty::TraitRef) -> String {
|
||||
}
|
||||
|
||||
pub fn ty_to_string(cx: &ctxt, typ: t) -> String {
|
||||
ty_to_string_with_var_ids(cx, typ, true)
|
||||
}
|
||||
|
||||
pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) -> String {
|
||||
print_var_ids = print_var_ids || cx.sess.verbose();
|
||||
fn bare_fn_to_string(cx: &ctxt,
|
||||
fn_style: ast::FnStyle,
|
||||
abi: abi::Abi,
|
||||
ident: Option<ast::Ident>,
|
||||
sig: &ty::FnSig,
|
||||
print_var_ids: bool)
|
||||
sig: &ty::FnSig)
|
||||
-> String {
|
||||
let mut s = String::new();
|
||||
match fn_style {
|
||||
@ -300,12 +287,12 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
_ => { }
|
||||
}
|
||||
|
||||
push_sig_to_string(cx, &mut s, '(', ')', sig, "", print_var_ids);
|
||||
push_sig_to_string(cx, &mut s, '(', ')', sig, "");
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
fn closure_to_string(cx: &ctxt, cty: &ty::ClosureTy, print_var_ids: bool) -> String {
|
||||
fn closure_to_string(cx: &ctxt, cty: &ty::ClosureTy) -> String {
|
||||
let mut s = String::new();
|
||||
|
||||
match cty.store {
|
||||
@ -330,7 +317,7 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
assert_eq!(cty.onceness, ast::Once);
|
||||
s.push_str("proc");
|
||||
push_sig_to_string(cx, &mut s, '(', ')', &cty.sig,
|
||||
bounds_str.as_slice(), print_var_ids);
|
||||
bounds_str.as_slice());
|
||||
}
|
||||
ty::RegionTraitStore(..) => {
|
||||
match cty.onceness {
|
||||
@ -338,7 +325,7 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
ast::Once => s.push_str("once ")
|
||||
}
|
||||
push_sig_to_string(cx, &mut s, '|', '|', &cty.sig,
|
||||
bounds_str.as_slice(), print_var_ids);
|
||||
bounds_str.as_slice());
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,12 +337,11 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
bra: char,
|
||||
ket: char,
|
||||
sig: &ty::FnSig,
|
||||
bounds: &str,
|
||||
print_var_ids: bool) {
|
||||
bounds: &str) {
|
||||
s.push(bra);
|
||||
let strs = sig.inputs
|
||||
.iter()
|
||||
.map(|a| ty_to_string_with_var_ids(cx, *a, print_var_ids))
|
||||
.map(|a| ty_to_string(cx, *a))
|
||||
.collect::<Vec<_>>();
|
||||
s.push_str(strs.connect(", ").as_slice());
|
||||
if sig.variadic {
|
||||
@ -372,7 +358,7 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
ty::FnConverging(t) => {
|
||||
if !ty::type_is_nil(t) {
|
||||
s.push_str(" -> ");
|
||||
s.push_str(ty_to_string_with_var_ids(cx, t, print_var_ids).as_slice());
|
||||
s.push_str(ty_to_string(cx, t).as_slice());
|
||||
}
|
||||
}
|
||||
ty::FnDiverging => {
|
||||
@ -381,21 +367,20 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_ty_to_string(ty: ty::InferTy, print_var_ids: bool) -> String {
|
||||
fn infer_ty_to_string(cx: &ctxt, ty: ty::InferTy) -> String {
|
||||
let print_var_ids = cx.sess.verbose();
|
||||
match ty {
|
||||
ty::TyVar(ty::TyVid { index: vid }) |
|
||||
ty::IntVar(ty::IntVid { index: vid }) |
|
||||
ty::FloatVar(ty::FloatVid { index: vid }) => {
|
||||
match ty {
|
||||
ty::TyVar(_) if print_var_ids => format!("_#{}", vid),
|
||||
ty::TyVar(_) => "_".to_string(),
|
||||
ty::IntVar(_) => format!("_#{}i", vid),
|
||||
ty::FloatVar(_) => format!("_#{}f", vid),
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
ty::TyVar(ty::TyVid { index: vid }) if print_var_ids =>
|
||||
format!("_#{}", vid),
|
||||
ty::IntVar(ty::IntVid { index: vid }) if print_var_ids =>
|
||||
format!("_#{}i", vid),
|
||||
ty::FloatVar(ty::FloatVid { index: vid }) if print_var_ids =>
|
||||
format!("_#{}f", vid),
|
||||
ty::TyVar(_) => "_".to_string(),
|
||||
ty::IntVar(_) => "_#i".to_string(),
|
||||
ty::FloatVar(_) => "_#f".to_string(),
|
||||
ty::SkolemizedTy(v) => format!("SkolemizedTy({})", v),
|
||||
ty::SkolemizedIntTy(v) => format!("SkolemizedIntTy({})", v),
|
||||
ty::SkolemizedIntTy(v) => format!("SkolemizedIntTy({})", v)
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,7 +392,7 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
ty_int(t) => ast_util::int_ty_to_string(t, None).to_string(),
|
||||
ty_uint(t) => ast_util::uint_ty_to_string(t, None).to_string(),
|
||||
ty_float(t) => ast_util::float_ty_to_string(t).to_string(),
|
||||
ty_uniq(typ) => format!("Box<{}>", ty_to_string_with_var_ids(cx, typ, print_var_ids)),
|
||||
ty_uniq(typ) => format!("Box<{}>", ty_to_string(cx, typ)),
|
||||
ty_ptr(ref tm) => {
|
||||
format!("*{} {}", match tm.mutbl {
|
||||
ast::MutMutable => "mut",
|
||||
@ -416,15 +401,15 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
}
|
||||
ty_rptr(r, ref tm) => {
|
||||
let mut buf = region_ptr_to_string(cx, r);
|
||||
buf.push_str(mt_to_string_with_var_ids(cx, tm, print_var_ids).as_slice());
|
||||
buf.push_str(mt_to_string(cx, tm).as_slice());
|
||||
buf
|
||||
}
|
||||
ty_open(typ) =>
|
||||
format!("opened<{}>", ty_to_string_with_var_ids(cx, typ, print_var_ids)),
|
||||
format!("opened<{}>", ty_to_string(cx, typ)),
|
||||
ty_tup(ref elems) => {
|
||||
let strs = elems
|
||||
.iter()
|
||||
.map(|elem| ty_to_string_with_var_ids(cx, *elem, print_var_ids))
|
||||
.map(|elem| ty_to_string(cx, *elem))
|
||||
.collect::<Vec<_>>();
|
||||
match strs.as_slice() {
|
||||
[ref string] => format!("({},)", string),
|
||||
@ -432,18 +417,18 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
}
|
||||
}
|
||||
ty_closure(ref f) => {
|
||||
closure_to_string(cx, &**f, print_var_ids)
|
||||
closure_to_string(cx, &**f)
|
||||
}
|
||||
ty_bare_fn(ref f) => {
|
||||
bare_fn_to_string(cx, f.fn_style, f.abi, None, &f.sig, print_var_ids)
|
||||
bare_fn_to_string(cx, f.fn_style, f.abi, None, &f.sig)
|
||||
}
|
||||
ty_infer(infer_ty) => infer_ty_to_string(infer_ty, print_var_ids),
|
||||
ty_infer(infer_ty) => infer_ty_to_string(cx, infer_ty),
|
||||
ty_err => "[type error]".to_string(),
|
||||
ty_param(ref param_ty) => param_ty.repr(cx),
|
||||
ty_enum(did, ref substs) | ty_struct(did, ref substs) => {
|
||||
let base = ty::item_path_str(cx, did);
|
||||
let generics = ty::lookup_item_type(cx, did).generics;
|
||||
parameterized(cx, base.as_slice(), substs, &generics, print_var_ids)
|
||||
parameterized(cx, base.as_slice(), substs, &generics)
|
||||
}
|
||||
ty_trait(box ty::TyTrait {
|
||||
def_id: did, ref substs, ref bounds
|
||||
@ -451,7 +436,7 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
let base = ty::item_path_str(cx, did);
|
||||
let trait_def = ty::lookup_trait_def(cx, did);
|
||||
let ty = parameterized(cx, base.as_slice(),
|
||||
substs, &trait_def.generics, print_var_ids);
|
||||
substs, &trait_def.generics);
|
||||
let bound_str = bounds.user_string(cx);
|
||||
let bound_sep = if bound_str.is_empty() { "" } else { "+" };
|
||||
format!("{}{}{}",
|
||||
@ -463,11 +448,11 @@ pub fn ty_to_string_with_var_ids(cx: &ctxt, typ: t, mut print_var_ids: bool) ->
|
||||
ty_unboxed_closure(ref did, _, ref substs) => {
|
||||
let unboxed_closures = cx.unboxed_closures.borrow();
|
||||
unboxed_closures.find(did).map(|cl| {
|
||||
closure_to_string(cx, &cl.closure_type.subst(cx, substs), print_var_ids)
|
||||
closure_to_string(cx, &cl.closure_type.subst(cx, substs))
|
||||
}).unwrap_or_else(|| "closure".to_string())
|
||||
}
|
||||
ty_vec(t, sz) => {
|
||||
let inner_str = ty_to_string_with_var_ids(cx, t, print_var_ids);
|
||||
let inner_str = ty_to_string(cx, t);
|
||||
match sz {
|
||||
Some(n) => format!("[{}, ..{}]", inner_str, n),
|
||||
None => format!("[{}]", inner_str),
|
||||
@ -492,8 +477,7 @@ pub fn explicit_self_category_to_str(category: &ty::ExplicitSelfCategory)
|
||||
pub fn parameterized(cx: &ctxt,
|
||||
base: &str,
|
||||
substs: &subst::Substs,
|
||||
generics: &ty::Generics,
|
||||
print_var_ids: bool)
|
||||
generics: &ty::Generics)
|
||||
-> String
|
||||
{
|
||||
let mut strs = Vec::new();
|
||||
@ -532,7 +516,7 @@ pub fn parameterized(cx: &ctxt,
|
||||
};
|
||||
|
||||
for t in tps[..tps.len() - num_defaults].iter() {
|
||||
strs.push(ty_to_string_with_var_ids(cx, *t, print_var_ids))
|
||||
strs.push(ty_to_string(cx, *t))
|
||||
}
|
||||
|
||||
if cx.sess.verbose() {
|
||||
@ -743,7 +727,7 @@ impl Repr for ty::TraitRef {
|
||||
let trait_def = ty::lookup_trait_def(tcx, self.def_id);
|
||||
format!("<{} as {}>",
|
||||
self.substs.self_ty().repr(tcx),
|
||||
parameterized(tcx, base.as_slice(), &self.substs, &trait_def.generics, false))
|
||||
parameterized(tcx, base.as_slice(), &self.substs, &trait_def.generics))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1128,12 +1112,9 @@ impl UserString for ty::BuiltinBounds {
|
||||
|
||||
impl UserString for ty::TraitRef {
|
||||
fn user_string(&self, tcx: &ctxt) -> String {
|
||||
self.user_string_with_var_ids(tcx, false)
|
||||
}
|
||||
fn user_string_with_var_ids(&self, tcx: &ctxt, print_var_ids: bool) -> String {
|
||||
let base = ty::item_path_str(tcx, self.def_id);
|
||||
let trait_def = ty::lookup_trait_def(tcx, self.def_id);
|
||||
parameterized(tcx, base.as_slice(), &self.substs, &trait_def.generics, print_var_ids)
|
||||
parameterized(tcx, base.as_slice(), &self.substs, &trait_def.generics)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1141,9 +1122,6 @@ impl UserString for ty::t {
|
||||
fn user_string(&self, tcx: &ctxt) -> String {
|
||||
ty_to_string(tcx, *self)
|
||||
}
|
||||
fn user_string_with_var_ids(&self, tcx: &ctxt, print_var_ids: bool) -> String {
|
||||
ty_to_string_with_var_ids(tcx, *self, print_var_ids)
|
||||
}
|
||||
}
|
||||
|
||||
impl UserString for ast::Ident {
|
||||
|
21
src/test/compile-fail/issue-13482-2.rs
Normal file
21
src/test/compile-fail/issue-13482-2.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// compile-flags:-Z verbose
|
||||
|
||||
fn main() {
|
||||
let x = [1,2];
|
||||
let y = match x {
|
||||
[] => None,
|
||||
//~^ ERROR types: expected `[_#0i, ..2]`, found `[_#7, ..0]`
|
||||
// (expected array of 2 elements, found array of 0 elements)
|
||||
[a,_] => Some(a)
|
||||
};
|
||||
}
|
@ -12,7 +12,7 @@ fn main() {
|
||||
let x = [1,2];
|
||||
let y = match x {
|
||||
[] => None,
|
||||
//~^ ERROR types: expected `[_#0i, ..2]`, found `[_#7, ..0]`
|
||||
//~^ ERROR types: expected `[_#i, ..2]`, found `[_, ..0]`
|
||||
// (expected array of 2 elements, found array of 0 elements)
|
||||
[a,_] => Some(a)
|
||||
};
|
||||
|
@ -11,7 +11,7 @@
|
||||
fn main() {
|
||||
match None {
|
||||
Err(_) => ()
|
||||
//~^ ERROR mismatched types: expected `core::option::Option<_#1>`
|
||||
// , found `core::result::Result<_#2, _#3>`
|
||||
//~^ ERROR mismatched types: expected `core::option::Option<_>`
|
||||
// , found `core::result::Result<_, _>`
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ fn main() {
|
||||
let a = if true {
|
||||
0
|
||||
} else if false {
|
||||
//~^ ERROR if may be missing an else clause: expected `()`, found `_#1i`
|
||||
//~^ ERROR if may be missing an else clause: expected `()`, found `_#i`
|
||||
1
|
||||
};
|
||||
}
|
||||
|
@ -13,6 +13,6 @@
|
||||
const A: (int,int) = (4,2);
|
||||
fn main() {
|
||||
match 42 { A => () }
|
||||
//~^ ERROR mismatched types: expected `_#0i`, found `(int, int)`
|
||||
//~^ ERROR mismatched types: expected `_#i`, found `(int, int)`
|
||||
// (expected integral variable, found tuple)
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ fn main() {
|
||||
|
||||
match (true, false) {
|
||||
(true, false, false) => ()
|
||||
//~^ ERROR mismatched types: expected `(bool, bool)`, found `(_#9, _#10, _#11)`
|
||||
//~^ ERROR mismatched types: expected `(bool, bool)`, found `(_, _, _)`
|
||||
}
|
||||
|
||||
match (true, false) {
|
||||
|
@ -18,7 +18,7 @@ fn main() {
|
||||
let c = [0, ..true]; //~ ERROR expected positive integer for repeat count, found boolean
|
||||
//~^ ERROR: expected `uint`, found `bool`
|
||||
let d = [0, ..0.5]; //~ ERROR expected positive integer for repeat count, found float
|
||||
//~^ ERROR: expected `uint`, found `_#0f`
|
||||
//~^ ERROR: expected `uint`, found `_#f`
|
||||
let e = [0, .."foo"]; //~ ERROR expected positive integer for repeat count, found string
|
||||
//~^ ERROR: expected `uint`, found `&'static str`
|
||||
let f = [0, ..-4];
|
||||
|
@ -13,7 +13,7 @@ struct Foo<T,U>(T);
|
||||
fn main() {
|
||||
match Foo(1.1) {
|
||||
1 => {}
|
||||
//~^ ERROR expected `Foo<_#0f, _#2>`, found `_#0i`
|
||||
//~^ ERROR expected `Foo<_#f, _>`, found `_#i`
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,6 @@
|
||||
|
||||
fn main() {
|
||||
let (x, y) = ();
|
||||
//~^ ERROR expected `()`, found `(_#3, _#4)` (expected (), found tuple)
|
||||
//~^ ERROR expected `()`, found `(_, _)` (expected (), found tuple)
|
||||
return x;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user