diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 42ccf7e72504b..854ad3ec59f11 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -13,7 +13,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE} use rustc_index::vec::IndexVec; use rustc_session::CrateDisambiguator; use rustc_span::hygiene::ExpnId; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use std::fmt::Write; @@ -90,7 +90,9 @@ pub struct Definitions { parent_modules_of_macro_defs: FxHashMap, /// Item with a given `DefIndex` was defined during macro expansion with ID `ExpnId`. expansions_that_defined: FxHashMap, - next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>, + // We use a `PlainDefPathData` instead of `DefPathData` so that we don't + // consider `Span`s (from `Ident`) when hashing or comparing + next_disambiguator: FxHashMap<(DefIndex, PlainDefPathData), u32>, def_index_to_span: FxHashMap, /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId` /// we know what parent node that fragment should be attached to thanks to this table. @@ -102,7 +104,7 @@ pub struct Definitions { /// A unique identifier that we can use to lookup a definition /// precisely. It combines the index of the definition's parent (if /// any) with a `DisambiguatedDefPathData`. -#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] pub struct DefKey { /// The parent path. pub parent: Option, @@ -153,7 +155,7 @@ impl DefKey { /// between them. This introduces some artificial ordering dependency /// but means that if you have, e.g., two impls for the same type in /// the same module, they do get distinct `DefId`s. -#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] pub struct DisambiguatedDefPathData { pub data: DefPathData, pub disambiguator: u32, @@ -206,7 +208,7 @@ impl DefPath { let mut s = String::with_capacity(self.data.len() * 16); for component in &self.data { - write!(s, "::{}[{}]", component.data.as_symbol(), component.disambiguator).unwrap(); + write!(s, "::{}[{}]", component.data.as_ident().name, component.disambiguator).unwrap(); } s @@ -225,9 +227,10 @@ impl DefPath { for component in &self.data { if component.disambiguator == 0 { - write!(s, "::{}", component.data.as_symbol()).unwrap(); + write!(s, "::{}", component.data.as_ident().name).unwrap(); } else { - write!(s, "{}[{}]", component.data.as_symbol(), component.disambiguator).unwrap(); + write!(s, "{}[{}]", component.data.as_ident().name, component.disambiguator) + .unwrap(); } } @@ -245,16 +248,49 @@ impl DefPath { opt_delimiter.map(|d| s.push(d)); opt_delimiter = Some('-'); if component.disambiguator == 0 { - write!(s, "{}", component.data.as_symbol()).unwrap(); + write!(s, "{}", component.data.as_ident().name).unwrap(); } else { - write!(s, "{}[{}]", component.data.as_symbol(), component.disambiguator).unwrap(); + write!(s, "{}[{}]", component.data.as_ident().name, component.disambiguator) + .unwrap(); } } s } } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +// A copy of `DefPathData`, but with `Symbol` substituted for `Ident`. +// We want to implement `Hash`, `Eq`, and `PartialEq` for this struct, +// but not for `DefPathData`. This prevents us from doing something like +// ```enum BaseDefPathData { ... }, type DefPathData = BaseDefPathData``` +//, as `DefPathData` would end up implementing `Hash`, `Eq`, and `PartialEq` due to +// the `#[derive] macros we would need to place on `BaseDefPathData`. +// +// This could be fixed by switching to the `derivative` crate, which allows +// custom bounds to be applied to parameters in the generated impls. +// This would allow us to write `trait IsSymbol {}; impl IsSymbol for Symbol {}`. +// and add a `T: IsSymbol` bound to the `derivative` impls on `PlainDefPathData`. +// +// For now, this small amount of duplication (which is invisible outside of this module) +// isn't worth pulling in an extra dependency. +#[derive(Eq, PartialEq, Hash, Clone, Copy)] +enum PlainDefPathData { + CrateRoot, + Misc, + Impl, + TypeNs(Symbol), + ValueNs(Symbol), + MacroNs(Symbol), + LifetimeNs(Symbol), + ClosureExpr, + Ctor, + AnonConst, + ImplTrait, +} + +// We intentionally do *not* derive `Eq`, `PartialEq`, and `Hash`: +// this would cause us to hash/compare using the `Span` from the `Ident`, +// which is almost never correct. +#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] pub enum DefPathData { // Root: these should only be used for the root nodes, because // they are treated specially by the `def_path` function. @@ -267,13 +303,13 @@ pub enum DefPathData { /// An impl. Impl, /// Something in the type namespace. - TypeNs(Symbol), + TypeNs(Ident), /// Something in the value namespace. - ValueNs(Symbol), + ValueNs(Ident), /// Something in the macro namespace. - MacroNs(Symbol), + MacroNs(Ident), /// Something in the lifetime namespace. - LifetimeNs(Symbol), + LifetimeNs(Ident), /// A closure expression. ClosureExpr, @@ -428,11 +464,12 @@ impl Definitions { ); // The root node must be created with `create_root_def()`. - assert!(data != DefPathData::CrateRoot); + assert!(!(matches!(data, DefPathData::CrateRoot))); // Find the next free disambiguator for this key. let disambiguator = { - let next_disamb = self.next_disambiguator.entry((parent, data)).or_insert(0); + let plain_data = data.to_plain(); + let next_disamb = self.next_disambiguator.entry((parent, plain_data)).or_insert(0); let disambiguator = *next_disamb; *next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow"); disambiguator @@ -522,7 +559,24 @@ impl Definitions { } impl DefPathData { - pub fn get_opt_name(&self) -> Option { + fn to_plain(&self) -> PlainDefPathData { + use self::DefPathData::*; + match *self { + TypeNs(name) => PlainDefPathData::TypeNs(name.name), + ValueNs(name) => PlainDefPathData::ValueNs(name.name), + MacroNs(name) => PlainDefPathData::MacroNs(name.name), + LifetimeNs(name) => PlainDefPathData::LifetimeNs(name.name), + CrateRoot => PlainDefPathData::CrateRoot, + Misc => PlainDefPathData::Misc, + Impl => PlainDefPathData::Impl, + ClosureExpr => PlainDefPathData::ClosureExpr, + Ctor => PlainDefPathData::Ctor, + AnonConst => PlainDefPathData::AnonConst, + ImplTrait => PlainDefPathData::ImplTrait, + } + } + + pub fn get_opt_name(&self) -> Option { use self::DefPathData::*; match *self { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), @@ -531,22 +585,22 @@ impl DefPathData { } } - pub fn as_symbol(&self) -> Symbol { + pub fn as_ident(&self) -> Ident { use self::DefPathData::*; match *self { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => name, // Note that this does not show up in user print-outs. - CrateRoot => sym::double_braced_crate, - Impl => sym::double_braced_impl, - Misc => sym::double_braced_misc, - ClosureExpr => sym::double_braced_closure, - Ctor => sym::double_braced_constructor, - AnonConst => sym::double_braced_constant, - ImplTrait => sym::double_braced_opaque, + CrateRoot => Ident::with_dummy_span(sym::double_braced_crate), + Impl => Ident::with_dummy_span(sym::double_braced_impl), + Misc => Ident::with_dummy_span(sym::double_braced_misc), + ClosureExpr => Ident::with_dummy_span(sym::double_braced_closure), + Ctor => Ident::with_dummy_span(sym::double_braced_constructor), + AnonConst => Ident::with_dummy_span(sym::double_braced_constant), + ImplTrait => Ident::with_dummy_span(sym::double_braced_opaque), } } pub fn to_string(&self) -> String { - self.as_symbol().to_string() + self.as_ident().name.to_string() } } diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 0b33408edf02d..addd7bbf9e6b9 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -64,9 +64,10 @@ pub struct FrameInfo<'tcx> { impl<'tcx> fmt::Display for FrameInfo<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ty::tls::with(|tcx| { - if tcx.def_key(self.instance.def_id()).disambiguated_data.data - == DefPathData::ClosureExpr - { + if matches!( + tcx.def_key(self.instance.def_id()).disambiguated_data.data, + DefPathData::ClosureExpr + ) { write!(f, "inside call to closure")?; } else { write!(f, "inside call to `{}`", self.instance)?; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 338ff45a4ac7a..52591b11d4bc2 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2996,9 +2996,16 @@ impl<'tcx> TyCtxt<'tcx> { hir_map::DefPathData::Ctor => { self.item_name(DefId { krate: id.krate, index: def_key.parent.unwrap() }) } - _ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| { - bug!("item_name: no name for {:?}", self.def_path(id)); - }), + _ => { + def_key + .disambiguated_data + .data + .get_opt_name() + .unwrap_or_else(|| { + bug!("item_name: no name for {:?}", self.def_path(id)); + }) + .name + } } } } diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs index 7605d44c7f30f..03e349b091ffd 100644 --- a/src/librustc/ty/print/obsolete.rs +++ b/src/librustc/ty/print/obsolete.rs @@ -186,9 +186,9 @@ impl DefPathBasedNames<'tcx> { // foo::bar::ItemName:: for part in self.tcx.def_path(def_id).data { if self.omit_disambiguators { - write!(output, "{}::", part.data.as_symbol()).unwrap(); + write!(output, "{}::", part.data.as_ident().name).unwrap(); } else { - write!(output, "{}[{}]::", part.data.as_symbol(), part.disambiguator).unwrap(); + write!(output, "{}[{}]::", part.data.as_ident().name, part.disambiguator).unwrap(); } } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index cb01d821c1871..f59a6021e1d81 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -13,7 +13,7 @@ use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; use rustc_ast::ast; use rustc_attr::{SignedInt, UnsignedInt}; -use rustc_span::symbol::{kw, Symbol}; +use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_target::spec::abi::Abi; use std::cell::Cell; @@ -402,12 +402,14 @@ pub trait PrettyPrinter<'tcx>: .find(|child| child.res.def_id() == def_id) .map(|child| child.ident.name); if let Some(reexport) = reexport { - *name = reexport; + *name = Ident::with_dummy_span(reexport); } } // Re-exported `extern crate` (#43189). DefPathData::CrateRoot => { - data = DefPathData::TypeNs(self.tcx().original_crate_name(def_id.krate)); + data = DefPathData::TypeNs(Ident::with_dummy_span( + self.tcx().original_crate_name(def_id.krate), + )); } _ => {} } @@ -1401,7 +1403,7 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { // FIXME(eddyb) `name` should never be empty, but it // currently is for `extern { ... }` "foreign modules". - let name = disambiguated_data.data.as_symbol().as_str(); + let name = disambiguated_data.data.to_string(); if !name.is_empty() { if !self.empty_path { write!(self, "::")?; diff --git a/src/librustc/ty/query/profiling_support.rs b/src/librustc/ty/query/profiling_support.rs index 99ada34d59ebe..58e86a3285142 100644 --- a/src/librustc/ty/query/profiling_support.rs +++ b/src/librustc/ty/query/profiling_support.rs @@ -60,12 +60,12 @@ impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> { match def_key.disambiguated_data.data { DefPathData::CrateRoot => { - name = self.tcx.original_crate_name(def_id.krate).as_str(); + name = self.tcx.original_crate_name(def_id.krate).as_str().to_string(); dis = ""; end_index = 3; } other => { - name = other.as_symbol().as_str(); + name = other.to_string(); if def_key.disambiguated_data.disambiguator == 0 { dis = ""; end_index = 3; diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 69daa2da1fd0e..e193dfc0313e7 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -448,7 +448,7 @@ impl<'tcx> TyCtxt<'tcx> { /// those are not yet phased out). The parent of the closure's /// `DefId` will also be the context where it appears. pub fn is_closure(self, def_id: DefId) -> bool { - self.def_key(def_id).disambiguated_data.data == DefPathData::ClosureExpr + matches!(self.def_key(def_id).disambiguated_data.data, DefPathData::ClosureExpr) } /// Returns `true` if `def_id` refers to a trait (i.e., `trait Foo { ... }`). @@ -465,7 +465,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns `true` if this `DefId` refers to the implicit constructor for /// a tuple struct like `struct Foo(u32)`, and `false` otherwise. pub fn is_constructor(self, def_id: DefId) -> bool { - self.def_key(def_id).disambiguated_data.data == DefPathData::Ctor + matches!(self.def_key(def_id).disambiguated_data.data, DefPathData::Ctor) } /// Given the def-ID of a fn or closure, returns the def-ID of diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 32b0f0db3589d..d017e953a2598 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -764,17 +764,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Get the name we'll use to make the def-path. Note // that collisions are ok here and this shouldn't // really show up for end-user. - let (str_name, kind) = match hir_name { - ParamName::Plain(ident) => (ident.name, hir::LifetimeParamKind::InBand), - ParamName::Fresh(_) => (kw::UnderscoreLifetime, hir::LifetimeParamKind::Elided), - ParamName::Error => (kw::UnderscoreLifetime, hir::LifetimeParamKind::Error), + let (name, kind) = match hir_name { + ParamName::Plain(ident) => (ident, hir::LifetimeParamKind::InBand), + ParamName::Fresh(_) => { + (Ident::with_dummy_span(kw::UnderscoreLifetime), hir::LifetimeParamKind::Elided) + } + ParamName::Error => { + (Ident::with_dummy_span(kw::UnderscoreLifetime), hir::LifetimeParamKind::Error) + } }; // Add a definition for the in-band lifetime def. self.resolver.definitions().create_def_with_parent( parent_index, node_id, - DefPathData::LifetimeNs(str_name), + DefPathData::LifetimeNs(name), ExpnId::root(), span, ); @@ -1560,7 +1564,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.context.resolver.definitions().create_def_with_parent( self.parent, def_node_id, - DefPathData::LifetimeNs(name.ident().name), + DefPathData::LifetimeNs(name.ident()), ExpnId::root(), lifetime.span, ); diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs index 55a3540809b48..311931e43251f 100644 --- a/src/librustc_codegen_llvm/debuginfo/namespace.rs +++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs @@ -29,7 +29,7 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { let namespace_name = match def_key.disambiguated_data.data { DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate), - data => data.as_symbol(), + data => data.as_ident().name, }; let namespace_name = namespace_name.as_str(); diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs index 8dd35208bf69a..b610bed561722 100644 --- a/src/librustc_codegen_ssa/debuginfo/type_names.rs +++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs @@ -217,7 +217,7 @@ pub fn push_debuginfo_type_name<'tcx>( output.push_str(&tcx.crate_name(def_id.krate).as_str()); for path_element in tcx.def_path(def_id).data { output.push_str("::"); - output.push_str(&path_element.data.as_symbol().as_str()); + output.push_str(&path_element.data.to_string()); } } else { output.push_str(&tcx.item_name(def_id).as_str()); diff --git a/src/librustc_codegen_utils/symbol_names/legacy.rs b/src/librustc_codegen_utils/symbol_names/legacy.rs index 0dedda9bb6b73..15b37526e5faa 100644 --- a/src/librustc_codegen_utils/symbol_names/legacy.rs +++ b/src/librustc_codegen_utils/symbol_names/legacy.rs @@ -315,7 +315,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { self.path.finalize_pending_component(); } - self.write_str(&disambiguated_data.data.as_symbol().as_str())?; + self.write_str(&disambiguated_data.data.to_string())?; Ok(self) } fn path_generic_args( diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs index a544381f33da1..76e2755556ad2 100644 --- a/src/librustc_infer/infer/error_reporting/mod.rs +++ b/src/librustc_infer/infer/error_reporting/mod.rs @@ -631,7 +631,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { disambiguated_data: &DisambiguatedDefPathData, ) -> Result { let mut path = print_prefix(self)?; - path.push(disambiguated_data.data.as_symbol().to_string()); + path.push(disambiguated_data.data.to_string()); Ok(path) } fn path_generic_args( diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs index 5b7b73b48ec5b..1d4517695f1a5 100644 --- a/src/librustc_lint/context.rs +++ b/src/librustc_lint/context.rs @@ -793,7 +793,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { _ => {} } - path.push(disambiguated_data.data.as_symbol()); + path.push(disambiguated_data.data.as_ident().name); Ok(path) } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 18b4c9ad5044c..6911cc66f79bb 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -14,7 +14,7 @@ use rustc_ast::ast; use rustc_ast::attr; use rustc_ast::expand::allocator::{global_allocator_spans, AllocatorKind}; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, Once}; use rustc_errors::struct_span_err; use rustc_expand::base::SyntaxExtension; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; @@ -29,6 +29,19 @@ use proc_macro::bridge::client::ProcMacro; use std::path::Path; use std::{cmp, fs}; +crate type SourceMapImportInfo = Once>; + +/// Holds information about a rustc_span::SourceFile imported from another crate. +/// See `imported_source_files()` for more information. +crate struct ImportedSourceFile { + /// This SourceFile's byte-offset within the source_map of its original crate + pub original_start_pos: rustc_span::BytePos, + /// The end of this SourceFile within the source_map of its original crate + pub original_end_pos: rustc_span::BytePos, + /// The imported SourceFile's representation within the local source_map + pub translated_source_file: Lrc, +} + #[derive(Clone)] pub struct CStore { metas: IndexVec>>, diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 5b7d89243c35f..162c44c2b50a5 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -35,16 +35,19 @@ use std::u32; use log::debug; use proc_macro::bridge::client::ProcMacro; -use rustc_ast::ast::{self, Ident}; +use rustc_ast::ast::{self, Ident, Name}; use rustc_attr as attr; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive}; use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder}; -use rustc_span::source_map::{self, respan, Spanned}; +use rustc_span::source_map; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{self, hygiene::MacroKind, BytePos, Pos, Span, DUMMY_SP}; +use crate::creader::{ImportedSourceFile, SourceMapImportInfo}; + pub use cstore_impl::{provide, provide_extern}; +use rustc_span::source_map::{respan, Spanned}; mod cstore_impl; @@ -80,7 +83,7 @@ crate struct CrateMetadata { /// Proc macro descriptions for this crate, if it's a proc macro crate. raw_proc_macros: Option<&'static [ProcMacro]>, /// Source maps for code from the crate. - source_map_import_info: Once>, + source_map_import_info: SourceMapImportInfo, /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. alloc_decoding_state: AllocDecodingState, /// The `DepNodeIndex` of the `DepNode` representing this upstream crate. @@ -113,17 +116,6 @@ crate struct CrateMetadata { extern_crate: Lock>, } -/// Holds information about a rustc_span::SourceFile imported from another crate. -/// See `imported_source_files()` for more information. -struct ImportedSourceFile { - /// This SourceFile's byte-offset within the source_map of its original crate - original_start_pos: rustc_span::BytePos, - /// The end of this SourceFile within the source_map of its original crate - original_end_pos: rustc_span::BytePos, - /// The imported SourceFile's representation within the local source_map - translated_source_file: Lrc, -} - pub(super) struct DecodeContext<'a, 'tcx> { opaque: opaque::Decoder<'a>, cdata: Option>, @@ -137,11 +129,28 @@ pub(super) struct DecodeContext<'a, 'tcx> { // Used for decoding interpret::AllocIds in a cached & thread-safe manner. alloc_decoding_session: Option>, + + meta_blob: Option<&'a MetadataBlob>, + crate_root: Option<&'a CrateRoot<'a>>, + local_source_map_import_info: Option<&'a SourceMapImportInfo>, + crate_num: Option, } /// Abstract over the various ways one can create metadata decoders. pub(super) trait Metadata<'a, 'tcx>: Copy { fn raw_bytes(self) -> &'a [u8]; + fn metadata_blob(self) -> Option<&'a MetadataBlob> { + None + } + fn crate_root(self) -> Option<&'a CrateRoot<'a>> { + None + } + fn local_source_map_import_info(self) -> Option<&'a SourceMapImportInfo> { + None + } + fn crate_num(self) -> Option { + None + } fn cdata(self) -> Option> { None } @@ -164,10 +173,45 @@ pub(super) trait Metadata<'a, 'tcx>: Copy { alloc_decoding_session: self .cdata() .map(|cdata| cdata.cdata.alloc_decoding_state.new_decoding_session()), + + meta_blob: self.metadata_blob(), + crate_root: self.crate_root(), + local_source_map_import_info: self.local_source_map_import_info(), + crate_num: self.crate_num(), } } } +struct InitialMetadataContext<'a, 'tcx> { + blob: &'a MetadataBlob, + crate_root: &'a CrateRoot<'a>, + local_source_map_import_info: &'a SourceMapImportInfo, + crate_num: CrateNum, + sess: &'tcx Session, +} + +impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a InitialMetadataContext<'a, 'tcx> { + fn raw_bytes(self) -> &'a [u8] { + &self.blob.0 + } + + fn metadata_blob(self) -> Option<&'a MetadataBlob> { + Some(self.blob) + } + fn crate_root(self) -> Option<&'a CrateRoot<'a>> { + Some(self.crate_root) + } + fn local_source_map_import_info(self) -> Option<&'a SourceMapImportInfo> { + Some(self.local_source_map_import_info) + } + fn crate_num(self) -> Option { + Some(self.crate_num) + } + fn sess(self) -> Option<&'tcx Session> { + Some(self.sess) + } +} + impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob { fn raw_bytes(self) -> &'a [u8] { &self.0 @@ -193,6 +237,19 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadataRef<'a> { fn cdata(self) -> Option> { Some(*self) } + + fn metadata_blob(self) -> Option<&'a MetadataBlob> { + Some(&self.blob) + } + fn crate_root(self) -> Option<&'a CrateRoot<'a>> { + Some(&self.cdata.root) + } + fn local_source_map_import_info(self) -> Option<&'a SourceMapImportInfo> { + Some(&self.cdata.source_map_import_info) + } + fn crate_num(self) -> Option { + Some(self.cdata.cnum) + } } impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, &'tcx Session) { @@ -202,6 +259,19 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, &'tcx Session) fn cdata(self) -> Option> { Some(*self.0) } + + fn metadata_blob(self) -> Option<&'a MetadataBlob> { + self.0.metadata_blob() + } + fn crate_root(self) -> Option<&'a CrateRoot<'a>> { + self.0.crate_root() + } + fn local_source_map_import_info(self) -> Option<&'a SourceMapImportInfo> { + self.0.local_source_map_import_info() + } + fn crate_num(self) -> Option { + self.0.crate_num() + } fn sess(self) -> Option<&'tcx Session> { Some(&self.1) } @@ -217,6 +287,18 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, TyCtxt<'tcx>) { fn tcx(self) -> Option> { Some(self.1) } + fn metadata_blob(self) -> Option<&'a MetadataBlob> { + self.0.metadata_blob() + } + fn crate_root(self) -> Option<&'a CrateRoot<'a>> { + self.0.crate_root() + } + fn local_source_map_import_info(self) -> Option<&'a SourceMapImportInfo> { + self.0.local_source_map_import_info() + } + fn crate_num(self) -> Option { + self.0.crate_num() + } } impl<'a, 'tcx, T: Decodable> Lazy { @@ -265,6 +347,112 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { self.lazy_state = LazyState::Previous(NonZeroUsize::new(position + min_size).unwrap()); Ok(Lazy::from_position_and_meta(NonZeroUsize::new(position).unwrap(), meta)) } + + /// Imports the source_map from an external crate into the source_map of the crate + /// currently being compiled (the "local crate"). + /// + /// The import algorithm works analogous to how AST items are inlined from an + /// external crate's metadata: + /// For every SourceFile in the external source_map an 'inline' copy is created in the + /// local source_map. The correspondence relation between external and local + /// SourceFiles is recorded in the `ImportedSourceFile` objects returned from this + /// function. When an item from an external crate is later inlined into this + /// crate, this correspondence information is used to translate the span + /// information of the inlined item so that it refers the correct positions in + /// the local source_map (see `>`). + /// + /// The import algorithm in the function below will reuse SourceFiles already + /// existing in the local source_map. For example, even if the SourceFile of some + /// source file of libstd gets imported many times, there will only ever be + /// one SourceFile object for the corresponding file in the local source_map. + /// + /// Note that imported SourceFiles do not actually contain the source code of the + /// file they represent, just information about length, line breaks, and + /// multibyte characters. This information is enough to generate valid debuginfo + /// for items inlined from other crates. + /// + /// Proc macro crates don't currently export spans, so this function does not have + /// to work for them. + fn imported_source_files( + &self, + local_source_map: &source_map::SourceMap, + ) -> &'a [ImportedSourceFile] { + self.local_source_map_import_info.unwrap().init_locking(|| { + // If we ever need more than just the metadata blob to decode `source_map`, + // we'll have to pass more data into this method + let external_source_map = + self.crate_root.unwrap().source_map.decode(self.meta_blob.unwrap()); + + external_source_map + .map(|source_file_to_import| { + // We can't reuse an existing SourceFile, so allocate a new one + // containing the information we need. + let rustc_span::SourceFile { + name, + name_was_remapped, + src_hash, + start_pos, + end_pos, + mut lines, + mut multibyte_chars, + mut non_narrow_chars, + mut normalized_pos, + name_hash, + .. + } = source_file_to_import; + + let source_length = (end_pos - start_pos).to_usize(); + + // Translate line-start positions and multibyte character + // position into frame of reference local to file. + // `SourceMap::new_imported_source_file()` will then translate those + // coordinates to their new global frame of reference when the + // offset of the SourceFile is known. + for pos in &mut lines { + *pos = *pos - start_pos; + } + for mbc in &mut multibyte_chars { + mbc.pos = mbc.pos - start_pos; + } + for swc in &mut non_narrow_chars { + *swc = *swc - start_pos; + } + for np in &mut normalized_pos { + np.pos = np.pos - start_pos; + } + + let local_version = local_source_map.new_imported_source_file( + name, + name_was_remapped, + self.crate_num.unwrap().as_u32(), + src_hash, + name_hash, + source_length, + lines, + multibyte_chars, + non_narrow_chars, + normalized_pos, + ); + debug!( + "CrateMetaData::imported_source_files alloc \ + source_file {:?} original (start_pos {:?} end_pos {:?}) \ + translated (start_pos {:?} end_pos {:?})", + local_version.name, + start_pos, + end_pos, + local_version.start_pos, + local_version.end_pos + ); + + ImportedSourceFile { + original_start_pos: start_pos, + original_end_pos: end_pos, + translated_source_file: local_version, + } + }) + .collect() + }) + } } impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { @@ -399,7 +587,7 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { bug!("Cannot decode Span without Session.") }; - let imported_source_files = self.cdata().imported_source_files(&sess.source_map()); + let imported_source_files = self.imported_source_files(&sess.source_map()); let source_file = { // Optimize for the case that most spans within a translated item // originate from the same source_file. @@ -433,14 +621,6 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { } } -impl SpecializedDecoder for DecodeContext<'_, '_> { - fn specialized_decode(&mut self) -> Result { - // FIXME(jseyfried): intercrate hygiene - - Ok(Ident::with_dummy_span(Symbol::decode(self)?)) - } -} - impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result { Fingerprint::decode_opaque(&mut self.opaque) @@ -587,7 +767,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { &self.raw_proc_macros.unwrap()[pos] } - fn item_name(&self, item_index: DefIndex) -> Symbol { + fn item_name(&self, item_index: DefIndex) -> Ident { if !self.is_proc_macro(item_index) { self.def_key(item_index) .disambiguated_data @@ -595,7 +775,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .get_opt_name() .expect("no name in item_name") } else { - Symbol::intern(self.raw_proc_macro(item_index).name()) + Ident::with_dummy_span(Symbol::intern(self.raw_proc_macro(item_index).name())) } } @@ -695,7 +875,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ty::VariantDef::new( tcx, - Ident::with_dummy_span(self.item_name(index)), + self.item_name(index), variant_did, ctor_did, data.discr, @@ -707,7 +887,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .decode(self) .map(|index| ty::FieldDef { did: self.local_def_id(index), - ident: Ident::with_dummy_span(self.item_name(index)), + ident: self.item_name(index), vis: self.get_visibility(index), }) .collect(), @@ -931,7 +1111,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { if let Some(kind) = self.def_kind(child_index) { callback(Export { res: Res::Def(kind, self.local_def_id(child_index)), - ident: Ident::with_dummy_span(self.item_name(child_index)), + ident: self.item_name(child_index), vis: self.get_visibility(child_index), span: self .root @@ -952,10 +1132,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let def_key = self.def_key(child_index); let span = self.get_span(child_index, sess); - if let (Some(kind), Some(name)) = + if let (Some(kind), Some(ident)) = (self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name()) { - let ident = Ident::with_dummy_span(name); let vis = self.get_visibility(child_index); let def_id = self.local_def_id(child_index); let res = Res::Def(kind, def_id); @@ -1079,7 +1258,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }; ty::AssocItem { - ident: Ident::with_dummy_span(name), + ident: name, kind, vis: self.get_visibility(id), defaultness: container.defaultness(), @@ -1119,7 +1298,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { // we assume that someone passing in a tuple struct ctor is actually wanting to // look at the definition let def_key = self.def_key(node_id); - let item_id = if def_key.disambiguated_data.data == DefPathData::Ctor { + let item_id = if matches!(def_key.disambiguated_data.data, DefPathData::Ctor) { def_key.parent.unwrap() } else { node_id @@ -1136,14 +1315,17 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ) } - fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec> { + fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec> { self.root .per_def .children .get(self, id) .unwrap_or(Lazy::empty()) - .decode(self) - .map(|index| respan(self.get_span(index, sess), self.item_name(index))) + .decode((self, sess)) + .map(|index| { + let ident = self.item_name(index); + respan(ident.span, ident.name) + }) .collect() } @@ -1342,7 +1524,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let mut key = self.def_path_table.def_key(index); if self.is_proc_macro(index) { let name = self.raw_proc_macro(index).name(); - key.disambiguated_data.data = DefPathData::MacroNs(Symbol::intern(name)); + key.disambiguated_data.data = + DefPathData::MacroNs(Ident::with_dummy_span(Symbol::intern(name))); } key } @@ -1352,109 +1535,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { debug!("def_path(cnum={:?}, id={:?})", self.cnum, id); DefPath::make(self.cnum, id, |parent| self.def_key(parent)) } - - /// Imports the source_map from an external crate into the source_map of the crate - /// currently being compiled (the "local crate"). - /// - /// The import algorithm works analogous to how AST items are inlined from an - /// external crate's metadata: - /// For every SourceFile in the external source_map an 'inline' copy is created in the - /// local source_map. The correspondence relation between external and local - /// SourceFiles is recorded in the `ImportedSourceFile` objects returned from this - /// function. When an item from an external crate is later inlined into this - /// crate, this correspondence information is used to translate the span - /// information of the inlined item so that it refers the correct positions in - /// the local source_map (see `>`). - /// - /// The import algorithm in the function below will reuse SourceFiles already - /// existing in the local source_map. For example, even if the SourceFile of some - /// source file of libstd gets imported many times, there will only ever be - /// one SourceFile object for the corresponding file in the local source_map. - /// - /// Note that imported SourceFiles do not actually contain the source code of the - /// file they represent, just information about length, line breaks, and - /// multibyte characters. This information is enough to generate valid debuginfo - /// for items inlined from other crates. - /// - /// Proc macro crates don't currently export spans, so this function does not have - /// to work for them. - fn imported_source_files( - &self, - local_source_map: &source_map::SourceMap, - ) -> &'a [ImportedSourceFile] { - self.cdata.source_map_import_info.init_locking(|| { - let external_source_map = self.root.source_map.decode(self); - - external_source_map - .map(|source_file_to_import| { - // We can't reuse an existing SourceFile, so allocate a new one - // containing the information we need. - let rustc_span::SourceFile { - name, - name_was_remapped, - src_hash, - start_pos, - end_pos, - mut lines, - mut multibyte_chars, - mut non_narrow_chars, - mut normalized_pos, - name_hash, - .. - } = source_file_to_import; - - let source_length = (end_pos - start_pos).to_usize(); - - // Translate line-start positions and multibyte character - // position into frame of reference local to file. - // `SourceMap::new_imported_source_file()` will then translate those - // coordinates to their new global frame of reference when the - // offset of the SourceFile is known. - for pos in &mut lines { - *pos = *pos - start_pos; - } - for mbc in &mut multibyte_chars { - mbc.pos = mbc.pos - start_pos; - } - for swc in &mut non_narrow_chars { - *swc = *swc - start_pos; - } - for np in &mut normalized_pos { - np.pos = np.pos - start_pos; - } - - let local_version = local_source_map.new_imported_source_file( - name, - name_was_remapped, - self.cnum.as_u32(), - src_hash, - name_hash, - source_length, - lines, - multibyte_chars, - non_narrow_chars, - normalized_pos, - ); - debug!( - "CrateMetaData::imported_source_files alloc \ - source_file {:?} original (start_pos {:?} end_pos {:?}) \ - translated (start_pos {:?} end_pos {:?})", - local_version.name, - start_pos, - end_pos, - local_version.start_pos, - local_version.end_pos - ); - - ImportedSourceFile { - original_start_pos: start_pos, - original_end_pos: end_pos, - translated_source_file: local_version, - } - }) - .collect() - }) - } } impl CrateMetadata { @@ -1470,8 +1550,15 @@ impl CrateMetadata { private_dep: bool, host_hash: Option, ) -> CrateMetadata { + let source_map_import_info = Once::new(); let def_path_table = record_time(&sess.perf_stats.decode_def_path_tables_time, || { - root.def_path_table.decode((&blob, sess)) + root.def_path_table.decode(&InitialMetadataContext { + blob: &blob, + crate_root: &root, + local_source_map_import_info: &source_map_import_info, + crate_num: cnum, + sess, + }) }); let trait_impls = root .impls @@ -1487,7 +1574,7 @@ impl CrateMetadata { def_path_table, trait_impls, raw_proc_macros, - source_map_import_info: Once::new(), + source_map_import_info, alloc_decoding_state, dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), cnum, diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index d87e24eeed173..8724ecc5e2e12 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -425,7 +425,6 @@ impl CStore { .disambiguated_data .data .get_opt_name() - .map(ast::Ident::with_dummy_span) // FIXME: cross-crate hygiene .expect("no name in load_macro"); LoadedMacro::MacroDef( diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 4c8e07c223bd3..bc78bf5293ffa 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -28,7 +28,7 @@ use log::{debug, trace}; use rustc_ast::ast; use rustc_ast::attr; use rustc_span::source_map::Spanned; -use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{self, FileName, SourceFile, Span}; use std::hash::Hash; use std::num::NonZeroUsize; @@ -186,13 +186,6 @@ impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { } } -impl SpecializedEncoder for EncodeContext<'tcx> { - fn specialized_encode(&mut self, ident: &Ident) -> Result<(), Self::Error> { - // FIXME(jseyfried): intercrate hygiene - ident.name.encode(self) - } -} - impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { #[inline] fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> { diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index 677dc69773516..a3cc33e059a4f 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -136,7 +136,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { self.path.push_str("::"); - self.path.push_str(&disambiguated_data.data.as_symbol().as_str()); + self.path.push_str(&disambiguated_data.data.to_string()); Ok(self) } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 9b81d69ce694c..6d65e18bb5bfa 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -750,7 +750,7 @@ fn compute_codegen_unit_name( *cache.entry((cgu_def_id, volatile)).or_insert_with(|| { let def_path = tcx.def_path(cgu_def_id); - let components = def_path.data.iter().map(|part| part.data.as_symbol()); + let components = def_path.data.iter().map(|part| part.data.as_ident()); let volatile_suffix = volatile.then_some("volatile"); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index ce3b1233a7473..774e8964e9180 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -33,11 +33,11 @@ use rustc_hir::def::{self, *}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_metadata::creader::LoadedMacro; use rustc_span::hygiene::{ExpnId, MacroKind}; -use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym}; use rustc_span::{Span, DUMMY_SP}; use log::debug; +use rustc_span::source_map::{respan, Spanned}; use std::cell::Cell; use std::ptr; @@ -105,7 +105,7 @@ impl<'a> Resolver<'a> { } let (name, parent) = if def_id.index == CRATE_DEF_INDEX { - (self.cstore().crate_name_untracked(def_id.krate), None) + (Ident::with_dummy_span(self.cstore().crate_name_untracked(def_id.krate)), None) } else { let def_key = self.cstore().def_key(def_id); ( @@ -114,7 +114,7 @@ impl<'a> Resolver<'a> { ) }; - let kind = ModuleKind::Def(DefKind::Mod, def_id, name); + let kind = ModuleKind::Def(DefKind::Mod, def_id, name.name); let module = self.arenas.alloc_module(ModuleData::new( parent, kind, @@ -288,7 +288,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let field_names = vdata .fields() .iter() - .map(|field| respan(field.span, field.ident.map_or(kw::Invalid, |ident| ident.name))) + .map(|field| { + field + .ident + // For unnamed fields, use the span of the field with `kw::Invalid` + // For named fields, just convert the `Ident` to a `Spanned` directly + .map_or_else(|| respan(field.span, kw::Invalid), |i| respan(i.span, i.name)) + }) .collect(); self.insert_field_names(def_id, field_names); } @@ -1166,7 +1172,7 @@ macro_rules! method { visit::$walk(self, node); } } - } + }; } impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index 16359cc743767..bdabb1abadb70 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -50,7 +50,8 @@ impl<'a> DefCollector<'a> { self.definitions.set_placeholder_field_index(field.id, index(self)); self.visit_macro_invoc(field.id); } else { - let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name); + let name = + field.ident.unwrap_or_else(|| Ident::new(sym::integer(index(self)), field.span)); let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span); self.with_parent(def, |this| visit::walk_struct_field(this, field)); } @@ -80,11 +81,12 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { | ItemKind::Union(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) - | ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), + | ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident), + ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => { - DefPathData::ValueNs(i.ident.name) + DefPathData::ValueNs(i.ident) } - ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.name), + ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident), ItemKind::MacCall(..) => return self.visit_macro_invoc(i.id), ItemKind::GlobalAsm(..) => DefPathData::Misc, ItemKind::Use(..) => { @@ -140,7 +142,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { let def = self.create_def( foreign_item.id, - DefPathData::ValueNs(foreign_item.ident.name), + DefPathData::ValueNs(foreign_item.ident), foreign_item.span, ); @@ -153,7 +155,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { if v.is_placeholder { return self.visit_macro_invoc(v.id); } - let def = self.create_def(v.id, DefPathData::TypeNs(v.ident.name), v.span); + let def = self.create_def(v.id, DefPathData::TypeNs(v.ident), v.span); self.with_parent(def, |this| { if let Some(ctor_hir_id) = v.data.ctor_id() { this.create_def(ctor_hir_id, DefPathData::Ctor, v.span); @@ -176,7 +178,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { self.visit_macro_invoc(param.id); return; } - let name = param.ident.name; + let name = param.ident; let def_path_data = match param.kind { GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name), GenericParamKind::Type { .. } => DefPathData::TypeNs(name), @@ -189,8 +191,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) { let def_data = match &i.kind { - AssocItemKind::Fn(..) | AssocItemKind::Const(..) => DefPathData::ValueNs(i.ident.name), - AssocItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), + AssocItemKind::Fn(..) | AssocItemKind::Const(..) => DefPathData::ValueNs(i.ident), + AssocItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident), AssocItemKind::MacCall(..) => return self.visit_macro_invoc(i.id), }; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 1ad4fb78e0820..e225259de7657 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -45,7 +45,6 @@ use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; use rustc_session::Session; use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency}; -use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym}; use rustc_span::{Span, DUMMY_SP}; @@ -59,6 +58,7 @@ use diagnostics::{ImportSuggestion, Suggestion}; use imports::{Import, ImportKind, ImportResolver, NameResolution}; use late::{HasGenericParams, PathSource, Rib, RibKind::*}; use macros::{MacroRulesBinding, MacroRulesScope}; +use rustc_span::source_map::Spanned; type Res = def::Res; diff --git a/src/test/rustdoc/auxiliary/raw-foreign.rs b/src/test/rustdoc/auxiliary/raw-foreign.rs new file mode 100644 index 0000000000000..24a747cd351c6 --- /dev/null +++ b/src/test/rustdoc/auxiliary/raw-foreign.rs @@ -0,0 +1,6 @@ +pub mod r#try { + // @has raw_idents/try/struct.struct.html + pub struct r#struct; + + pub trait r#trait {} +} diff --git a/src/test/rustdoc/raw_idents.rs b/src/test/rustdoc/raw_idents.rs new file mode 100644 index 0000000000000..7d1e02bc765e3 --- /dev/null +++ b/src/test/rustdoc/raw_idents.rs @@ -0,0 +1,14 @@ +// aux-build:raw-foreign.rs +// build-aux-docs + +extern crate raw_foreign; + +// has 'raw_idents/trait.MyTrait.html' '//a[@href="../raw_foreign/try/trait.trait.html"]' 'trait' +// has 'raw_idents/trait.MyTrait.html' '//a[@href="../raw_foreign/try/struct.struct.html"]' 'struct' +pub trait MyTrait { + fn foo() where T: raw_foreign::r#try::r#trait {} +} + +impl MyTrait for raw_foreign::r#try::r#struct { + fn foo() where T: raw_foreign::r#try::r#trait {} +} diff --git a/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr b/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr index 56746c04f5cd7..e120583c77bbb 100644 --- a/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr +++ b/src/test/ui/consts/const-eval/feature-gate-const_panic.stderr @@ -1,17 +1,17 @@ error[E0658]: panicking in constants is unstable - --> $DIR/feature-gate-const_panic.rs:3:15 + --> $DIR/feature-gate-const_panic.rs:6:15 | -LL | const Z: () = panic!("cheese"); - | ^^^^^^^^^^^^^^^^ +LL | const Y: () = unreachable!(); + | ^^^^^^^^^^^^^^ | = note: see issue #51999 for more information = help: add `#![feature(const_panic)]` to the crate attributes to enable = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: panicking in constants is unstable - --> $DIR/feature-gate-const_panic.rs:9:15 + --> $DIR/feature-gate-const_panic.rs:3:15 | -LL | const X: () = unimplemented!(); +LL | const Z: () = panic!("cheese"); | ^^^^^^^^^^^^^^^^ | = note: see issue #51999 for more information @@ -19,10 +19,10 @@ LL | const X: () = unimplemented!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: panicking in constants is unstable - --> $DIR/feature-gate-const_panic.rs:6:15 + --> $DIR/feature-gate-const_panic.rs:9:15 | -LL | const Y: () = unreachable!(); - | ^^^^^^^^^^^^^^ +LL | const X: () = unimplemented!(); + | ^^^^^^^^^^^^^^^^ | = note: see issue #51999 for more information = help: add `#![feature(const_panic)]` to the crate attributes to enable diff --git a/src/test/ui/copy-a-resource.stderr b/src/test/ui/copy-a-resource.stderr index c95e8d239d2b9..a5c961a061acb 100644 --- a/src/test/ui/copy-a-resource.stderr +++ b/src/test/ui/copy-a-resource.stderr @@ -6,6 +6,14 @@ LL | struct Foo { ... LL | let _y = x.clone(); | ^^^^^ method not found in `Foo` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc` here + | the method is available for `std::rc::Rc` here | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.stderr b/src/test/ui/derives/derive-assoc-type-not-impl.stderr index c4c85773fbc1d..be446feb847eb 100644 --- a/src/test/ui/derives/derive-assoc-type-not-impl.stderr +++ b/src/test/ui/derives/derive-assoc-type-not-impl.stderr @@ -12,6 +12,14 @@ LL | struct NotClone; ... LL | Bar:: { x: 1 }.clone(); | ^^^^^ method not found in `Bar` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc>` here + | the method is available for `std::rc::Rc>` here | = note: the method `clone` exists but the following trait bounds were not satisfied: `NotClone: std::clone::Clone` diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr index f5b41cd1cc0bb..8bf245648f84b 100644 --- a/src/test/ui/error-codes/E0004-2.stderr +++ b/src/test/ui/error-codes/E0004-2.stderr @@ -3,6 +3,14 @@ error[E0004]: non-exhaustive patterns: `None` and `Some(_)` not covered | LL | match x { } | ^ patterns `None` and `Some(_)` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | None, + | ---- not covered +... +LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), + | ---- not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/error-codes/E0005.stderr b/src/test/ui/error-codes/E0005.stderr index 577c6e886d523..5028405e731a3 100644 --- a/src/test/ui/error-codes/E0005.stderr +++ b/src/test/ui/error-codes/E0005.stderr @@ -3,6 +3,11 @@ error[E0005]: refutable pattern in local binding: `None` not covered | LL | let Some(y) = x; | ^^^^^^^ pattern `None` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | None, + | ---- not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html diff --git a/src/test/ui/error-codes/E0297.stderr b/src/test/ui/error-codes/E0297.stderr index f356a5b954d6d..e25fb09f15757 100644 --- a/src/test/ui/error-codes/E0297.stderr +++ b/src/test/ui/error-codes/E0297.stderr @@ -3,6 +3,11 @@ error[E0005]: refutable pattern in `for` loop binding: `None` not covered | LL | for Some(x) in xs {} | ^^^^^^^ pattern `None` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | None, + | ---- not covered error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr index 08c36cece4cf9..3334e47019494 100644 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr @@ -3,6 +3,11 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered | LL | let Ok(_x) = foo(); | ^^^^^^ pattern `Err(_)` not covered + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), + | --- not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html diff --git a/src/test/ui/generic-associated-types/iterable.stderr b/src/test/ui/generic-associated-types/iterable.stderr index ccb1c9bcc7f4e..b5bc0c76c2fc5 100644 --- a/src/test/ui/generic-associated-types/iterable.stderr +++ b/src/test/ui/generic-associated-types/iterable.stderr @@ -5,6 +5,11 @@ LL | impl Iterable for Vec { | --------------------------- in this `impl` item LL | type Item<'a> where T: 'a = as Iterator>::Item; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type + | + ::: $SRC_DIR/libcore/iter/traits/iterator.rs:LL:COL + | +LL | type Item; + | ---- associated type defined here | = note: expected reference `&T` found associated type ` as Iterable>::Item<'_>` @@ -18,6 +23,11 @@ LL | impl Iterable for [T] { | ------------------------ in this `impl` item LL | type Item<'a> where T: 'a = as Iterator>::Item; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type + | + ::: $SRC_DIR/libcore/iter/traits/iterator.rs:LL:COL + | +LL | type Item; + | ---- associated type defined here | = note: expected reference `&T` found associated type `<[T] as Iterable>::Item<'_>` diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index c0ca341385df5..b5135b53e1890 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -83,6 +83,16 @@ error[E0599]: no method named `method` found for struct `std::rc::Rc<&mut std::b | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); | ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&i32>>` + | + ::: $DIR/auxiliary/no_method_suggested_traits.rs:8:12 + | +LL | fn method(&self) {} + | ------ + | | + | the method is available for `std::boxed::Box>>` here + | the method is available for `std::pin::Pin>>` here + | the method is available for `std::sync::Arc>>` here + | the method is available for `std::rc::Rc>>` here | = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: diff --git a/src/test/ui/issues/issue-2823.stderr b/src/test/ui/issues/issue-2823.stderr index aa720fd45895a..0cdc501d56811 100644 --- a/src/test/ui/issues/issue-2823.stderr +++ b/src/test/ui/issues/issue-2823.stderr @@ -6,6 +6,14 @@ LL | struct C { ... LL | let _d = c.clone(); | ^^^^^ method not found in `C` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc` here + | the method is available for `std::rc::Rc` here | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: diff --git a/src/test/ui/issues/issue-69725.stderr b/src/test/ui/issues/issue-69725.stderr index 667383e072a54..d9d61fe66f78e 100644 --- a/src/test/ui/issues/issue-69725.stderr +++ b/src/test/ui/issues/issue-69725.stderr @@ -8,6 +8,14 @@ LL | let _ = Struct::::new().clone(); | LL | pub struct Struct(A); | ------------------------ doesn't satisfy `issue_69725::Struct: std::clone::Clone` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc>` here + | the method is available for `std::rc::Rc>` here | = note: the method `clone` exists but the following trait bounds were not satisfied: `A: std::clone::Clone` diff --git a/src/test/ui/non-copyable-void.stderr b/src/test/ui/non-copyable-void.stderr index 074ed66a26183..78d212f7a7ba7 100644 --- a/src/test/ui/non-copyable-void.stderr +++ b/src/test/ui/non-copyable-void.stderr @@ -3,6 +3,14 @@ error[E0599]: no method named `clone` found for enum `libc::c_void` in the curre | LL | let _z = (*y).clone(); | ^^^^^ method not found in `libc::c_void` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc` here + | the method is available for `std::rc::Rc` here error: aborting due to previous error diff --git a/src/test/ui/noncopyable-class.stderr b/src/test/ui/noncopyable-class.stderr index 6c3c4a6ac9888..994eb65ae15bf 100644 --- a/src/test/ui/noncopyable-class.stderr +++ b/src/test/ui/noncopyable-class.stderr @@ -6,6 +6,14 @@ LL | struct Foo { ... LL | let _y = x.clone(); | ^^^^^ method not found in `Foo` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc` here + | the method is available for `std::rc::Rc` here | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr index 8521e37d3fddc..5bf491144ae45 100644 --- a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr +++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr @@ -11,6 +11,14 @@ error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered | LL | match Some(Some(North)) { | ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), + | ---- + | | + | not covered + | not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.stderr b/src/test/ui/pattern/usefulness/match-privately-empty.stderr index f79d180a1b8b5..ce2ab34f87d69 100644 --- a/src/test/ui/pattern/usefulness/match-privately-empty.stderr +++ b/src/test/ui/pattern/usefulness/match-privately-empty.stderr @@ -3,6 +3,11 @@ error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not co | LL | match private::DATA { | ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), + | ---- not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr index a06ad5788515c..f7c2772584052 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr @@ -25,6 +25,11 @@ error[E0004]: non-exhaustive patterns: `Some(_)` not covered | LL | match Some(10) { | ^^^^^^^^ pattern `Some(_)` not covered + | + ::: $SRC_DIR/libcore/option.rs:LL:COL + | +LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), + | ---- not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr index aa23aed4b425a..a91c4dd35e467 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr @@ -3,6 +3,11 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered | LL | let Ok(x) = res; | ^^^^^ pattern `Err(_)` not covered + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), + | --- not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index d0c278d12d70a..bd6e9d5950272 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -3,8 +3,11 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object | LL | fn bar(_x: Foo) {} | ^^^ the trait `issue_3907::Foo` cannot be made into an object + | + ::: $DIR/auxiliary/issue-3907.rs:2:8 | - = note: the trait cannot be made into an object because associated function `bar` has no `self` parameter +LL | fn bar(); + | --- the trait cannot be made into an object because associated function `bar` has no `self` parameter error: aborting due to previous error diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr index ccc25a184e946..a214a652a387f 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr @@ -27,6 +27,13 @@ error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covere | LL | match x {} | ^ patterns `Tuple(_)` and `Struct { .. }` not covered + | + ::: $DIR/auxiliary/uninhabited.rs:17:23 + | +LL | #[non_exhaustive] Tuple(!), + | ----- not covered +LL | #[non_exhaustive] Struct { x: ! } + | ------ not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr index a54885c96e5ee..63564e9c3cc8c 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr @@ -27,6 +27,13 @@ error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covere | LL | match x {} | ^ patterns `Tuple(_)` and `Struct { .. }` not covered + | + ::: $DIR/auxiliary/uninhabited.rs:17:23 + | +LL | #[non_exhaustive] Tuple(!), + | ----- not covered +LL | #[non_exhaustive] Struct { x: ! } + | ------ not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index a667e1fe2da3a..e4396afb2dbf5 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -3,6 +3,11 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered | LL | let _ = match x { | ^ pattern `Err(_)` not covered + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), + | --- not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms @@ -46,6 +51,11 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered | LL | let _ = match x { | ^ pattern `Err(_)` not covered + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), + | --- not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms @@ -54,6 +64,11 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered | LL | let Ok(x) = x; | ^^^^^ pattern `Err(_)` not covered + | + ::: $SRC_DIR/libcore/result.rs:LL:COL + | +LL | Err(#[stable(feature = "rust1", since = "1.0.0")] E), + | --- not covered | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr index 01c8e8471aac2..66437611872df 100644 --- a/src/test/ui/union/union-derive-clone.stderr +++ b/src/test/ui/union/union-derive-clone.stderr @@ -21,6 +21,14 @@ LL | struct CloneNoCopy; ... LL | let w = u.clone(); | ^^^^^ method not found in `U5` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc>` here + | the method is available for `std::rc::Rc>` here | = note: the method `clone` exists but the following trait bounds were not satisfied: `CloneNoCopy: std::marker::Copy` diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr index fb78095224b90..2e81e7cf83200 100644 --- a/src/test/ui/unique-object-noncopyable.stderr +++ b/src/test/ui/unique-object-noncopyable.stderr @@ -14,6 +14,14 @@ LL | let _z = y.clone(); | LL | pub struct Box(Unique); | ------------------------------------- doesn't satisfy `std::boxed::Box: std::clone::Clone` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc>` here + | the method is available for `std::rc::Rc>` here | = note: the method `clone` exists but the following trait bounds were not satisfied: `dyn Foo: std::marker::Sized` diff --git a/src/test/ui/unique-pinned-nocopy.stderr b/src/test/ui/unique-pinned-nocopy.stderr index ea6575d1d85dc..06c4b95baef56 100644 --- a/src/test/ui/unique-pinned-nocopy.stderr +++ b/src/test/ui/unique-pinned-nocopy.stderr @@ -11,6 +11,14 @@ LL | let _j = i.clone(); | LL | pub struct Box(Unique); | ------------------------------------- doesn't satisfy `std::boxed::Box: std::clone::Clone` + | + ::: $SRC_DIR/libcore/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `std::sync::Arc>` here + | the method is available for `std::rc::Rc>` here | = note: the method `clone` exists but the following trait bounds were not satisfied: `R: std::clone::Clone`