Always drop var IDs from type variables modulo -Z verbose, per PR discussion

This commit is contained in:
Jakub Bukaj 2014-10-29 21:20:06 +01:00
parent 1b79303f49
commit 3db13f4892
11 changed files with 71 additions and 101 deletions

View file

@ -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)

View file

@ -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 {

View 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)
};
}

View file

@ -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)
};

View file

@ -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<_, _>`
}
}

View file

@ -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
};
}

View file

@ -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)
}

View file

@ -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) {

View file

@ -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];

View file

@ -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`
}
}

View file

@ -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;
}