From 71b82c4573b7b94d4d70e66f788a2e452be82aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 16 Sep 2017 15:36:52 -0700 Subject: [PATCH 1/4] Fix docstring typo --- src/librustc/hir/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index dd2a3978d8844..9a90fa8617b4d 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -176,7 +176,7 @@ pub struct LifetimeDef { } /// A "Path" is essentially Rust's notion of a name; for instance: -/// std::cmp::PartialEq . It's represented as a sequence of identifiers, +/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers, /// along with a bunch of supporting information. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] pub struct Path { From 78ccfd6aa5e9d3f7973c390fb144e0a254fb02c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 16 Sep 2017 15:43:23 -0700 Subject: [PATCH 2/4] Move ty printing/elision logic to its own struct --- src/librustc/infer/error_reporting/mod.rs | 575 ++++++++++++---------- 1 file changed, 317 insertions(+), 258 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index a88e90caee307..858b53d1bb3cf 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -399,262 +399,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } - /// Given that `other_ty` is the same as a type argument for `name` in `sub`, populate `value` - /// highlighting `name` and every type argument that isn't at `pos` (which is `other_ty`), and - /// populate `other_value` with `other_ty`. - /// - /// ```text - /// Foo> - /// ^^^^--------^ this is highlighted - /// | | - /// | this type argument is exactly the same as the other type, not highlighted - /// this is highlighted - /// Bar - /// -------- this type is the same as a type argument in the other type, not highlighted - /// ``` - fn highlight_outer(&self, - value: &mut DiagnosticStyledString, - other_value: &mut DiagnosticStyledString, - name: String, - sub: &ty::subst::Substs<'tcx>, - pos: usize, - other_ty: &Ty<'tcx>) { - // `value` and `other_value` hold two incomplete type representation for display. - // `name` is the path of both types being compared. `sub` - value.push_highlighted(name); - let len = sub.len(); - if len > 0 { - value.push_highlighted("<"); - } - - // Output the lifetimes fot the first type - let lifetimes = sub.regions().map(|lifetime| { - let s = format!("{}", lifetime); - if s.is_empty() { - "'_".to_string() - } else { - s - } - }).collect::>().join(", "); - if !lifetimes.is_empty() { - if sub.regions().count() < len { - value.push_normal(lifetimes + &", "); - } else { - value.push_normal(lifetimes); - } - } - - // Highlight all the type arguments that aren't at `pos` and compare the type argument at - // `pos` and `other_ty`. - for (i, type_arg) in sub.types().enumerate() { - if i == pos { - let values = self.cmp(type_arg, other_ty); - value.0.extend((values.0).0); - other_value.0.extend((values.1).0); - } else { - value.push_highlighted(format!("{}", type_arg)); - } - - if len > 0 && i != len - 1 { - value.push_normal(", "); - } - //self.push_comma(&mut value, &mut other_value, len, i); - } - if len > 0 { - value.push_highlighted(">"); - } - } - - /// If `other_ty` is the same as a type argument present in `sub`, highlight `path` in `t1_out`, - /// as that is the difference to the other type. - /// - /// For the following code: - /// - /// ```norun - /// let x: Foo> = foo::>(); - /// ``` - /// - /// The type error output will behave in the following way: - /// - /// ```text - /// Foo> - /// ^^^^--------^ this is highlighted - /// | | - /// | this type argument is exactly the same as the other type, not highlighted - /// this is highlighted - /// Bar - /// -------- this type is the same as a type argument in the other type, not highlighted - /// ``` - fn cmp_type_arg(&self, - mut t1_out: &mut DiagnosticStyledString, - mut t2_out: &mut DiagnosticStyledString, - path: String, - sub: &ty::subst::Substs<'tcx>, - other_path: String, - other_ty: &Ty<'tcx>) -> Option<()> { - for (i, ta) in sub.types().enumerate() { - if &ta == other_ty { - self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty); - return Some(()); - } - if let &ty::TyAdt(def, _) = &ta.sty { - let path_ = self.tcx.item_path_str(def.did.clone()); - if path_ == other_path { - self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty); - return Some(()); - } - } - } - None - } - - /// Add a `,` to the type representation only if it is appropriate. - fn push_comma(&self, - value: &mut DiagnosticStyledString, - other_value: &mut DiagnosticStyledString, - len: usize, - pos: usize) { - if len > 0 && pos != len - 1 { - value.push_normal(", "); - other_value.push_normal(", "); - } - } - - /// Compare two given types, eliding parts that are the same between them and highlighting - /// relevant differences, and return two representation of those types for highlighted printing. - fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) - -> (DiagnosticStyledString, DiagnosticStyledString) - { - match (&t1.sty, &t2.sty) { - (&ty::TyAdt(def1, sub1), &ty::TyAdt(def2, sub2)) => { - let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); - let path1 = self.tcx.item_path_str(def1.did.clone()); - let path2 = self.tcx.item_path_str(def2.did.clone()); - if def1.did == def2.did { - // Easy case. Replace same types with `_` to shorten the output and highlight - // the differing ones. - // let x: Foo = y::>(); - // Foo - // Foo - // --- ^ type argument elided - // | - // highlighted in output - values.0.push_normal(path1); - values.1.push_normal(path2); - - // Only draw `<...>` if there're lifetime/type arguments. - let len = sub1.len(); - if len > 0 { - values.0.push_normal("<"); - values.1.push_normal("<"); - } - - fn lifetime_display(lifetime: Region) -> String { - let s = format!("{}", lifetime); - if s.is_empty() { - "'_".to_string() - } else { - s - } - } - // At one point we'd like to elide all lifetimes here, they are irrelevant for - // all diagnostics that use this output - // - // Foo<'x, '_, Bar> - // Foo<'y, '_, Qux> - // ^^ ^^ --- type arguments are not elided - // | | - // | elided as they were the same - // not elided, they were different, but irrelevant - let lifetimes = sub1.regions().zip(sub2.regions()); - for (i, lifetimes) in lifetimes.enumerate() { - let l1 = lifetime_display(lifetimes.0); - let l2 = lifetime_display(lifetimes.1); - if l1 == l2 { - values.0.push_normal("'_"); - values.1.push_normal("'_"); - } else { - values.0.push_highlighted(l1); - values.1.push_highlighted(l2); - } - self.push_comma(&mut values.0, &mut values.1, len, i); - } - - // We're comparing two types with the same path, so we compare the type - // arguments for both. If they are the same, do not highlight and elide from the - // output. - // Foo<_, Bar> - // Foo<_, Qux> - // ^ elided type as this type argument was the same in both sides - let type_arguments = sub1.types().zip(sub2.types()); - let regions_len = sub1.regions().collect::>().len(); - for (i, (ta1, ta2)) in type_arguments.enumerate() { - let i = i + regions_len; - if ta1 == ta2 { - values.0.push_normal("_"); - values.1.push_normal("_"); - } else { - let (x1, x2) = self.cmp(ta1, ta2); - (values.0).0.extend(x1.0); - (values.1).0.extend(x2.0); - } - self.push_comma(&mut values.0, &mut values.1, len, i); - } - - // Close the type argument bracket. - // Only draw `<...>` if there're lifetime/type arguments. - if len > 0 { - values.0.push_normal(">"); - values.1.push_normal(">"); - } - values - } else { - // Check for case: - // let x: Foo = foo::>(); - // Foo - // ------- this type argument is exactly the same as the other type - // Bar - if self.cmp_type_arg(&mut values.0, - &mut values.1, - path1.clone(), - sub1, - path2.clone(), - &t2).is_some() { - return values; - } - // Check for case: - // let x: Bar = y:>>(); - // Bar - // Foo> - // ------- this type argument is exactly the same as the other type - if self.cmp_type_arg(&mut values.1, - &mut values.0, - path2, - sub2, - path1, - &t1).is_some() { - return values; - } - - // We couldn't find anything in common, highlight everything. - // let x: Bar = y::>(); - (DiagnosticStyledString::highlighted(format!("{}", t1)), - DiagnosticStyledString::highlighted(format!("{}", t2))) - } - } - _ => { - if t1 == t2 { - // The two types are the same, elide and don't highlight. - (DiagnosticStyledString::normal("_"), DiagnosticStyledString::normal("_")) - } else { - // We couldn't find anything in common, highlight everything. - (DiagnosticStyledString::highlighted(format!("{}", t1)), - DiagnosticStyledString::highlighted(format!("{}", t2))) - } - } - } - } - pub fn note_type_err(&self, diag: &mut DiagnosticBuilder<'tcx>, cause: &ObligationCause<'tcx>, @@ -749,8 +493,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if exp_found.references_error() { return None; } - - Some(self.cmp(exp_found.expected, exp_found.found)) + let printer = TyPrinter::new(self.tcx); + Some(printer.cmp(exp_found.expected, exp_found.found)) } /// Returns a string of the form "expected `{}`, found `{}`". @@ -966,3 +710,318 @@ impl<'tcx> ObligationCause<'tcx> { } } } + +struct TyPrinter<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, +} + +impl<'a, 'gcx, 'tcx> TyPrinter<'a, 'gcx, 'tcx> { + + fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> TyPrinter<'a, 'gcx, 'tcx> { + TyPrinter { tcx } + } + + fn item_path_str(&self, did: DefId) -> String { + self.tcx.item_path_str(did) + } + + fn lifetime_display(&self, lifetime: Region) -> String { + let s = format!("{}", lifetime); + if s.is_empty() { + "'_".to_string() + } else { + s + } + } + + fn ty_str(&self, ty: Ty<'tcx>) -> String { + if let ty::TyAdt(def, sub) = ty.sty { + let mut path = self.item_path_str(def.did.clone()); + + // Only draw `<...>` if there're lifetime/type arguments. + let len = sub.len(); + if len > 0 { + path.push_str("<"); + } + + let mut regions_len = 0; + for (i, lifetimes) in sub.regions().enumerate() { + let l = self.lifetime_display(lifetimes); + path.push_str(&l); + if len > 0 && i != len - 1 { + path.push_str(", "); + } + regions_len = i; + } + + for (i, type_arg) in sub.types().enumerate() { + let i = i + regions_len; + path.push_str(&self.ty_str(type_arg)); + if len > 0 && i != len - 1 { + path.push_str(", "); + } + } + + // Close the type argument bracket. + // Only draw `<...>` if there're lifetime/type arguments. + if len > 0 { + path.push_str(">"); + } + path + } else { + format!("{}", ty) + } + } + + /// Given that `other_ty` is the same as a type argument for `name` in `sub`, populate `value` + /// highlighting `name` and every type argument that isn't at `pos` (which is `other_ty`), and + /// populate `other_value` with `other_ty`. + /// + /// ```text + /// Foo> + /// ^^^^--------^ this is highlighted + /// | | + /// | this type argument is exactly the same as the other type, not highlighted + /// this is highlighted + /// Bar + /// -------- this type is the same as a type argument in the other type, not highlighted + /// ``` + fn highlight_outer(&self, + value: &mut DiagnosticStyledString, + other_value: &mut DiagnosticStyledString, + name: String, + sub: &ty::subst::Substs<'tcx>, + pos: usize, + other_ty: &Ty<'tcx>) { + // `value` and `other_value` hold two incomplete type representation for display. + // `name` is the path of both types being compared. `sub` + value.push_highlighted(name); + let len = sub.len(); + if len > 0 { + value.push_highlighted("<"); + } + + // Output the lifetimes fot the first type + let lifetimes = sub.regions().map(|lifetime| { + let s = format!("{}", lifetime); + if s.is_empty() { + "'_".to_string() + } else { + s + } + }).collect::>().join(", "); + if !lifetimes.is_empty() { + if sub.regions().count() < len { + value.push_normal(lifetimes + &", "); + } else { + value.push_normal(lifetimes); + } + } + + // Highlight all the type arguments that aren't at `pos` and compare the type argument at + // `pos` and `other_ty`. + for (i, type_arg) in sub.types().enumerate() { + if i == pos { + let values = self.cmp(type_arg, other_ty); + value.0.extend((values.0).0); + other_value.0.extend((values.1).0); + } else { + value.push_highlighted(self.ty_str(type_arg)); + } + + if len > 0 && i != len - 1 { + value.push_normal(", "); + } + //self.push_comma(&mut value, &mut other_value, len, i); + } + if len > 0 { + value.push_highlighted(">"); + } + } + + /// If `other_ty` is the same as a type argument present in `sub`, highlight `path` in `t1_out`, + /// as that is the difference to the other type. + /// + /// For the following code: + /// + /// ```norun + /// let x: Foo> = foo::>(); + /// ``` + /// + /// The type error output will behave in the following way: + /// + /// ```text + /// Foo> + /// ^^^^--------^ this is highlighted + /// | | + /// | this type argument is exactly the same as the other type, not highlighted + /// this is highlighted + /// Bar + /// -------- this type is the same as a type argument in the other type, not highlighted + /// ``` + fn cmp_type_arg(&self, + mut t1_out: &mut DiagnosticStyledString, + mut t2_out: &mut DiagnosticStyledString, + path: String, + sub: &ty::subst::Substs<'tcx>, + other_path: String, + other_ty: &Ty<'tcx>) -> Option<()> { + for (i, ta) in sub.types().enumerate() { + if &ta == other_ty { + self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty); + return Some(()); + } + if let &ty::TyAdt(def, _) = &ta.sty { + let path_ = self.item_path_str(def.did.clone()); + if path_ == other_path { + self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty); + return Some(()); + } + } + } + None + } + + /// Add a `,` to the type representation only if it is appropriate. + fn push_comma(&self, + value: &mut DiagnosticStyledString, + other_value: &mut DiagnosticStyledString, + len: usize, + pos: usize) { + if len > 0 && pos != len - 1 { + value.push_normal(", "); + other_value.push_normal(", "); + } + } + + /// Compare two given types, eliding parts that are the same between them and highlighting + /// relevant differences, and return two representation of those types for highlighted printing. + fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) + -> (DiagnosticStyledString, DiagnosticStyledString) + { + match (&t1.sty, &t2.sty) { + (&ty::TyAdt(def1, sub1), &ty::TyAdt(def2, sub2)) => { + let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); + let path1 = self.item_path_str(def1.did.clone()); + let path2 = self.item_path_str(def2.did.clone()); + debug!("\npath1: {}\npath2: {}", path1, path2); + if def1.did == def2.did { + // Easy case. Replace same types with `_` to shorten the output and highlight + // the differing ones. + // let x: Foo = y::>(); + // Foo + // Foo + // --- ^ type argument elided + // | + // highlighted in output + values.0.push_normal(path1); + values.1.push_normal(path2); + + // Only draw `<...>` if there're lifetime/type arguments. + let len = sub1.len(); + if len > 0 { + values.0.push_normal("<"); + values.1.push_normal("<"); + } + + // At one point we'd like to elide all lifetimes here, they are irrelevant for + // all diagnostics that use this output + // + // Foo<'x, '_, Bar> + // Foo<'y, '_, Qux> + // ^^ ^^ --- type arguments are not elided + // | | + // | elided as they were the same + // not elided, they were different, but irrelevant + let lifetimes = sub1.regions().zip(sub2.regions()); + for (i, lifetimes) in lifetimes.enumerate() { + let l1 = self.lifetime_display(lifetimes.0); + let l2 = self.lifetime_display(lifetimes.1); + if l1 == l2 { + values.0.push_normal("'_"); + values.1.push_normal("'_"); + } else { + values.0.push_highlighted(l1); + values.1.push_highlighted(l2); + } + self.push_comma(&mut values.0, &mut values.1, len, i); + } + + // We're comparing two types with the same path, so we compare the type + // arguments for both. If they are the same, do not highlight and elide from the + // output. + // Foo<_, Bar> + // Foo<_, Qux> + // ^ elided type as this type argument was the same in both sides + let type_arguments = sub1.types().zip(sub2.types()); + let regions_len = sub1.regions().collect::>().len(); + for (i, (ta1, ta2)) in type_arguments.enumerate() { + let i = i + regions_len; + if ta1 == ta2 { + values.0.push_normal("_"); + values.1.push_normal("_"); + } else { + let (x1, x2) = self.cmp(ta1, ta2); + (values.0).0.extend(x1.0); + (values.1).0.extend(x2.0); + } + self.push_comma(&mut values.0, &mut values.1, len, i); + } + + // Close the type argument bracket. + // Only draw `<...>` if there're lifetime/type arguments. + if len > 0 { + values.0.push_normal(">"); + values.1.push_normal(">"); + } + values + } else { + // Check for case: + // let x: Foo = foo::>(); + // Foo + // ------- this type argument is exactly the same as the other type + // Bar + if self.cmp_type_arg(&mut values.0, + &mut values.1, + path1.clone(), + sub1, + path2.clone(), + &t2).is_some() { + return values; + } + // Check for case: + // let x: Bar = y:>>(); + // Bar + // Foo> + // ------- this type argument is exactly the same as the other type + if self.cmp_type_arg(&mut values.1, + &mut values.0, + path2, + sub2, + path1, + &t1).is_some() { + return values; + } + + // We couldn't find anything in common, highlight everything. + // let x: Bar = y::>(); + (DiagnosticStyledString::highlighted(format!("{}", self.ty_str(t1))), + DiagnosticStyledString::highlighted(format!("{}", self.ty_str(t2)))) + } + } + _ => { + if t1 == t2 { + // The two types are the same, elide and don't highlight. + (DiagnosticStyledString::normal("_"), DiagnosticStyledString::normal("_")) + } else { + // We couldn't find anything in common, highlight everything. + let t1 = format!("{}", t1); + let t2 = format!("{}", t2); + debug!("\nt1: {}\nt2: {}", t1, t2); + (DiagnosticStyledString::highlighted(t1), + DiagnosticStyledString::highlighted(t2)) + } + } + } + } +} From 2efc1f82be42c89d9d118262b0af37e275edc088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 16 Sep 2017 16:21:52 -0700 Subject: [PATCH 3/4] Add `Debug` to `DiagnosticStyledString` --- src/librustc_errors/diagnostic.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index 9aae188f9ecdf..f3b8b36dccca4 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -36,7 +36,7 @@ pub struct SubDiagnostic { pub render_span: Option, } -#[derive(PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] pub struct DiagnosticStyledString(pub Vec); impl DiagnosticStyledString { @@ -62,7 +62,7 @@ impl DiagnosticStyledString { } } -#[derive(PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] pub enum StringPart { Normal(String), Highlighted(String), From 6877688f517e90f22683e526618bf921b168641d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 16 Sep 2017 16:51:18 -0700 Subject: [PATCH 4/4] Refer to types using the local identifier On type errors, refer to types using the locally available name when they have been imported into scope instead of the fully qualified path. ``` error[E0308]: mismatched types --> file.rs:7:24 | 7 | let y: Option = Ok(()); | ^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result` | = note: expected type `Option` found type `Result<(), _>` = help: here are some functions which might fulfill your needs: - .err() - .unwrap_err() ``` --- src/librustc/infer/error_reporting/mod.rs | 281 +++++++++++++++--- src/librustc/middle/const_val.rs | 4 + src/librustc/ty/context.rs | 4 + src/librustc/ty/sty.rs | 6 + src/librustc_const_math/int.rs | 9 + src/test/compile-fail/bad-const-type.rs | 2 +- src/test/compile-fail/cross-borrow-trait.rs | 2 +- .../compile-fail/destructure-trait-ref.rs | 2 +- src/test/compile-fail/fn-trait-formatting.rs | 6 +- .../fully-qualified-type-name1.rs | 2 +- .../fully-qualified-type-name4.rs | 2 +- .../generic-type-params-name-repr.rs | 4 +- src/test/compile-fail/issue-13466.rs | 8 +- src/test/compile-fail/issue-15783.rs | 4 +- src/test/compile-fail/issue-3680.rs | 4 +- src/test/compile-fail/issue-40749.rs | 2 +- src/test/compile-fail/issue-5100.rs | 2 +- src/test/compile-fail/issue-7061.rs | 2 +- src/test/compile-fail/issue-7092.rs | 2 +- src/test/compile-fail/issue-7867.rs | 8 +- src/test/compile-fail/noexporttypeexe.rs | 2 +- src/test/compile-fail/occurs-check-2.rs | 2 +- src/test/compile-fail/occurs-check.rs | 2 +- .../regions-infer-paramd-indirect.rs | 4 +- .../tag-that-dare-not-speak-its-name.rs | 2 +- src/test/compile-fail/terr-sorts.rs | 2 +- .../type-mismatch-same-crate-name.rs | 4 +- .../consider-removing-last-semi.stderr | 4 +- src/test/ui/block-result/issue-13428.stderr | 4 +- ...coercion-missing-tail-expected-type.stderr | 2 +- .../ex2d-push-inference-variable-2.stderr | 2 +- .../ex2e-push-inference-variable-3.stderr | 2 +- src/test/ui/local-ident.rs | 25 ++ src/test/ui/local-ident.stderr | 24 ++ src/test/ui/mismatched_types/abridged.stderr | 12 +- .../trait-bounds-cant-coerce.stderr | 4 +- .../ui/resolve/token-error-correct-3.stderr | 2 +- src/test/ui/span/coerce-suggestions.stderr | 16 +- src/test/ui/span/issue-33884.stderr | 4 +- .../issue-43420-no-over-suggest.stderr | 2 +- 40 files changed, 374 insertions(+), 103 deletions(-) create mode 100644 src/test/ui/local-ident.rs create mode 100644 src/test/ui/local-ident.stderr diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 858b53d1bb3cf..5af7329471da7 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -64,6 +64,7 @@ use std::fmt; use hir; use hir::map as hir_map; use hir::def_id::DefId; +use hir::intravisit::{self, Visitor, NestedVisitorMap}; use middle::region; use traits::{ObligationCause, ObligationCauseCode}; use ty::{self, Region, Ty, TyCtxt, TypeFoldable}; @@ -71,6 +72,7 @@ use ty::error::TypeError; use syntax::ast::DUMMY_NODE_ID; use syntax_pos::{Pos, Span}; use errors::{DiagnosticBuilder, DiagnosticStyledString}; +use util::nodemap::{FxHashMap, FxHashSet}; mod note; @@ -357,7 +359,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // for imported and non-imported crates if exp_path == found_path || exp_abs_path == found_abs_path { - let crate_name = self.tcx.crate_name(did1.krate); + let crate_name = self.tcx.cstore().crate_name_untracked(did1.krate); err.span_note(sp, &format!("Perhaps two different versions \ of crate `{}` are being used?", crate_name)); @@ -711,18 +713,182 @@ impl<'tcx> ObligationCause<'tcx> { } } +/// Visitor that collects every `Item` imported into the current `TyCtxt`'s scope. +struct ImportVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + /// All the `Item`s from other scopes visible from this `TyCtxt`, as well as their local name. + full_imports: FxHashMap, +} + +impl<'a, 'gcx, 'tcx> ImportVisitor<'a, 'gcx, 'tcx> { + fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self { + ImportVisitor { + tcx, + full_imports: FxHashMap(), + } + } +} + +impl<'a, 'gcx, 'tcx> Visitor<'gcx> for ImportVisitor<'a, 'gcx, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> { + NestedVisitorMap::All(&self.tcx.hir) + } + + fn visit_item(&mut self, item: &'gcx hir::Item) { + use hir::def::Def; + use hir::def::Def::*; + + fn handle_external_def(tcx: TyCtxt, + // avoid inspecting the same crates twice + external_mods: &mut FxHashSet, + // item to inspect + def: Def, + // the type alias table for imported tys + full_imports: &mut FxHashMap) { + match def { + Mod(def_id) => { + if !external_mods.insert(def_id) { + return; + } + for child in tcx.cstore().item_children_untracked(def_id, tcx.sess) { + let def_id = child.def.def_id(); + if let ty::Visibility::Public = tcx.cstore().visibility_untracked(def_id) { + let name = format!("{}", child.ident); + let path = tcx.item_path_str(def_id); + full_imports.insert(path, name); + // We're only looking at exported children, so everything under this + // will be visible when this module is imported, add all of them to the + // alias map. + handle_external_def(tcx, external_mods, child.def, full_imports) + } + } + } + Struct(def_id) | + Union(def_id) | + Enum(def_id) | + Variant(def_id) | + Trait(def_id) | + TyAlias(def_id) | + StructCtor(def_id, _) | + VariantCtor(def_id, _) => { + if let (ty::Visibility::Public, Some(name)) = ( + tcx.cstore().visibility_untracked(def_id), + tcx.cstore().def_key(def_id) + .disambiguated_data.data + .get_opt_name()) { + let name = format!("{}", name); + let path = tcx.item_path_str(def_id); + full_imports.insert(path, name); + } + } + _ => (), + } + } + + let mut external_mods = FxHashSet(); + match item.node { + // Importing a fully qualified path, add to type alias table. + hir::ItemUse(ref path, hir::UseKind::Single) => { + debug!("visit_item itemuse single {:?} {:?}", path, path.def); + let ty = self.tcx.item_path_str(path.def.def_id()); + self.full_imports.insert(format!("{}", ty), format!("{}", item.name)); + } + // Importing everything under a path, inspect recursively all the public exports from + // that module and add all of them to the type alias table. + hir::ItemUse(ref path, hir::UseKind::Glob) => { + debug!("visit_item itemuse glob {:?} {:?}", path, path.def); + + if let Mod(def_id) = path.def { + if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { + // Same crate import. + + // Inspect the module being imported for all visible items and add them to + // the type alias table. + if let hir::map::NodeItem(item) = self.tcx.hir.get(node_id) { + if let hir::ItemMod(ref mod_) = item.node { + // Look at all the items in the imported mod. + for item_id in &mod_.item_ids { + if let hir::map::NodeItem(item) = self.tcx.hir.get(item_id.id) { + // We only want to add items that have been exported to the + // type alias table, check visibility. + match item.vis { + hir::Visibility::Public | + hir::Visibility::Crate => { + let ty = self.tcx.node_path_str(item.id); + + self.full_imports.insert(format!("{}", ty), + format!("{}", item.name)); + } + _ => (), // item not visible, don't alias + } + } + } + } + } + } else { + // Importing from a different crate. + for child in self.tcx.cstore().item_children_untracked(def_id, + self.tcx.sess) { + handle_external_def(self.tcx, + &mut external_mods, + child.def, + &mut self.full_imports) + } + } + } + if let Err = path.def { // external crate + // Cross-crate: + for cnum in self.tcx.cstore().crates_untracked() { + let crate_name = self.tcx.cstore().crate_name_untracked(cnum); + if Some(crate_name) == path.segments.first().map(|s| s.name) { + let def_id = DefId { + krate: cnum, + index: hir::def_id::CRATE_DEF_INDEX, + }; + debug!("visit_item crate cnum {:?} {}", cnum, crate_name); + // Filter out crates not imported in this context. + handle_external_def(self.tcx, + &mut external_mods, + Mod(def_id), + &mut self.full_imports); + } + } + } + } + _ => (), // Ignore non-import items + } + } +} + +/// This struct knows how to print out a single type for human consumption, compare two types and +/// elide type arguments that are the same, highlight differences for terminal output, and identify +/// types that have been imported into this `TyCtxt` to refer to them with their local path, +/// instead of their fully qualified path. struct TyPrinter<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, + local_names: FxHashMap, } impl<'a, 'gcx, 'tcx> TyPrinter<'a, 'gcx, 'tcx> { - fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> TyPrinter<'a, 'gcx, 'tcx> { - TyPrinter { tcx } + let local_names = { + let mut visitor = ImportVisitor::new(tcx); + + let krate = tcx.hir.krate(); + intravisit::walk_crate(&mut visitor, krate); + debug!("full_imports {:?}", visitor.full_imports); + visitor.full_imports + }; + TyPrinter { tcx, local_names } } + /// `did`'s item's path string relative to this `TyCtxt`, taking into account imports. fn item_path_str(&self, did: DefId) -> String { - self.tcx.item_path_str(did) + let full_path_str = self.tcx.item_path_str(did); + match self.local_names.get(&full_path_str) { + Some(path) => path.to_owned(), + None => full_path_str, + } } fn lifetime_display(&self, lifetime: Region) -> String { @@ -735,41 +901,79 @@ impl<'a, 'gcx, 'tcx> TyPrinter<'a, 'gcx, 'tcx> { } fn ty_str(&self, ty: Ty<'tcx>) -> String { - if let ty::TyAdt(def, sub) = ty.sty { - let mut path = self.item_path_str(def.did.clone()); - - // Only draw `<...>` if there're lifetime/type arguments. - let len = sub.len(); - if len > 0 { - path.push_str("<"); - } + match ty.sty { + ty::TyAdt(def, sub) => { + let mut path = self.item_path_str(def.did.clone()); + + // Only draw `<...>` if there're lifetime/type arguments. + let len = sub.len(); + if len > 0 { + path.push_str("<"); + } - let mut regions_len = 0; - for (i, lifetimes) in sub.regions().enumerate() { - let l = self.lifetime_display(lifetimes); - path.push_str(&l); - if len > 0 && i != len - 1 { + let lifetimes = sub.regions() + .map(|lifetime| self.lifetime_display(lifetime)) + .collect::>() + .join(", "); + if lifetimes.len() > 0 { + path.push_str(&lifetimes); + } + let type_args = sub.types() + .map(|ty| self.ty_str(ty)) + .collect::>() + .join(", "); + if lifetimes.len() > 0 && type_args.len() > 0 { path.push_str(", "); } - regions_len = i; - } + if type_args.len() > 0 { + path.push_str(&type_args); + } - for (i, type_arg) in sub.types().enumerate() { - let i = i + regions_len; - path.push_str(&self.ty_str(type_arg)); - if len > 0 && i != len - 1 { - path.push_str(", "); + // Close the type argument bracket. + // Only draw `<...>` if there're lifetime/type arguments. + if len > 0 { + path.push_str(">"); } + path } - - // Close the type argument bracket. - // Only draw `<...>` if there're lifetime/type arguments. - if len > 0 { - path.push_str(">"); + ty::TyArray(ty, tyconst) => format!("[{}; {}]", + self.ty_str(ty), + tyconst.usize_val()), + ty::TySlice(ty) => format!("[{}]", self.ty_str(ty)), + ty::TyTuple(tys, _) => { + let tuple_tys = tys.iter().map(|ty| self.ty_str(ty)).collect::>(); + if tuple_tys.len() == 1 { + format!("({},)", tuple_tys[0]) + } else { + format!("({})", tuple_tys.join(", ")) + } } - path - } else { - format!("{}", ty) + ty::TyRawPtr(ty_and_mut) => { + let mut s = String::new(); + s.push_str("*"); + if let hir::Mutability::MutMutable = ty_and_mut.mutbl { + s.push_str("mut ") + } else { + s.push_str("const ") + } + s.push_str(&self.ty_str(ty_and_mut.ty)); + s + } + ty::TyRef(region, ty_and_mut) => { + let mut s = String::new(); + s.push_str("&"); + let r = region.to_string(); + s.push_str(&r); + if !r.is_empty() { + s.push_str(" "); + } + if let hir::Mutability::MutMutable = ty_and_mut.mutbl { + s.push_str("mut ") + } + s.push_str(&self.ty_str(ty_and_mut.ty)); + s + } + _ => format!("{}", ty), } } @@ -832,7 +1036,6 @@ impl<'a, 'gcx, 'tcx> TyPrinter<'a, 'gcx, 'tcx> { if len > 0 && i != len - 1 { value.push_normal(", "); } - //self.push_comma(&mut value, &mut other_value, len, i); } if len > 0 { value.push_highlighted(">"); @@ -904,7 +1107,6 @@ impl<'a, 'gcx, 'tcx> TyPrinter<'a, 'gcx, 'tcx> { let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); let path1 = self.item_path_str(def1.did.clone()); let path2 = self.item_path_str(def2.did.clone()); - debug!("\npath1: {}\npath2: {}", path1, path2); if def1.did == def2.did { // Easy case. Replace same types with `_` to shorten the output and highlight // the differing ones. @@ -1005,8 +1207,8 @@ impl<'a, 'gcx, 'tcx> TyPrinter<'a, 'gcx, 'tcx> { // We couldn't find anything in common, highlight everything. // let x: Bar = y::>(); - (DiagnosticStyledString::highlighted(format!("{}", self.ty_str(t1))), - DiagnosticStyledString::highlighted(format!("{}", self.ty_str(t2)))) + (DiagnosticStyledString::highlighted(self.ty_str(t1)), + DiagnosticStyledString::highlighted(self.ty_str(t2))) } } _ => { @@ -1015,11 +1217,8 @@ impl<'a, 'gcx, 'tcx> TyPrinter<'a, 'gcx, 'tcx> { (DiagnosticStyledString::normal("_"), DiagnosticStyledString::normal("_")) } else { // We couldn't find anything in common, highlight everything. - let t1 = format!("{}", t1); - let t2 = format!("{}", t2); - debug!("\nt1: {}\nt2: {}", t1, t2); - (DiagnosticStyledString::highlighted(t1), - DiagnosticStyledString::highlighted(t2)) + (DiagnosticStyledString::highlighted(self.ty_str(t1)), + DiagnosticStyledString::highlighted(self.ty_str(t2))) } } } diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 7b23998046730..0376823e4fae5 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -76,6 +76,10 @@ impl<'tcx> ConstVal<'tcx> { _ => None } } + + pub fn to_usize(&self) -> Option { + self.to_const_int().and_then(|i| i.to_usize()) + } } #[derive(Clone, Debug)] diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index fb0cdab0b6a0f..9d64945af2739 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1179,6 +1179,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.all_crate_nums(LOCAL_CRATE) } + pub fn cstore(&self) -> &CrateStore { + self.cstore + } + pub fn def_key(self, id: DefId) -> hir_map::DefKey { if id.is_local() { self.hir.def_key(id) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index f17f81ca06bea..a9be14ba1842b 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1469,4 +1469,10 @@ pub struct Const<'tcx> { pub val: ConstVal<'tcx>, } +impl<'tcx> Const<'tcx> { + pub fn usize_val(&self) -> usize { + self.val.to_usize().unwrap_or(0) + } +} + impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {} diff --git a/src/librustc_const_math/int.rs b/src/librustc_const_math/int.rs index 08473d729e4e5..46ee101f66e1d 100644 --- a/src/librustc_const_math/int.rs +++ b/src/librustc_const_math/int.rs @@ -188,6 +188,15 @@ impl ConstInt { }) } + /// Converts the value to a `usize` if it's in the range 0...std::usize::MAX + pub fn to_usize(&self) -> Option { + self.to_u128().and_then(|v| if v <= usize::max_value() as u128 { + Some(v as usize) + } else { + None + }) + } + /// Converts the value to a `u128` if it's in the range 0...std::u128::MAX pub fn to_u128(&self) -> Option { match *self { diff --git a/src/test/compile-fail/bad-const-type.rs b/src/test/compile-fail/bad-const-type.rs index 5547d19868d34..28a01d1d87bbd 100644 --- a/src/test/compile-fail/bad-const-type.rs +++ b/src/test/compile-fail/bad-const-type.rs @@ -10,7 +10,7 @@ static i: String = 10; //~^ ERROR mismatched types -//~| expected type `std::string::String` +//~| expected type `String` //~| found type `{integer}` //~| expected struct `std::string::String`, found integral variable fn main() { println!("{}", i); } diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs index 847a82c082651..f62a6ead24b60 100644 --- a/src/test/compile-fail/cross-borrow-trait.rs +++ b/src/test/compile-fail/cross-borrow-trait.rs @@ -19,5 +19,5 @@ pub fn main() { let x: Box = Box::new(Foo); let _y: &Trait = x; //~ ERROR E0308 //~| expected type `&Trait` - //~| found type `std::boxed::Box` + //~| found type `Box` } diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs index 09bd3a2fc57d9..e92d33a301f28 100644 --- a/src/test/compile-fail/destructure-trait-ref.rs +++ b/src/test/compile-fail/destructure-trait-ref.rs @@ -51,5 +51,5 @@ fn main() { let box box x = box 1isize as Box; //~^ ERROR mismatched types //~| expected type `T` - //~| found type `std::boxed::Box<_>` + //~| found type `Box<_>` } diff --git a/src/test/compile-fail/fn-trait-formatting.rs b/src/test/compile-fail/fn-trait-formatting.rs index 6d70f54edb429..d0df51eeea088 100644 --- a/src/test/compile-fail/fn-trait-formatting.rs +++ b/src/test/compile-fail/fn-trait-formatting.rs @@ -16,15 +16,15 @@ fn main() { let _: () = (box |_: isize| {}) as Box; //~^ ERROR mismatched types //~| expected type `()` - //~| found type `std::boxed::Box` + //~| found type `Box` let _: () = (box |_: isize, isize| {}) as Box; //~^ ERROR mismatched types //~| expected type `()` - //~| found type `std::boxed::Box` + //~| found type `Box` let _: () = (box || -> isize { unimplemented!() }) as Box isize>; //~^ ERROR mismatched types //~| expected type `()` - //~| found type `std::boxed::Box isize>` + //~| found type `Box isize>` needs_fn(1); //~^ ERROR : std::ops::Fn<(isize,)>` diff --git a/src/test/compile-fail/fully-qualified-type-name1.rs b/src/test/compile-fail/fully-qualified-type-name1.rs index 1a7ceb2e7639e..0482b7cf8b21c 100644 --- a/src/test/compile-fail/fully-qualified-type-name1.rs +++ b/src/test/compile-fail/fully-qualified-type-name1.rs @@ -14,7 +14,7 @@ fn main() { let x: Option; x = 5; //~^ ERROR mismatched types - //~| expected type `std::option::Option` + //~| expected type `Option` //~| found type `{integer}` //~| expected enum `std::option::Option`, found integral variable } diff --git a/src/test/compile-fail/fully-qualified-type-name4.rs b/src/test/compile-fail/fully-qualified-type-name4.rs index 3c8fde751f123..a83f281b0a82e 100644 --- a/src/test/compile-fail/fully-qualified-type-name4.rs +++ b/src/test/compile-fail/fully-qualified-type-name4.rs @@ -15,7 +15,7 @@ use std::option::Option; fn bar(x: usize) -> Option { return x; //~^ ERROR mismatched types - //~| expected type `std::option::Option` + //~| expected type `Option` //~| found type `usize` //~| expected enum `std::option::Option`, found usize } diff --git a/src/test/compile-fail/generic-type-params-name-repr.rs b/src/test/compile-fail/generic-type-params-name-repr.rs index 71d7cf792e475..64cf9a49f4793 100644 --- a/src/test/compile-fail/generic-type-params-name-repr.rs +++ b/src/test/compile-fail/generic-type-params-name-repr.rs @@ -36,12 +36,12 @@ fn main() { // Including cases where the default is using previous type params. let _: HashMap = (); //~^ ERROR mismatched types - //~| expected type `HashMap` + //~| expected type `HashMap` //~| found type `()` //~| expected struct `HashMap`, found () let _: HashMap> = (); //~^ ERROR mismatched types - //~| expected type `HashMap` + //~| expected type `HashMap` //~| found type `()` //~| expected struct `HashMap`, found () diff --git a/src/test/compile-fail/issue-13466.rs b/src/test/compile-fail/issue-13466.rs index abddf6ba7a38d..3552d8412ef6e 100644 --- a/src/test/compile-fail/issue-13466.rs +++ b/src/test/compile-fail/issue-13466.rs @@ -17,14 +17,14 @@ pub fn main() { let _x: usize = match Some(1) { Ok(u) => u, //~^ ERROR mismatched types - //~| expected type `std::option::Option<{integer}>` - //~| found type `std::result::Result<_, _>` + //~| expected type `Option<{integer}>` + //~| found type `Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` Err(e) => panic!(e) //~^ ERROR mismatched types - //~| expected type `std::option::Option<{integer}>` - //~| found type `std::result::Result<_, _>` + //~| expected type `Option<{integer}>` + //~| found type `Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` }; } diff --git a/src/test/compile-fail/issue-15783.rs b/src/test/compile-fail/issue-15783.rs index 37a2f1582bf08..bc3bae49a49c1 100644 --- a/src/test/compile-fail/issue-15783.rs +++ b/src/test/compile-fail/issue-15783.rs @@ -17,8 +17,8 @@ fn main() { let x = Some(&[name]); let msg = foo(x); //~^ ERROR mismatched types -//~| expected type `std::option::Option<&[&str]>` -//~| found type `std::option::Option<&[&str; 1]>` +//~| expected type `Option<&[&str]>` +//~| found type `Option<&[&str; 1]>` //~| expected slice, found array of 1 elements assert_eq!(msg, 3); } diff --git a/src/test/compile-fail/issue-3680.rs b/src/test/compile-fail/issue-3680.rs index e698e6da5294e..5a9cfddd1d763 100644 --- a/src/test/compile-fail/issue-3680.rs +++ b/src/test/compile-fail/issue-3680.rs @@ -12,8 +12,8 @@ fn main() { match None { Err(_) => () //~^ ERROR mismatched types - //~| expected type `std::option::Option<_>` - //~| found type `std::result::Result<_, _>` + //~| expected type `Option<_>` + //~| found type `Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` } } diff --git a/src/test/compile-fail/issue-40749.rs b/src/test/compile-fail/issue-40749.rs index 261ed49d10c1e..2e18ba45377b7 100644 --- a/src/test/compile-fail/issue-40749.rs +++ b/src/test/compile-fail/issue-40749.rs @@ -12,5 +12,5 @@ fn main() { [0; ..10]; //~^ ERROR mismatched types //~| expected type `usize` - //~| found type `std::ops::RangeTo<{integer}>` + //~| found type `RangeTo<{integer}>` } diff --git a/src/test/compile-fail/issue-5100.rs b/src/test/compile-fail/issue-5100.rs index 9ef780aac8e27..066fc925cd7d5 100644 --- a/src/test/compile-fail/issue-5100.rs +++ b/src/test/compile-fail/issue-5100.rs @@ -43,7 +43,7 @@ fn main() { box (true, false) => () //~^ ERROR mismatched types //~| expected type `(bool, bool)` -//~| found type `std::boxed::Box<_>` +//~| found type `Box<_>` } match (true, false) { diff --git a/src/test/compile-fail/issue-7061.rs b/src/test/compile-fail/issue-7061.rs index b99f5b707ee2d..9754dcabab65c 100644 --- a/src/test/compile-fail/issue-7061.rs +++ b/src/test/compile-fail/issue-7061.rs @@ -13,7 +13,7 @@ struct BarStruct; impl<'a> BarStruct { fn foo(&'a mut self) -> Box { self } //~^ ERROR mismatched types - //~| expected type `std::boxed::Box` + //~| expected type `Box` //~| found type `&'a mut BarStruct` } diff --git a/src/test/compile-fail/issue-7092.rs b/src/test/compile-fail/issue-7092.rs index 26e1597b1db4b..f868af97b64ad 100644 --- a/src/test/compile-fail/issue-7092.rs +++ b/src/test/compile-fail/issue-7092.rs @@ -16,7 +16,7 @@ fn foo(x: Whatever) { Some(field) => //~^ ERROR mismatched types //~| expected type `Whatever` -//~| found type `std::option::Option<_>` +//~| found type `Option<_>` //~| expected enum `Whatever`, found enum `std::option::Option` field.access(), } diff --git a/src/test/compile-fail/issue-7867.rs b/src/test/compile-fail/issue-7867.rs index 7d9f8e9058521..2ef5a6341cafd 100644 --- a/src/test/compile-fail/issue-7867.rs +++ b/src/test/compile-fail/issue-7867.rs @@ -25,13 +25,13 @@ fn main() { match &Some(42) { Some(x) => (), //~^ ERROR mismatched types - //~| expected type `&std::option::Option<{integer}>` - //~| found type `std::option::Option<_>` + //~| expected type `&Option<{integer}>` + //~| found type `Option<_>` //~| expected reference, found enum `std::option::Option` None => () //~^ ERROR mismatched types - //~| expected type `&std::option::Option<{integer}>` - //~| found type `std::option::Option<_>` + //~| expected type `&Option<{integer}>` + //~| found type `Option<_>` //~| expected reference, found enum `std::option::Option` } } diff --git a/src/test/compile-fail/noexporttypeexe.rs b/src/test/compile-fail/noexporttypeexe.rs index c950ef5b68002..1afdfe300c678 100644 --- a/src/test/compile-fail/noexporttypeexe.rs +++ b/src/test/compile-fail/noexporttypeexe.rs @@ -20,6 +20,6 @@ fn main() { let x: isize = noexporttypelib::foo(); //~^ ERROR mismatched types //~| expected type `isize` - //~| found type `std::option::Option` + //~| found type `Option` //~| expected isize, found enum `std::option::Option` } diff --git a/src/test/compile-fail/occurs-check-2.rs b/src/test/compile-fail/occurs-check-2.rs index a276af83dee25..5cb60079fa4b8 100644 --- a/src/test/compile-fail/occurs-check-2.rs +++ b/src/test/compile-fail/occurs-check-2.rs @@ -17,6 +17,6 @@ fn main() { f = box g; //~^ ERROR mismatched types //~| expected type `_` - //~| found type `std::boxed::Box<_>` + //~| found type `Box<_>` //~| cyclic type of infinite size } diff --git a/src/test/compile-fail/occurs-check.rs b/src/test/compile-fail/occurs-check.rs index 5b6a11e58c27c..499124cb0573b 100644 --- a/src/test/compile-fail/occurs-check.rs +++ b/src/test/compile-fail/occurs-check.rs @@ -15,6 +15,6 @@ fn main() { f = box f; //~^ ERROR mismatched types //~| expected type `_` - //~| found type `std::boxed::Box<_>` + //~| found type `Box<_>` //~| cyclic type of infinite size } diff --git a/src/test/compile-fail/regions-infer-paramd-indirect.rs b/src/test/compile-fail/regions-infer-paramd-indirect.rs index c559992c86531..fad115c2aedf8 100644 --- a/src/test/compile-fail/regions-infer-paramd-indirect.rs +++ b/src/test/compile-fail/regions-infer-paramd-indirect.rs @@ -32,8 +32,8 @@ impl<'a> set_f<'a> for c<'a> { fn set_f_bad(&mut self, b: Box) { self.f = b; //~^ ERROR mismatched types - //~| expected type `std::boxed::Box>` - //~| found type `std::boxed::Box>` + //~| expected type `Box>` + //~| found type `Box>` //~| lifetime mismatch } } diff --git a/src/test/compile-fail/tag-that-dare-not-speak-its-name.rs b/src/test/compile-fail/tag-that-dare-not-speak-its-name.rs index 8f420f1ce4b0d..88f8946ac814e 100644 --- a/src/test/compile-fail/tag-that-dare-not-speak-its-name.rs +++ b/src/test/compile-fail/tag-that-dare-not-speak-its-name.rs @@ -22,6 +22,6 @@ fn main() { let x : char = last(y); //~^ ERROR mismatched types //~| expected type `char` - //~| found type `std::option::Option<_>` + //~| found type `Option<_>` //~| expected char, found enum `std::option::Option` } diff --git a/src/test/compile-fail/terr-sorts.rs b/src/test/compile-fail/terr-sorts.rs index fd92a26d0fcec..d560bfce845e9 100644 --- a/src/test/compile-fail/terr-sorts.rs +++ b/src/test/compile-fail/terr-sorts.rs @@ -20,7 +20,7 @@ fn want_foo(f: foo) {} fn have_bar(b: bar) { want_foo(b); //~ ERROR mismatched types //~| expected type `foo` - //~| found type `std::boxed::Box` + //~| found type `Box` } fn main() {} diff --git a/src/test/compile-fail/type-mismatch-same-crate-name.rs b/src/test/compile-fail/type-mismatch-same-crate-name.rs index 4295d08a4709c..e74acaa71b0f3 100644 --- a/src/test/compile-fail/type-mismatch-same-crate-name.rs +++ b/src/test/compile-fail/type-mismatch-same-crate-name.rs @@ -33,7 +33,7 @@ fn main() { //~^ ERROR mismatched types //~| Perhaps two different versions of crate `crate_a1` //~| expected trait `main::a::Bar` - //~| expected type `std::boxed::Box` - //~| found type `std::boxed::Box` + //~| expected type `Box` + //~| found type `Box` } } diff --git a/src/test/ui/block-result/consider-removing-last-semi.stderr b/src/test/ui/block-result/consider-removing-last-semi.stderr index 5905cfa9322a2..d354cbde4d2a2 100644 --- a/src/test/ui/block-result/consider-removing-last-semi.stderr +++ b/src/test/ui/block-result/consider-removing-last-semi.stderr @@ -9,7 +9,7 @@ error[E0308]: mismatched types 14 | | } | |_^ expected struct `std::string::String`, found () | - = note: expected type `std::string::String` + = note: expected type `String` found type `()` error[E0308]: mismatched types @@ -23,7 +23,7 @@ error[E0308]: mismatched types 19 | | } | |_^ expected struct `std::string::String`, found () | - = note: expected type `std::string::String` + = note: expected type `String` found type `()` error: aborting due to 2 previous errors diff --git a/src/test/ui/block-result/issue-13428.stderr b/src/test/ui/block-result/issue-13428.stderr index 7bd4529c46399..dbecff6c104e6 100644 --- a/src/test/ui/block-result/issue-13428.stderr +++ b/src/test/ui/block-result/issue-13428.stderr @@ -12,7 +12,7 @@ error[E0308]: mismatched types 19 | | } | |_^ expected struct `std::string::String`, found () | - = note: expected type `std::string::String` + = note: expected type `String` found type `()` error[E0308]: mismatched types @@ -26,7 +26,7 @@ error[E0308]: mismatched types 24 | | } | |_^ expected struct `std::string::String`, found () | - = note: expected type `std::string::String` + = note: expected type `String` found type `()` error: aborting due to 2 previous errors diff --git a/src/test/ui/coercion-missing-tail-expected-type.stderr b/src/test/ui/coercion-missing-tail-expected-type.stderr index 0de0a25e68e24..0c4aa0f97e992 100644 --- a/src/test/ui/coercion-missing-tail-expected-type.stderr +++ b/src/test/ui/coercion-missing-tail-expected-type.stderr @@ -21,7 +21,7 @@ error[E0308]: mismatched types 19 | | } | |_^ expected enum `std::result::Result`, found () | - = note: expected type `std::result::Result` + = note: expected type `Result` found type `()` error: aborting due to 2 previous errors diff --git a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr index 38b0acf9339e0..8bfe700723650 100644 --- a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr +++ b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr @@ -27,7 +27,7 @@ note: but, the lifetime must be valid for the lifetime 'b as defined on the func 18 | | a.push(b); 19 | | } | |_^ -note: ...so that expression is assignable (expected &mut std::vec::Vec>, found &mut std::vec::Vec>) +note: ...so that expression is assignable (expected &mut Vec>, found &mut Vec>) --> $DIR/ex2d-push-inference-variable-2.rs:16:33 | 16 | let a: &mut Vec> = x; diff --git a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr index 035e516e8628e..75cc17097f0e9 100644 --- a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr +++ b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr @@ -27,7 +27,7 @@ note: but, the lifetime must be valid for the lifetime 'b as defined on the func 18 | | Vec::push(a, b); 19 | | } | |_^ -note: ...so that expression is assignable (expected &mut std::vec::Vec>, found &mut std::vec::Vec>) +note: ...so that expression is assignable (expected &mut Vec>, found &mut Vec>) --> $DIR/ex2e-push-inference-variable-3.rs:16:33 | 16 | let a: &mut Vec> = x; diff --git a/src/test/ui/local-ident.rs b/src/test/ui/local-ident.rs new file mode 100644 index 0000000000000..78f390c84687b --- /dev/null +++ b/src/test/ui/local-ident.rs @@ -0,0 +1,25 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use Mod1::S; +use Mod2::*; + +fn main() { + let x: X = S; + let y: Option = Ok(2); +} + +mod Mod1 { + pub struct S; +} + +mod Mod2 { + pub struct X; +} diff --git a/src/test/ui/local-ident.stderr b/src/test/ui/local-ident.stderr new file mode 100644 index 0000000000000..f8dc47994db11 --- /dev/null +++ b/src/test/ui/local-ident.stderr @@ -0,0 +1,24 @@ +error[E0308]: mismatched types + --> $DIR/local-ident.rs:15:16 + | +15 | let x: X = S; + | ^ expected struct `Mod2::X`, found struct `Mod1::S` + | + = note: expected type `X` + found type `S` + +error[E0308]: mismatched types + --> $DIR/local-ident.rs:16:28 + | +16 | let y: Option = Ok(2); + | ^^^^^ expected enum `std::option::Option`, found enum `std::result::Result` + | + = note: expected type `Option` + found type `Result<{integer}, _>` + = help: here are some functions which might fulfill your needs: + - .err() + - .ok() + - .unwrap_err() + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr index 8c63d7d6f91c5..009affd9333a1 100644 --- a/src/test/ui/mismatched_types/abridged.stderr +++ b/src/test/ui/mismatched_types/abridged.stderr @@ -7,7 +7,7 @@ error[E0308]: mismatched types | ^^^^^^^^^^^^^^^^^^^^ expected struct `Foo`, found enum `std::option::Option` | = note: expected type `Foo` - found type `std::option::Option` + found type `Option` error[E0308]: mismatched types --> $DIR/abridged.rs:30:5 @@ -18,7 +18,7 @@ error[E0308]: mismatched types | ^^^^^^^^^^^^^^^^^ expected struct `Foo`, found enum `std::result::Result` | = note: expected type `Foo` - found type `std::result::Result` + found type `Result` error[E0308]: mismatched types --> $DIR/abridged.rs:34:5 @@ -28,7 +28,7 @@ error[E0308]: mismatched types 34 | Foo { bar: 1 } | ^^^^^^^^^^^^^^ expected enum `std::option::Option`, found struct `Foo` | - = note: expected type `std::option::Option` + = note: expected type `Option` found type `Foo` error[E0308]: mismatched types @@ -39,7 +39,7 @@ error[E0308]: mismatched types 38 | Foo { bar: 1 } | ^^^^^^^^^^^^^^ expected enum `std::result::Result`, found struct `Foo` | - = note: expected type `std::result::Result` + = note: expected type `Result` found type `Foo` error[E0308]: mismatched types @@ -51,7 +51,7 @@ error[E0308]: mismatched types 49 | x | ^ expected struct `std::string::String`, found integral variable | - = note: expected type `X, std::string::String>` + = note: expected type `X, String>` found type `X, {integer}>` error[E0308]: mismatched types @@ -63,7 +63,7 @@ error[E0308]: mismatched types 60 | x | ^ expected struct `std::string::String`, found integral variable | - = note: expected type `X, _>` + = note: expected type `X, _>` found type `X, _>` error: aborting due to 6 previous errors diff --git a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr index ccc9fb56772f5..c47975b01355d 100644 --- a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr +++ b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types 24 | a(x); //~ ERROR mismatched types [E0308] | ^ expected trait `Foo + std::marker::Send`, found trait `Foo` | - = note: expected type `std::boxed::Box` - found type `std::boxed::Box` + = note: expected type `Box` + found type `Box` error: aborting due to previous error diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr index c8e19db3707e1..ac859b0127750 100644 --- a/src/test/ui/resolve/token-error-correct-3.stderr +++ b/src/test/ui/resolve/token-error-correct-3.stderr @@ -40,7 +40,7 @@ error[E0308]: mismatched types | expected (), found enum `std::result::Result` | = note: expected type `()` - found type `std::result::Result` + found type `Result` error: aborting due to 5 previous errors diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index b703632bf90c1..4915cb27a4ff9 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -5,7 +5,7 @@ error[E0308]: mismatched types | ^^^^^^^^^^^^^ expected usize, found struct `std::string::String` | = note: expected type `usize` - found type `std::string::String` + found type `String` = help: here are some functions which might fulfill your needs: - .capacity() - .len() @@ -17,7 +17,7 @@ error[E0308]: mismatched types | ^^^^^^^^^^^^^ expected &str, found struct `std::string::String` | = note: expected type `&str` - found type `std::string::String` + found type `String` = help: try with `&String::new()` error[E0308]: mismatched types @@ -26,8 +26,8 @@ error[E0308]: mismatched types 30 | test(&y); | ^^ types differ in mutability | - = note: expected type `&mut std::string::String` - found type `&std::string::String` + = note: expected type `&mut String` + found type `&String` error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:35:11 @@ -36,7 +36,7 @@ error[E0308]: mismatched types | ^^ types differ in mutability | = note: expected type `&mut i32` - found type `&std::string::String` + found type `&String` error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:41:9 @@ -45,7 +45,7 @@ error[E0308]: mismatched types | ^^^^^ cyclic type of infinite size | = note: expected type `_` - found type `std::boxed::Box<_>` + found type `Box<_>` error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:48:9 @@ -53,8 +53,8 @@ error[E0308]: mismatched types 48 | s = format!("foo"); | ^^^^^^^^^^^^^^ expected mutable reference, found struct `std::string::String` | - = note: expected type `&mut std::string::String` - found type `std::string::String` + = note: expected type `&mut String` + found type `String` = help: try with `&mut format!("foo")` = note: this error originates in a macro outside of the current crate diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr index 2a874181c7ad9..b238df619722c 100644 --- a/src/test/ui/span/issue-33884.stderr +++ b/src/test/ui/span/issue-33884.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types 16 | stream.write_fmt(format!("message received")) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::fmt::Arguments`, found struct `std::string::String` | - = note: expected type `std::fmt::Arguments<'_>` - found type `std::string::String` + = note: expected type `Arguments<'_>` + found type `String` = note: this error originates in a macro outside of the current crate error: aborting due to previous error diff --git a/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr b/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr index bcad9ce56c65e..1a5225f8f99ee 100644 --- a/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr +++ b/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr @@ -5,7 +5,7 @@ error[E0308]: mismatched types | ^^ expected slice, found struct `std::vec::Vec` | = note: expected type `&[u16]` - found type `&std::vec::Vec` + found type `&Vec` error: aborting due to previous error