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 { diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index a88e90caee307..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)); @@ -399,262 +401,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 +495,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 +712,515 @@ 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> { + 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 { + 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 { + let s = format!("{}", lifetime); + if s.is_empty() { + "'_".to_string() + } else { + s + } + } + + fn ty_str(&self, ty: Ty<'tcx>) -> String { + 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 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(", "); + } + if type_args.len() > 0 { + path.push_str(&type_args); + } + + // Close the type argument bracket. + // Only draw `<...>` if there're lifetime/type arguments. + if len > 0 { + path.push_str(">"); + } + path + } + 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(", ")) + } + } + 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), + } + } + + /// 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(", "); + } + } + 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()); + 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(self.ty_str(t1)), + DiagnosticStyledString::highlighted(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. + (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/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), 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