Skip to content

Commit

Permalink
Always drop var IDs from type variables modulo -Z verbose, per PR dis…
Browse files Browse the repository at this point in the history
…cussion
  • Loading branch information
Jakub Bukaj committed Oct 29, 2014
1 parent 1b79303 commit 3db13f4
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 101 deletions.
37 changes: 4 additions & 33 deletions src/librustc/middle/typeck/infer/error_reporting.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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>;
Expand Down Expand Up @@ -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>
Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
96 changes: 37 additions & 59 deletions src/librustc/util/ppaux.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -330,15 +317,15 @@ 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 {
ast::Many => {}
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());
}
}

Expand All @@ -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 {
Expand All @@ -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 => {
Expand All @@ -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)
}
}

Expand All @@ -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",
Expand All @@ -416,42 +401,42 @@ 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),
strs => format!("({})", strs.connect(", "))
}
}
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
}) => {
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!("{}{}{}",
Expand All @@ -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),
Expand All @@ -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();
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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))
}
}

Expand Down Expand Up @@ -1128,22 +1112,16 @@ 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)
}
}

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 {
Expand Down
21 changes: 21 additions & 0 deletions src/test/compile-fail/issue-13482-2.rs
@@ -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)
};
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-13482.rs
Expand Up @@ -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)
};
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-3680.rs
Expand Up @@ -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<_, _>`
}
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-4201.rs
Expand Up @@ -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
};
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-4968.rs
Expand Up @@ -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)
}

0 comments on commit 3db13f4

Please sign in to comment.