diff options
| author | bors <bors@rust-lang.org> | 2022-04-19 13:10:12 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-04-19 13:10:12 +0000 |
| commit | 4ca19e09d302a4cbde14f9cb1bc109179dc824cd (patch) | |
| tree | b779b25871b429dfaafe1c4de5cc5051333c3689 /compiler | |
| parent | c102c5cfc60203c82460bdde2eecd19ccd8c125b (diff) | |
| parent | 9fad214593e87f151b8f09ff0cda9cd52372d037 (diff) | |
Auto merge of #96214 - Dylan-DPC:rollup-a5b4fow, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #94493 (Improved diagnostic on failure to meet send bound on future in a foreign crate) - #95809 (Fix typo in bootstrap.py) - #96086 (Remove `--extern-location` and all associated code) - #96089 (`alloc`: make `vec!` unavailable under `no_global_oom_handling`) - #96122 (Fix an invalid error for a suggestion to add a slice in pattern-matching) - #96142 (Stop using CRATE_DEF_INDEX outside of metadata encoding.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
39 files changed, 376 insertions, 518 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 765bd877db1..7b7c676c26c 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -1,12 +1,10 @@ use std::collections::hash_map::Entry::*; use rustc_ast::expand::allocator::ALLOCATOR_METHODS; -use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; -use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; use rustc_hir::Node; -use rustc_index::vec::IndexVec; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::exported_symbols::{ metadata_symbol_name, ExportedSymbol, SymbolExportLevel, @@ -277,17 +275,6 @@ fn upstream_monomorphizations_provider( let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default(); - let cnum_stable_ids: IndexVec<CrateNum, Fingerprint> = { - let mut cnum_stable_ids = IndexVec::from_elem_n(Fingerprint::ZERO, cnums.len() + 1); - - for &cnum in cnums.iter() { - cnum_stable_ids[cnum] = - tcx.def_path_hash(DefId { krate: cnum, index: CRATE_DEF_INDEX }).0; - } - - cnum_stable_ids - }; - let drop_in_place_fn_def_id = tcx.lang_items().drop_in_place_fn(); for &cnum in cnums.iter() { @@ -316,7 +303,7 @@ fn upstream_monomorphizations_provider( // If there are multiple monomorphizations available, // we select one deterministically. let other_cnum = *e.get(); - if cnum_stable_ids[other_cnum] > cnum_stable_ids[cnum] { + if tcx.stable_crate_id(other_cnum) > tcx.stable_crate_id(cnum) { e.insert(cnum); } } diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 9cd072c8b4c..cd17726c785 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1,12 +1,11 @@ use crate::snippet::Style; use crate::{ CodeSuggestion, DiagnosticMessage, Level, MultiSpan, Substitution, SubstitutionPart, - SuggestionStyle, ToolMetadata, + SuggestionStyle, }; use rustc_data_structures::stable_map::FxHashMap; use rustc_error_messages::FluentValue; use rustc_lint_defs::{Applicability, LintExpectationId}; -use rustc_serialize::json::Json; use rustc_span::edition::LATEST_STABLE_EDITION; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -554,7 +553,6 @@ impl Diagnostic { msg: msg.into(), style, applicability, - tool_metadata: Default::default(), }); self } @@ -582,7 +580,6 @@ impl Diagnostic { msg: msg.into(), style: SuggestionStyle::CompletelyHidden, applicability, - tool_metadata: Default::default(), }); self } @@ -637,7 +634,6 @@ impl Diagnostic { msg: msg.into(), style, applicability, - tool_metadata: Default::default(), }); self } @@ -680,7 +676,6 @@ impl Diagnostic { msg: msg.into(), style: SuggestionStyle::ShowCode, applicability, - tool_metadata: Default::default(), }); self } @@ -705,7 +700,6 @@ impl Diagnostic { msg: msg.into(), style: SuggestionStyle::ShowCode, applicability, - tool_metadata: Default::default(), }); self } @@ -774,23 +768,6 @@ impl Diagnostic { self } - /// Adds a suggestion intended only for a tool. The intent is that the metadata encodes - /// the suggestion in a tool-specific way, as it may not even directly involve Rust code. - pub fn tool_only_suggestion_with_metadata( - &mut self, - msg: impl Into<DiagnosticMessage>, - applicability: Applicability, - tool_metadata: Json, - ) { - self.push_suggestion(CodeSuggestion { - substitutions: vec![], - msg: msg.into(), - style: SuggestionStyle::CompletelyHidden, - applicability, - tool_metadata: ToolMetadata::new(tool_metadata), - }) - } - pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self { self.span = sp.into(); if let Some(span) = self.span.primary_span() { diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 0139007da42..d680e7fab70 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -14,7 +14,6 @@ use rustc_span::source_map::{FilePathMapping, SourceMap}; use crate::emitter::{Emitter, HumanReadableErrorType}; use crate::registry::Registry; use crate::DiagnosticId; -use crate::ToolMetadata; use crate::{ CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, SubDiagnostic, }; @@ -30,7 +29,6 @@ use std::sync::{Arc, Mutex}; use std::vec; use rustc_serialize::json::{as_json, as_pretty_json}; -use rustc_serialize::{Encodable, Encoder}; #[cfg(test)] mod tests; @@ -205,8 +203,7 @@ impl Emitter for JsonEmitter { // The following data types are provided just for serialisation. -// NOTE: this has a manual implementation of Encodable which needs to be updated in -// parallel. +#[derive(Encodable)] struct Diagnostic { /// The primary error message. message: String, @@ -218,65 +215,6 @@ struct Diagnostic { children: Vec<Diagnostic>, /// The message as rustc would render it. rendered: Option<String>, - /// Extra tool metadata - tool_metadata: ToolMetadata, -} - -macro_rules! encode_fields { - ( - $enc:expr, // encoder - $idx:expr, // starting field index - $struct:expr, // struct we're serializing - $struct_name:ident, // struct name - [ $($name:ident),+$(,)? ], // fields to encode - [ $($ignore:ident),+$(,)? ] // fields we're skipping - ) => { - { - // Pattern match to make sure all fields are accounted for - let $struct_name { $($name,)+ $($ignore: _,)+ } = $struct; - let mut idx = $idx; - $( - $enc.emit_struct_field( - stringify!($name), - idx == 0, - |enc| $name.encode(enc), - )?; - idx += 1; - )+ - idx - } - }; -} - -// Special-case encoder to skip tool_metadata if not set -impl<E: Encoder> Encodable<E> for Diagnostic { - fn encode(&self, s: &mut E) -> Result<(), E::Error> { - s.emit_struct(false, |s| { - let mut idx = 0; - - idx = encode_fields!( - s, - idx, - self, - Self, - [message, code, level, spans, children, rendered], - [tool_metadata] - ); - if self.tool_metadata.is_set() { - idx = encode_fields!( - s, - idx, - self, - Self, - [tool_metadata], - [message, code, level, spans, children, rendered] - ); - } - - let _ = idx; - Ok(()) - }) - } } #[derive(Encodable)] @@ -380,7 +318,6 @@ impl Diagnostic { spans: DiagnosticSpan::from_suggestion(sugg, &args, je), children: vec![], rendered: None, - tool_metadata: sugg.tool_metadata.clone(), } }); @@ -428,7 +365,6 @@ impl Diagnostic { .chain(sugg) .collect(), rendered: Some(output), - tool_metadata: ToolMetadata::default(), } } @@ -449,7 +385,6 @@ impl Diagnostic { .unwrap_or_else(|| DiagnosticSpan::from_multispan(&diag.span, args, je)), children: vec![], rendered: None, - tool_metadata: ToolMetadata::default(), } } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index d7c5df7d8e2..339bcc24751 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -36,13 +36,11 @@ pub use rustc_error_messages::{ LazyFallbackBundle, MultiSpan, SpanLabel, DEFAULT_LOCALE_RESOURCES, }; pub use rustc_lint_defs::{pluralize, Applicability}; -use rustc_serialize::json::Json; -use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::source_map::SourceMap; use rustc_span::{Loc, Span}; use std::borrow::Cow; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; use std::num::NonZeroUsize; use std::panic; use std::path::Path; @@ -93,39 +91,6 @@ impl SuggestionStyle { } } -#[derive(Clone, Debug, PartialEq, Default)] -pub struct ToolMetadata(pub Option<Json>); - -impl ToolMetadata { - fn new(json: Json) -> Self { - ToolMetadata(Some(json)) - } - - fn is_set(&self) -> bool { - self.0.is_some() - } -} - -impl Hash for ToolMetadata { - fn hash<H: Hasher>(&self, _state: &mut H) {} -} - -// Doesn't really need to round-trip -impl<D: Decoder> Decodable<D> for ToolMetadata { - fn decode(_d: &mut D) -> Self { - ToolMetadata(None) - } -} - -impl<S: Encoder> Encodable<S> for ToolMetadata { - fn encode(&self, e: &mut S) -> Result<(), S::Error> { - match &self.0 { - None => e.emit_unit(), - Some(json) => json.encode(e), - } - } -} - #[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)] pub struct CodeSuggestion { /// Each substitute can have multiple variants due to multiple @@ -159,8 +124,6 @@ pub struct CodeSuggestion { /// which are useful for users but not useful for /// tools like rustfix pub applicability: Applicability, - /// Tool-specific metadata - pub tool_metadata: ToolMetadata, } #[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)] diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 53d60d280c0..324e1100057 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -1,4 +1,4 @@ -use crate::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use crate::def_id::DefId; use crate::hir; use rustc_ast as ast; @@ -124,9 +124,7 @@ impl DefKind { pub fn descr(self, def_id: DefId) -> &'static str { match self { DefKind::Fn => "function", - DefKind::Mod if def_id.index == CRATE_DEF_INDEX && def_id.krate != LOCAL_CRATE => { - "crate" - } + DefKind::Mod if def_id.is_crate_root() && !def_id.is_local() => "crate", DefKind::Mod => "module", DefKind::Static(..) => "static", DefKind::Enum => "enum", diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 4908992085a..bce9ba12ac0 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -353,11 +353,6 @@ impl Definitions { } } - /// Retrieves the root definition. - pub fn get_root_def(&self) -> LocalDefId { - LocalDefId { local_def_index: CRATE_DEF_INDEX } - } - /// Adds a definition with a parent definition. pub fn create_def( &mut self, diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index 3b5e4dcf5e0..e0ff28dff15 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -1,4 +1,4 @@ -use crate::def_id::{LocalDefId, CRATE_DEF_INDEX}; +use crate::def_id::{LocalDefId, CRATE_DEF_ID}; use std::fmt; /// Uniquely identifies a node in the HIR of the current crate. It is @@ -84,8 +84,5 @@ impl ItemLocalId { pub const INVALID: ItemLocalId = ItemLocalId::MAX; } -/// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_INDEX`. -pub const CRATE_HIR_ID: HirId = HirId { - owner: LocalDefId { local_def_index: CRATE_DEF_INDEX }, - local_id: ItemLocalId::from_u32(0), -}; +/// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`. +pub const CRATE_HIR_ID: HirId = HirId { owner: CRATE_DEF_ID, local_id: ItemLocalId::from_u32(0) }; diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index 8ea47dda928..02f747eeccc 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -18,7 +18,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_feature = { path = "../rustc_feature" } rustc_index = { path = "../rustc_index" } rustc_session = { path = "../rustc_session" } -rustc_serialize = { path = "../rustc_serialize" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_parse_format = { path = "../rustc_parse_format" } rustc_infer = { path = "../rustc_infer" } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 152c53dac7f..0ffa65b79b5 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -33,8 +33,7 @@ use rustc_middle::middle::stability; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, print::Printer, subst::GenericArg, RegisteredTools, Ty, TyCtxt}; -use rustc_serialize::json::Json; -use rustc_session::lint::{BuiltinLintDiagnostics, ExternDepSpec}; +use rustc_session::lint::BuiltinLintDiagnostics; use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId}; use rustc_session::Session; use rustc_span::lev_distance::find_best_match_for_name; @@ -728,30 +727,6 @@ pub trait LintContext: Sized { BuiltinLintDiagnostics::LegacyDeriveHelpers(span) => { db.span_label(span, "the attribute is introduced here"); } - BuiltinLintDiagnostics::ExternDepSpec(krate, loc) => { - let json = match loc { - ExternDepSpec::Json(json) => { - db.help(&format!("remove unnecessary dependency `{}`", krate)); - json - } - ExternDepSpec::Raw(raw) => { - db.help(&format!("remove unnecessary dependency `{}` at `{}`", krate, raw)); - db.span_suggestion_with_style( - DUMMY_SP, - "raw extern location", - raw.clone(), - Applicability::Unspecified, - SuggestionStyle::CompletelyHidden, - ); - Json::String(raw) - } - }; - db.tool_only_suggestion_with_metadata( - "json extern location", - Applicability::Unspecified, - json - ); - } BuiltinLintDiagnostics::ProcMacroBackCompat(note) => { db.note(¬e); } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 4debbf26be6..bde773a32db 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -9,7 +9,6 @@ use rustc_ast::{AttrId, Attribute}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_error_messages::MultiSpan; use rustc_hir::HirId; -use rustc_serialize::json::Json; use rustc_span::edition::Edition; use rustc_span::{sym, symbol::Ident, Span, Symbol}; use rustc_target::spec::abi::Abi; @@ -403,13 +402,6 @@ impl<HCX> ToStableHashKey<HCX> for LintId { } } -// Duplicated from rustc_session::config::ExternDepSpec to avoid cyclic dependency -#[derive(PartialEq, Debug)] -pub enum ExternDepSpec { - Json(Json), - Raw(String), -} - // This could be a closure, but then implementing derive trait // becomes hacky (and it gets allocated). #[derive(Debug)] @@ -428,7 +420,6 @@ pub enum BuiltinLintDiagnostics { UnusedBuiltinAttribute { attr_name: Symbol, macro_name: String, invoc_span: Span }, PatternsInFnsWithoutBody(Span, Ident), LegacyDeriveHelpers(Span), - ExternDepSpec(String, ExternDepSpec), ProcMacroBackCompat(String), OrPatternsBackCompat(Span, String), ReservedPrefix(Span), diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 566d27212d0..e5d0cd28925 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -13,11 +13,10 @@ use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_index::vec::IndexVec; use rustc_middle::ty::TyCtxt; -use rustc_serialize::json::ToJson; use rustc_session::config::{self, CrateType, ExternLocation}; use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate}; use rustc_session::cstore::{ExternCrateSource, MetadataLoaderDyn}; -use rustc_session::lint::{self, BuiltinLintDiagnostics, ExternDepSpec}; +use rustc_session::lint; use rustc_session::output::validate_crate_name; use rustc_session::search_paths::PathKind; use rustc_session::Session; @@ -27,7 +26,6 @@ use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use proc_macro::bridge::client::ProcMacro; -use std::collections::BTreeMap; use std::ops::Fn; use std::path::Path; use std::{cmp, env}; @@ -920,20 +918,7 @@ impl<'a> CrateLoader<'a> { continue; } - let diag = match self.sess.opts.extern_dep_specs.get(name) { - Some(loc) => BuiltinLintDiagnostics::ExternDepSpec(name.clone(), loc.into()), - None => { - // If we don't have a specific location, provide a json encoding of the `--extern` - // option. - let meta: BTreeMap<String, String> = - std::iter::once(("name".to_string(), name.to_string())).collect(); - BuiltinLintDiagnostics::ExternDepSpec( - name.clone(), - ExternDepSpec::Json(meta.to_json()), - ) - } - }; - self.sess.parse_sess.buffer_lint_with_diagnostic( + self.sess.parse_sess.buffer_lint( lint::builtin::UNUSED_CRATE_DEPENDENCIES, span, ast::CRATE_NODE_ID, @@ -942,7 +927,6 @@ impl<'a> CrateLoader<'a> { name, self.local_crate_name, name), - diag, ); } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 611694a0d30..c0f2319f003 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -28,6 +28,7 @@ use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_middle::thir; use rustc_middle::ty::codec::TyDecoder; use rustc_middle::ty::fast_reject::SimplifiedType; +use rustc_middle::ty::GeneratorDiagnosticData; use rustc_middle::ty::{self, Ty, TyCtxt, Visibility}; use rustc_serialize::{opaque, Decodable, Decoder}; use rustc_session::cstore::{ @@ -1725,6 +1726,24 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .collect() }) } + + fn get_generator_diagnostic_data( + self, + tcx: TyCtxt<'tcx>, + id: DefIndex, + ) -> Option<GeneratorDiagnosticData<'tcx>> { + self.root + .tables + .generator_diagnostic_data + .get(self, id) + .map(|param| param.decode((self, tcx))) + .map(|generator_data| GeneratorDiagnosticData { + generator_interior_types: generator_data.generator_interior_types, + hir_owner: generator_data.hir_owner, + nodes_types: generator_data.nodes_types, + adjustments: generator_data.adjustments, + }) + } } impl CrateMetadata { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 63bf929fb86..6a8f1dec0c5 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -5,7 +5,7 @@ use crate::native_libs; use rustc_ast as ast; use rustc_hir::def::{CtorKind, DefKind, Res}; -use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::exported_symbols::ExportedSymbol; @@ -246,6 +246,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, crate_extern_paths => { cdata.source().paths().cloned().collect() } expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) } + generator_diagnostic_data => { cdata.get_generator_diagnostic_data(tcx, def_id.index) } } pub(in crate::rmeta) fn provide(providers: &mut Providers) { @@ -324,7 +325,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { continue; } - bfs_queue.push_back(DefId { krate: cnum, index: CRATE_DEF_INDEX }); + bfs_queue.push_back(cnum.as_def_id()); } let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &ModChild, parent: DefId| { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 6a8d4e03754..066bcb428f6 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1556,16 +1556,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_closure(&mut self, hir_id: hir::HirId) { let def_id = self.tcx.hir().local_def_id(hir_id); debug!("EncodeContext::encode_info_for_closure({:?})", def_id); - // NOTE(eddyb) `tcx.type_of(def_id)` isn't used because it's fully generic, // including on the signature, which is inferred in `typeck. - let ty = self.tcx.typeck(def_id).node_type(hir_id); - + let typeck_result: &'tcx ty::TypeckResults<'tcx> = self.tcx.typeck(def_id); + let ty = typeck_result.node_type(hir_id); match ty.kind() { ty::Generator(..) => { let data = self.tcx.generator_kind(def_id).unwrap(); + let generator_diagnostic_data = typeck_result.get_generator_diagnostic_data(); record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Generator); record!(self.tables.generator_kind[def_id.to_def_id()] <- data); + record!(self.tables.generator_diagnostic_data[def_id.to_def_id()] <- generator_diagnostic_data); } ty::Closure(..) => { @@ -1639,7 +1640,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let hir = tcx.hir(); let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index; - let stability = tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)); + let stability = tcx.lookup_stability(CRATE_DEF_ID); let macros = self.lazy(tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index)); let spans = self.tcx.sess.parse_sess.proc_macro_quoted_spans(); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 43ccfc64e05..e1a1589adb3 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -19,6 +19,7 @@ use rustc_middle::mir; use rustc_middle::thir; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::query::Providers; +use rustc_middle::ty::GeneratorDiagnosticData; use rustc_middle::ty::{self, ReprOptions, Ty}; use rustc_serialize::opaque::Encoder; use rustc_session::config::SymbolManglingVersion; @@ -358,6 +359,7 @@ define_tables! { def_keys: Table<DefIndex, Lazy<DefKey>>, def_path_hashes: Table<DefIndex, DefPathHash>, proc_macro_quoted_spans: Table<usize, Lazy<Span>>, + generator_diagnostic_data: Table<DefIndex, Lazy<GeneratorDiagnosticData<'tcx>>>, } #[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)] diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index d20be0a34d2..8402ca3028c 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -60,7 +60,7 @@ use crate::mir::mono::MonoItem; use crate::ty::TyCtxt; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_hir::definitions::DefPathHash; use rustc_hir::HirId; use rustc_query_system::dep_graph::FingerprintStyle; @@ -366,7 +366,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for CrateNum { #[inline(always)] fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX }; + let def_id = self.as_def_id(); def_id.to_fingerprint(tcx) } diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index fd6e241346d..758658c3d8c 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -11,7 +11,7 @@ use rustc_errors::{Applicability, Diagnostic}; use rustc_feature::GateIssue; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self, HirId}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE}; @@ -370,8 +370,7 @@ impl<'tcx> TyCtxt<'tcx> { }; } - let is_staged_api = - self.lookup_stability(DefId { index: CRATE_DEF_INDEX, ..def_id }).is_some(); + let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some(); if !is_staged_api { return EvalResult::Allow; } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 49769b7ae3d..4f4b6cf704f 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -15,7 +15,7 @@ use crate::ty::{AdtDef, InstanceDef, Region, ScalarInt, UserTypeAnnotationIndex} use rustc_errors::ErrorGuaranteed; use rustc_hir::def::{CtorKind, Namespace}; -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_hir::{self, GeneratorKind}; use rustc_hir::{self as hir, HirId}; use rustc_session::Session; @@ -385,7 +385,7 @@ impl<'tcx> Body<'tcx> { pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self { let mut body = Body { phase: MirPhase::Built, - source: MirSource::item(DefId::local(CRATE_DEF_INDEX)), + source: MirSource::item(CRATE_DEF_ID.to_def_id()), basic_blocks, source_scopes: IndexVec::new(), generator: None, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 999cb9f30b8..78a33832433 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1969,4 +1969,10 @@ rustc_queries! { eval_always desc { "computing the backend features for CLI flags" } } + + query generator_diagnostic_data(key: DefId) -> Option<GeneratorDiagnosticData<'tcx>> { + storage(ArenaCacheSelector<'tcx>) + desc { |tcx| "looking up generator diagnostic data of `{}`", tcx.def_path_str(key) } + separate_provide_extern + } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4e6be84ad7f..30fe3ffa7e3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -367,6 +367,16 @@ pub struct GeneratorInteriorTypeCause<'tcx> { pub expr: Option<hir::HirId>, } +// This type holds diagnostic information on generators and async functions across crate boundaries +// and is used to provide better error messages +#[derive(TyEncodable, TyDecodable, Clone, Debug, HashStable)] +pub struct GeneratorDiagnosticData<'tcx> { + pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>, + pub hir_owner: DefId, + pub nodes_types: ItemLocalMap<Ty<'tcx>>, + pub adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>, +} + #[derive(TyEncodable, TyDecodable, Debug, HashStable)] pub struct TypeckResults<'tcx> { /// The `HirId::owner` all `ItemLocalId`s in this table are relative to. @@ -623,6 +633,28 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types } } + pub fn get_generator_diagnostic_data(&self) -> GeneratorDiagnosticData<'tcx> { + let generator_interior_type = self.generator_interior_types.map_bound_ref(|vec| { + vec.iter() + .map(|item| { + GeneratorInteriorTypeCause { + ty: item.ty, + span: item.span, + scope_span: item.scope_span, + yield_span: item.yield_span, + expr: None, //FIXME: Passing expression over crate boundaries is impossible at the moment + } + }) + .collect::<Vec<_>>() + }); + GeneratorDiagnosticData { + generator_interior_types: generator_interior_type, + hir_owner: self.hir_owner.to_def_id(), + nodes_types: self.node_types.clone(), + adjustments: self.adjustments.clone(), + } + } + pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> { self.node_type_opt(id).unwrap_or_else(|| { bug!("node_type: no type for node `{}`", tls::with(|tcx| tcx.hir().node_to_string(id))) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c2accea11ba..d59fdf47904 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -36,7 +36,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; -use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, CRATE_DEF_ID}; use rustc_hir::Node; use rustc_macros::HashStable; use rustc_query_system::ich::StableHashingContext; @@ -67,8 +67,9 @@ pub use self::consts::{ }; pub use self::context::{ tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, - CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorInteriorTypeCause, GlobalCtxt, - Lift, OnDiskCache, TyCtxt, TypeckResults, UserType, UserTypeAnnotationIndex, + CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorDiagnosticData, + GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType, + UserTypeAnnotationIndex, }; pub use self::instance::{Instance, InstanceDef}; pub use self::list::List; @@ -319,7 +320,7 @@ impl Visibility { pub fn from_hir(visibility: &hir::Visibility<'_>, id: hir::HirId, tcx: TyCtxt<'_>) -> Self { match visibility.node { hir::VisibilityKind::Public => Visibility::Public, - hir::VisibilityKind::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)), + hir::VisibilityKind::Crate(_) => Visibility::Restricted(CRATE_DEF_ID.to_def_id()), hir::VisibilityKind::Restricted { ref path, .. } => match path.res { // If there is no resolution, `resolve` will have already reported an error, so // assume that the visibility is public to avoid reporting more privacy errors. @@ -1992,8 +1993,8 @@ impl<'tcx> TyCtxt<'tcx> { } fn opt_item_name(self, def_id: DefId) -> Option<Symbol> { - if def_id.index == CRATE_DEF_INDEX { - Some(self.crate_name(def_id.krate)) + if let Some(cnum) = def_id.as_crate_root() { + Some(self.crate_name(cnum)) } else { let def_key = self.def_key(def_id); match def_key.disambiguated_data.data { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index cac46ba25fe..38362a4cbb9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sso::SsoHashSet; use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; -use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; use rustc_session::config::TrimmedDefPaths; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; @@ -335,9 +335,7 @@ pub trait PrettyPrinter<'tcx>: // If `def_id` is a direct or injected extern crate, return the // path to the crate followed by the path to the item within the crate. - if def_id.index == CRATE_DEF_INDEX { - let cnum = def_id.krate; - + if let Some(cnum) = def_id.as_crate_root() { if cnum == LOCAL_CRATE { return Ok((self.path_crate(cnum)?, true)); } @@ -2227,11 +2225,11 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { ty::BrNamed(_, _) => br.kind, ty::BrAnon(i) => { let name = region_map[&(i + 1)]; - ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name) + ty::BrNamed(CRATE_DEF_ID.to_def_id(), name) } ty::BrEnv => { let name = region_map[&0]; - ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name) + ty::BrNamed(CRATE_DEF_ID.to_def_id(), name) } }; self.tcx.mk_region(ty::ReLateBound( @@ -2257,7 +2255,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { } }; do_continue(&mut self, name); - ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name) + ty::BrNamed(CRATE_DEF_ID.to_def_id(), name) } }; tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind })) @@ -2697,7 +2695,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N let mut seen_defs: DefIdSet = Default::default(); for &cnum in tcx.crates(()).iter() { - let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX }; + let def_id = cnum.as_def_id(); // Ignore crates that are not direct dependencies. match tcx.extern_crate(def_id) { diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 9e48c569c25..7629d7a8259 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -31,8 +31,11 @@ use crate::traits::{self, ImplSource}; use crate::ty::fast_reject::SimplifiedType; use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::util::AlwaysRequiresDrop; +use crate::ty::GeneratorDiagnosticData; use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; +use rustc_ast as ast; use rustc_ast::expand::allocator::AllocatorKind; +use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; @@ -49,13 +52,10 @@ use rustc_session::cstore::{CrateDepKind, CrateSource}; use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib}; use rustc_session::utils::NativeLibKind; use rustc_session::Limits; -use rustc_target::abi; -use rustc_target::spec::PanicStrategy; - -use rustc_ast as ast; -use rustc_attr as attr; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; +use rustc_target::abi; +use rustc_target::spec::PanicStrategy; use std::ops::Deref; use std::path::PathBuf; use std::sync::Arc; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 5c7910db362..4ef6ff1835f 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -10,7 +10,6 @@ use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt}; use rustc_data_structures::functor::IdFunctor; use rustc_hir as hir; use rustc_hir::def::Namespace; -use rustc_hir::def_id::CRATE_DEF_INDEX; use rustc_index::vec::{Idx, IndexVec}; use std::fmt; @@ -71,7 +70,7 @@ impl fmt::Debug for ty::BoundRegionKind { match *self { ty::BrAnon(n) => write!(f, "BrAnon({:?})", n), ty::BrNamed(did, name) => { - if did.index == CRATE_DEF_INDEX { + if did.is_crate_root() { write!(f, "BrNamed({})", name) } else { write!(f, "BrNamed({:?}, {})", did, name) diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index c4ffb19f87a..16774198879 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -2,7 +2,7 @@ use std::collections::hash_map::Entry; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathDataName; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::exported_symbols::SymbolExportLevel; @@ -335,10 +335,10 @@ fn compute_codegen_unit_name( let mut cgu_def_id = None; // Walk backwards from the item we want to find the module for. loop { - if current_def_id.index == CRATE_DEF_INDEX { + if current_def_id.is_crate_root() { if cgu_def_id.is_none() { // If we have not found a module yet, take the crate root. - cgu_def_id = Some(DefId { krate: def_id.krate, index: CRATE_DEF_INDEX }); + cgu_def_id = Some(def_id.krate.as_def_id()); } break; } else if tcx.def_kind(current_def_id) == DefKind::Mod { diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 5a1373ad1a2..db083d0453b 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -1,21 +1,18 @@ use rustc_ast::entry::EntryPointType; use rustc_errors::struct_span_err; -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::{ForeignItem, ImplItem, Item, ItemKind, Node, TraitItem, CRATE_HIR_ID}; -use rustc_middle::hir::map::Map; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{DefIdTree, TyCtxt}; use rustc_session::config::{CrateType, EntryFnType}; use rustc_session::parse::feature_err; use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::{Span, DUMMY_SP}; -struct EntryContext<'a, 'tcx> { - session: &'a Session, - - map: Map<'tcx>, +struct EntryContext<'tcx> { + tcx: TyCtxt<'tcx>, /// The function that has attribute named `main`. attr_main_fn: Option<(LocalDefId, Span)>, @@ -28,10 +25,9 @@ struct EntryContext<'a, 'tcx> { non_main_fns: Vec<Span>, } -impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> { +impl<'tcx> ItemLikeVisitor<'tcx> for EntryContext<'tcx> { fn visit_item(&mut self, item: &'tcx Item<'tcx>) { - let def_key = self.map.def_key(item.def_id); - let at_root = def_key.parent == Some(CRATE_DEF_INDEX); + let at_root = self.tcx.local_parent(item.def_id) == Some(CRATE_DEF_ID); find_item(item, self, at_root); } @@ -60,13 +56,8 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { return None; } - let mut ctxt = EntryContext { - session: tcx.sess, - map: tcx.hir(), - attr_main_fn: None, - start_fn: None, - non_main_fns: Vec::new(), - }; + let mut ctxt = + EntryContext { tcx, attr_main_fn: None, start_fn: None, non_main_fns: Vec::new() }; tcx.hir().visit_all_item_likes(&mut ctxt); @@ -75,11 +66,11 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { // Beware, this is duplicated in `librustc_builtin_macros/test_harness.rs` // (with `ast::Item`), so make sure to keep them in sync. -fn entry_point_type(ctxt: &EntryContext<'_, '_>, item: &Item<'_>, at_root: bool) -> EntryPointType { - let attrs = ctxt.map.attrs(item.hir_id()); - if ctxt.session.contains_name(attrs, sym::start) { +fn entry_point_type(ctxt: &EntryContext<'_>, item: &Item<'_>, at_root: bool) -> EntryPointType { + let attrs = ctxt.tcx.hir().attrs(item.hir_id()); + if ctxt.tcx.sess.contains_name(attrs, sym::start) { EntryPointType::Start - } else if ctxt.session.contains_name(attrs, sym::rustc_main) { + } else if ctxt.tcx.sess.contains_name(attrs, sym::rustc_main) { EntryPointType::MainAttr } else if item.ident.name == sym::main { if at_root { @@ -98,16 +89,16 @@ fn throw_attr_err(sess: &Session, span: Span, attr: &str) { .emit(); } -fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) { +fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_>, at_root: bool) { match entry_point_type(ctxt, item, at_root) { EntryPointType::None => (), _ if !matches!(item.kind, ItemKind::Fn(..)) => { - let attrs = ctxt.map.attrs(item.hir_id()); - if let Some(attr) = ctxt.session.find_by_name(attrs, sym::start) { - throw_attr_err(&ctxt.session, attr.span, "start"); + let attrs = ctxt.tcx.hir().attrs(item.hir_id()); + if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym::start) { + throw_attr_err(&ctxt.tcx.sess, attr.span, "start"); } - if let Some(attr) = ctxt.session.find_by_name(attrs, sym::rustc_main) { - throw_attr_err(&ctxt.session, attr.span, "rustc_main"); + if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym::rustc_main) { + throw_attr_err(&ctxt.tcx.sess, attr.span, "rustc_main"); } } EntryPointType::MainNamed => (), @@ -119,7 +110,7 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) { ctxt.attr_main_fn = Some((item.def_id, item.span)); } else { struct_span_err!( - ctxt.session, + ctxt.tcx.sess, item.span, E0137, "multiple functions with a `#[main]` attribute" @@ -133,7 +124,7 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) { if ctxt.start_fn.is_none() { ctxt.start_fn = Some((item.def_id, item.span)); } else { - struct_span_err!(ctxt.session, item.span, E0138, "multiple `start` functions") + struct_span_err!(ctxt.tcx.sess, item.span, E0138, "multiple `start` functions") .span_label(ctxt.start_fn.unwrap().1, "previous `#[start]` function here") .span_label(item.span, "multiple `start` functions") .emit(); @@ -142,7 +133,7 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) { } } -fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(DefId, EntryFnType)> { +fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> { if let Some((def_id, _)) = visitor.start_fn { Some((def_id.to_def_id(), EntryFnType::Start)) } else if let Some((def_id, _)) = visitor.attr_main_fn { @@ -177,7 +168,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De } } -fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) { +fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) { let sp = tcx.def_span(CRATE_DEF_ID); if *tcx.sess.parse_sess.reached_eof.borrow() { // There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 56755d68686..379a6827c8a 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -1,7 +1,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lock; use rustc_hir as hir; -use rustc_hir::def_id::{LocalDefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::intravisit; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::{HirId, ItemLocalId}; @@ -89,7 +89,7 @@ impl<'a, 'hir> HirIdValidator<'a, 'hir> { self.owner = Some(owner); walk(self); - if owner.local_def_index == CRATE_DEF_INDEX { + if owner == CRATE_DEF_ID { return; } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 01ba9e35c24..35a858cb86c 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::hir_id::CRATE_HIR_ID; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{FieldDef, Generics, HirId, Item, TraitRef, Ty, TyKind, Variant}; @@ -703,7 +703,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { let Some(cnum) = self.tcx.extern_mod_stmt_cnum(item.def_id) else { return; }; - let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX }; + let def_id = cnum.as_def_id(); self.tcx.check_stability(def_id, Some(item.hir_id()), item.span, None); } diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index acccf43f062..b20aa7b5346 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -1,7 +1,7 @@ use measureme::{StringComponent, StringId}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfiler; -use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; use rustc_middle::ty::{TyCtxt, WithOptConstParam}; use rustc_query_system::query::QueryCache; @@ -143,7 +143,7 @@ impl SpecIntoSelfProfilingString for CrateNum { &self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>, ) -> StringId { - builder.def_id_to_string_id(DefId { krate: *self, index: CRATE_DEF_INDEX }) + builder.def_id_to_string_id(self.as_def_id()) } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 063b15e643d..d97d9199b77 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -23,7 +23,7 @@ use rustc_errors::{struct_span_err, Applicability}; use rustc_expand::base::SyntaxExtension; use rustc_expand::expand::AstFragment; use rustc_hir::def::{self, *}; -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_metadata::creader::LoadedMacro; use rustc_middle::bug; use rustc_middle::metadata::ModChild; @@ -140,8 +140,8 @@ impl<'a> Resolver<'a> { let parent = def_key.parent.map(|index| { self.get_nearest_non_block_module(DefId { index, krate: def_id.krate }) }); - let name = if def_id.index == CRATE_DEF_INDEX { - self.cstore().crate_name(def_id.krate) + let name = if let Some(cnum) = def_id.as_crate_root() { + self.cstore().crate_name(cnum) } else { def_key.disambiguated_data.data.get_opt_name().expect("module without name") }; @@ -250,7 +250,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { match vis.kind { ast::VisibilityKind::Public => Ok(ty::Visibility::Public), ast::VisibilityKind::Crate(..) => { - Ok(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))) + Ok(ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())) } ast::VisibilityKind::Inherited => { Ok(match self.parent_scope.module.kind { @@ -758,7 +758,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let mut ctor_vis = if vis == ty::Visibility::Public && self.r.session.contains_name(&item.attrs, sym::non_exhaustive) { - ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)) + ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) } else { vis }; @@ -1107,7 +1107,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { root_span: span, span, module_path: Vec::new(), - vis: Cell::new(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))), + vis: Cell::new(ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())), used: Cell::new(false), }) }; @@ -1243,7 +1243,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let vis = if is_macro_export { ty::Visibility::Public } else { - ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)) + ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) }; let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas); self.r.set_binding_parent_module(binding, parent_scope.module); @@ -1489,7 +1489,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { let ctor_vis = if vis == ty::Visibility::Public && self.r.session.contains_name(&variant.attrs, sym::non_exhaustive) { - ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)) + ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) } else { vis }; diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index f3b8c1e266c..899980a4c08 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -10,7 +10,7 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS}; -use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::PrimTy; use rustc_middle::bug; use rustc_middle::ty::DefIdTree; @@ -1167,7 +1167,7 @@ impl<'a> Resolver<'a> { } Scope::ExternPrelude => { suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| { - let res = Res::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX)); + let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id()); filter_fn(res).then_some(TypoSuggestion::typo_from_res(ident.name, res)) })); } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 9bc5d63ca17..591bad70840 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -19,7 +19,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::DiagnosticId; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS}; -use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::{PrimTy, TraitCandidate}; use rustc_middle::ty::DefIdTree; use rustc_middle::{bug, span_bug}; @@ -2751,7 +2751,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // trait to resolve. In that case, we leave the `B` // segment to be resolved by type-check. return Ok(Some(PartialRes::with_unresolved_segments( - Res::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX)), + Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id()), path.len(), ))); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0bae141ce26..d77cc917e2f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -20,7 +20,7 @@ use rustc_errors::{ use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind}; -use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::PrimTy; use rustc_session::parse::feature_err; use rustc_span::edition::Edition; @@ -352,7 +352,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } }) .collect::<Vec<_>>(); - let crate_def_id = DefId::local(CRATE_DEF_INDEX); + let crate_def_id = CRATE_DEF_ID.to_def_id(); if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) { let mut enum_candidates: Vec<_> = self .r @@ -1332,10 +1332,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { names.extend(extern_prelude.iter().flat_map(|(ident, _)| { self.r.crate_loader.maybe_process_path_extern(ident.name).and_then( |crate_id| { - let crate_mod = Res::Def( - DefKind::Mod, - DefId { krate: crate_id, index: CRATE_DEF_INDEX }, - ); + let crate_mod = + Res::Def(DefKind::Mod, crate_id.as_def_id()); if filter_fn(crate_mod) { Some(TypoSuggestion::typo_from_res( diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index eed54370e23..4dfb7aef86f 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -38,7 +38,7 @@ use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind use rustc_hir::def::Namespace::*; use rustc_hir::def::{self, CtorOf, DefKind, PartialRes}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefPathHash, LocalDefId}; -use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPathData, Definitions}; use rustc_hir::TraitCandidate; use rustc_index::vec::IndexVec; @@ -796,7 +796,7 @@ impl<'a> NameBinding<'a> { NameBindingKind::Module(&ModuleData { kind: ModuleKind::Def(DefKind::Mod, def_id, _), .. - }) => def_id.index == CRATE_DEF_INDEX, + }) => def_id.is_crate_root(), _ => false, } } @@ -1248,18 +1248,17 @@ impl<'a> Resolver<'a> { ); let definitions = Definitions::new(session.local_stable_crate_id(), krate.spans.inner_span); - let root = definitions.get_root_def(); let mut visibilities = FxHashMap::default(); visibilities.insert(CRATE_DEF_ID, ty::Visibility::Public); let mut def_id_to_node_id = IndexVec::default(); - assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), root); + assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), CRATE_DEF_ID); let mut node_id_to_def_id = FxHashMap::default(); - node_id_to_def_id.insert(CRATE_NODE_ID, root); + node_id_to_def_id.insert(CRATE_NODE_ID, CRATE_DEF_ID); let mut invocation_parents = FxHashMap::default(); - invocation_parents.insert(LocalExpnId::ROOT, (root, ImplTraitContext::Existential)); + invocation_parents.insert(LocalExpnId::ROOT, (CRATE_DEF_ID, ImplTraitContext::Existential)); let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'_>> = session .opts diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 5a447aa6237..86a078f4a38 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -15,8 +15,6 @@ use rustc_target::abi::{Align, TargetDataLayout}; use rustc_target::spec::{LinkerFlavor, SplitDebuginfo, Target, TargetTriple, TargetWarnings}; use rustc_target::spec::{PanicStrategy, SanitizerSet, TARGETS}; -use rustc_serialize::json; - use crate::parse::{CrateCheckConfig, CrateConfig}; use rustc_feature::UnstableFeatures; use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION}; @@ -460,9 +458,6 @@ impl OutputTypes { #[derive(Clone)] pub struct Externs(BTreeMap<String, ExternEntry>); -#[derive(Clone)] -pub struct ExternDepSpecs(BTreeMap<String, ExternDepSpec>); - #[derive(Clone, Debug)] pub struct ExternEntry { pub location: ExternLocation, @@ -494,27 +489,6 @@ pub enum ExternLocation { ExactPaths(BTreeSet<CanonicalizedPath>), } -/// Supplied source location of a dependency - for example in a build specification -/// file like Cargo.toml. We support several syntaxes: if it makes sense to reference -/// a file and line, then the build system can specify that. On the other hand, it may -/// make more sense to have an arbitrary raw string. -#[derive(Clone, PartialEq)] -pub enum ExternDepSpec { - /// Raw string - Raw(String), - /// Raw data in json format - Json(json::Json), -} - -impl<'a> From<&'a ExternDepSpec> for rustc_lint_defs::ExternDepSpec { - fn from(from: &'a ExternDepSpec) -> Self { - match from { - ExternDepSpec::Raw(s) => rustc_lint_defs::ExternDepSpec::Raw(s.clone()), - ExternDepSpec::Json(json) => rustc_lint_defs::ExternDepSpec::Json(json.clone()), - } - } -} - impl Externs { /// Used for testing. pub fn new(data: BTreeMap<String, ExternEntry>) -> Externs { @@ -547,25 +521,6 @@ impl ExternEntry { } } -impl ExternDepSpecs { - pub fn new(data: BTreeMap<String, ExternDepSpec>) -> ExternDepSpecs { - ExternDepSpecs(data) - } - - pub fn get(&self, key: &str) -> Option<&ExternDepSpec> { - self.0.get(key) - } -} - -impl fmt::Display for ExternDepSpec { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ExternDepSpec::Raw(raw) => fmt.write_str(raw), - ExternDepSpec::Json(json) => json::as_json(json).fmt(fmt), - } - } -} - #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum PrintRequest { FileNames, @@ -785,7 +740,6 @@ impl Default for Options { cg: Default::default(), error_format: ErrorOutputType::default(), externs: Externs(BTreeMap::new()), - extern_dep_specs: ExternDepSpecs(BTreeMap::new()), crate_name: None, libs: Vec::new(), unstable_features: UnstableFeatures::Disallow, @@ -1454,12 +1408,6 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> { "Specify where an external rust library is located", "NAME[=PATH]", ), - opt::multi_s( - "", - "extern-location", - "Location where an external crate dependency is specified", - "NAME=LOCATION", - ), opt::opt_s("", "sysroot", "Override the system root", "PATH"), opt::multi("Z", "", "Set internal debugging options", "FLAG"), opt::opt_s( @@ -2221,68 +2169,6 @@ pub fn parse_externs( Externs(externs) } -fn parse_extern_dep_specs( - matches: &getopts::Matches, - debugging_opts: &DebuggingOptions, - error_format: ErrorOutputType, -) -> ExternDepSpecs { - let is_unstable_enabled = debugging_opts.unstable_options; - let mut map = BTreeMap::new(); - - for arg in matches.opt_strs("extern-location") { - if !is_unstable_enabled { - early_error( - error_format, - "`--extern-location` option is unstable: set `-Z unstable-options`", - ); - } - - let mut parts = arg.splitn(2, '='); - let name = parts.next().unwrap_or_else(|| { - early_error(error_format, "`--extern-location` value must not be empty") - }); - let loc = parts.next().unwrap_or_else(|| { - early_error( - error_format, - &format!("`--extern-location`: specify location for extern crate `{name}`"), - ) - }); - - let locparts: Vec<_> = loc.split(':').collect(); - let spec = match &locparts[..] { - ["raw", ..] => { - // Don't want `:` split string - let raw = loc.splitn(2, ':').nth(1).unwrap_or_else(|| { - early_error(error_format, "`--extern-location`: missing `raw` location") - }); - ExternDepSpec::Raw(raw.to_string()) - } - ["json", ..] => { - // Don't want `:` split string - let raw = loc.splitn(2, ':').nth(1).unwrap_or_else(|| { - early_error(error_format, "`--extern-location`: missing `json` location") - }); - let json = json::from_str(raw).unwrap_or_else(|_| { - early_error( - error_format, - &format!("`--extern-location`: malformed json location `{raw}`"), - ) - }); - ExternDepSpec::Json(json) - } - [bad, ..] => early_error( - error_format, - &format!("unknown location type `{bad}`: use `raw` or `json`"), - ), - [] => early_error(error_format, "missing location specification"), - }; - - map.insert(name.to_string(), spec); - } - - ExternDepSpecs::new(map) -} - fn parse_remap_path_prefix( matches: &getopts::Matches, debugging_opts: &DebuggingOptions, @@ -2525,7 +2411,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } let externs = parse_externs(matches, &debugging_opts, error_format); - let extern_dep_specs = parse_extern_dep_specs(matches, &debugging_opts, error_format); let crate_name = matches.opt_str("crate-name"); @@ -2601,7 +2486,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { error_format, externs, unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()), - extern_dep_specs, crate_name, libs, debug_assertions, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 4994f8eaeb2..df65409a8a0 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -183,7 +183,6 @@ top_level_options!( borrowck_mode: BorrowckMode [UNTRACKED], cg: CodegenOptions [SUBSTRUCT], externs: Externs [UNTRACKED], - extern_dep_specs: ExternDepSpecs [UNTRACKED], crate_name: Option<String> [TRACKED], /// Indicates how the compiler should treat unstable features. unstable_features: UnstableFeatures [TRACKED], diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 6d1b36796d8..d5f806308cf 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -283,8 +283,19 @@ impl DefId { self.as_local().unwrap_or_else(|| panic!("DefId::expect_local: `{:?}` isn't local", self)) } + #[inline] + pub fn is_crate_root(self) -> bool { + self.index == CRATE_DEF_INDEX + } + + #[inline] + pub fn as_crate_root(self) -> Option<CrateNum> { + if self.is_crate_root() { Some(self.krate) } else { None } + } + + #[inline] pub fn is_top_level_module(self) -> bool { - self.is_local() && self.index == CRATE_DEF_INDEX + self.is_local() && self.is_crate_root() } } @@ -357,7 +368,7 @@ impl LocalDefId { #[inline] pub fn is_top_level_module(self) -> bool { - self.local_def_index == CRATE_DEF_INDEX + self == CRATE_DEF_ID } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 7485c082f4e..0c1ca65c48f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -19,9 +19,11 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node}; +use rustc_middle::hir::map; use rustc_middle::ty::{ self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree, - Infer, InferTy, ToPredicate, Ty, TyCtxt, TypeFoldable, + GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, ToPredicate, Ty, TyCtxt, + TypeFoldable, }; use rustc_middle::ty::{TypeAndMut, TypeckResults}; use rustc_session::Limit; @@ -44,6 +46,123 @@ pub enum GeneratorInteriorOrUpvar { Upvar(Span), } +// This type provides a uniform interface to retrieve data on generators, whether it originated from +// the local crate being compiled or from a foreign crate. +#[derive(Debug)] +pub enum GeneratorData<'tcx, 'a> { + Local(&'a TypeckResults<'tcx>), + Foreign(&'tcx GeneratorDiagnosticData<'tcx>), +} + +impl<'tcx, 'a> GeneratorData<'tcx, 'a> { + // Try to get information about variables captured by the generator that matches a type we are + // looking for with `ty_matches` function. We uses it to find upvar which causes a failure to + // meet an obligation + fn try_get_upvar_span<F>( + &self, + infer_context: &InferCtxt<'a, 'tcx>, + generator_did: DefId, + ty_matches: F, + ) -> Option<GeneratorInteriorOrUpvar> + where + F: Fn(ty::Binder<'tcx, Ty<'tcx>>) -> bool, + { + match self { + GeneratorData::Local(typeck_results) => { + infer_context.tcx.upvars_mentioned(generator_did).and_then(|upvars| { + upvars.iter().find_map(|(upvar_id, upvar)| { + let upvar_ty = typeck_results.node_type(*upvar_id); + let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty); + if ty_matches(ty::Binder::dummy(upvar_ty)) { + Some(GeneratorInteriorOrUpvar::Upvar(upvar.span)) + } else { + None + } + }) + }) + } + GeneratorData::Foreign(_) => None, + } + } + + // Try to get the span of a type being awaited on that matches the type we are looking with the + // `ty_matches` function. We uses it to find awaited type which causes a failure to meet an + // obligation + fn get_from_await_ty<F>( + &self, + visitor: AwaitsVisitor, + hir: map::Map<'tcx>, + ty_matches: F, + ) -> Option<Span> + where + F: Fn(ty::Binder<'tcx, Ty<'tcx>>) -> bool, + { + match self { + GeneratorData::Local(typeck_results) => visitor + .awaits + .into_iter() + .map(|id| hir.expect_expr(id)) + .find(|await_expr| { + ty_matches(ty::Binder::dummy(typeck_results.expr_ty_adjusted(&await_expr))) + }) + .map(|expr| expr.span), + GeneratorData::Foreign(generator_diagnostic_data) => visitor + .awaits + .into_iter() + .map(|id| hir.expect_expr(id)) + .find(|await_expr| { + ty_matches(ty::Binder::dummy( + generator_diagnostic_data + .adjustments + .get(&await_expr.hir_id.local_id) + .map_or::<&[ty::adjustment::Adjustment<'tcx>], _>(&[], |a| &a[..]) + .last() + .map_or_else::<Ty<'tcx>, _, _>( + || { + generator_diagnostic_data + .nodes_types + .get(&await_expr.hir_id.local_id) + .cloned() + .unwrap_or_else(|| { + bug!( + "node_type: no type for node `{}`", + ty::tls::with(|tcx| tcx + .hir() + .node_to_string(await_expr.hir_id)) + ) + }) + }, + |adj| adj.target, + ), + )) + }) + .map(|expr| expr.span), + } + } + + /// Get the type, expression, span and optional scope span of all types + /// that are live across the yield of this generator + fn get_generator_interior_types( + &self, + ) -> ty::Binder<'tcx, &Vec<GeneratorInteriorTypeCause<'tcx>>> { + match self { + GeneratorData::Local(typeck_result) => typeck_result.generator_interior_types.as_ref(), + GeneratorData::Foreign(generator_diagnostic_data) => { + generator_diagnostic_data.generator_interior_types.as_ref() + } + } + } + + // Used to get the source of the data, note we don't have as much information for generators + // originated from foreign crates + fn is_foreign(&self) -> bool { + match self { + GeneratorData::Local(_) => false, + GeneratorData::Foreign(_) => true, + } + } +} + // This trait is public to expose the diagnostics methods to clippy. pub trait InferCtxtExt<'tcx> { fn suggest_restricting_param_bound( @@ -152,7 +271,7 @@ pub trait InferCtxtExt<'tcx> { err: &mut Diagnostic, interior_or_upvar_span: GeneratorInteriorOrUpvar, interior_extra_info: Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>, - inner_generator_body: Option<&hir::Body<'tcx>>, + is_async: bool, outer_generator: Option<DefId>, trait_pred: ty::TraitPredicate<'tcx>, target_ty: Ty<'tcx>, @@ -1642,6 +1761,17 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { .map(|def_id| hir.local_def_id_to_hir_id(def_id)) .and_then(|hir_id| hir.maybe_body_owned_by(hir_id)) .map(|body_id| hir.body(body_id)); + let is_async = match generator_did.as_local() { + Some(_) => generator_body + .and_then(|body| body.generator_kind()) + .map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..))) + .unwrap_or(false), + None => self + .tcx + .generator_kind(generator_did) + .map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..))) + .unwrap_or(false), + }; let mut visitor = AwaitsVisitor::default(); if let Some(body) = generator_body { visitor.visit_body(body); @@ -1682,61 +1812,55 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // type-checking; otherwise, get them by performing a query. This is needed to avoid // cycles. If we can't use resolved types because the generator comes from another crate, // we still provide a targeted error but without all the relevant spans. - let query_typeck_results; - let typeck_results: Option<&TypeckResults<'tcx>> = match &in_progress_typeck_results { - Some(t) if t.hir_owner.to_def_id() == generator_did_root => Some(&t), + let generator_data: Option<GeneratorData<'tcx, '_>> = match &in_progress_typeck_results { + Some(t) if t.hir_owner.to_def_id() == generator_did_root => { + Some(GeneratorData::Local(&t)) + } _ if generator_did.is_local() => { - query_typeck_results = self.tcx.typeck(generator_did.expect_local()); - Some(&query_typeck_results) + Some(GeneratorData::Local(self.tcx.typeck(generator_did.expect_local()))) } - _ => None, // Do not ICE on closure typeck (#66868). + _ => self + .tcx + .generator_diagnostic_data(generator_did) + .as_ref() + .map(|generator_diag_data| GeneratorData::Foreign(generator_diag_data)), }; - if let Some(typeck_results) = typeck_results { - if let Some(upvars) = self.tcx.upvars_mentioned(generator_did) { - interior_or_upvar_span = upvars.iter().find_map(|(upvar_id, upvar)| { - let upvar_ty = typeck_results.node_type(*upvar_id); - let upvar_ty = self.resolve_vars_if_possible(upvar_ty); - if ty_matches(ty::Binder::dummy(upvar_ty)) { - Some(GeneratorInteriorOrUpvar::Upvar(upvar.span)) - } else { - None - } - }); - }; + + if let Some(generator_data) = generator_data.as_ref() { + interior_or_upvar_span = + generator_data.try_get_upvar_span(&self, generator_did, ty_matches); // The generator interior types share the same binders if let Some(cause) = - typeck_results.generator_interior_types.as_ref().skip_binder().iter().find( + generator_data.get_generator_interior_types().skip_binder().iter().find( |ty::GeneratorInteriorTypeCause { ty, .. }| { - ty_matches(typeck_results.generator_interior_types.rebind(*ty)) + ty_matches(generator_data.get_generator_interior_types().rebind(*ty)) }, ) { - // Check to see if any awaited expressions have the target type. - let from_awaited_ty = visitor - .awaits - .into_iter() - .map(|id| hir.expect_expr(id)) - .find(|await_expr| { - ty_matches(ty::Binder::dummy(typeck_results.expr_ty_adjusted(&await_expr))) - }) - .map(|expr| expr.span); + let from_awaited_ty = generator_data.get_from_await_ty(visitor, hir, ty_matches); let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause; interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(*span)); interior_extra_info = Some((*scope_span, *yield_span, *expr, from_awaited_ty)); - }; - } else { - interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(span)); + } + + if interior_or_upvar_span.is_none() && generator_data.is_foreign() { + interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(span)); + } } if let Some(interior_or_upvar_span) = interior_or_upvar_span { + let typeck_results = generator_data.and_then(|generator_data| match generator_data { + GeneratorData::Local(typeck_results) => Some(typeck_results), + GeneratorData::Foreign(_) => None, + }); self.note_obligation_cause_for_async_await( err, interior_or_upvar_span, interior_extra_info, - generator_body, + is_async, outer_generator, trait_ref, target_ty, @@ -1757,7 +1881,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err: &mut Diagnostic, interior_or_upvar_span: GeneratorInteriorOrUpvar, interior_extra_info: Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>, - inner_generator_body: Option<&hir::Body<'tcx>>, + is_async: bool, outer_generator: Option<DefId>, trait_pred: ty::TraitPredicate<'tcx>, target_ty: Ty<'tcx>, @@ -1767,10 +1891,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ) { let source_map = self.tcx.sess.source_map(); - let is_async = inner_generator_body - .and_then(|body| body.generator_kind()) - .map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..))) - .unwrap_or(false); let (await_or_yield, an_await_or_yield) = if is_async { ("await", "an await") } else { ("yield", "a yield") }; let future_or_generator = if is_async { "future" } else { "generator" }; diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index f3dcf5fff74..cf0c5703cd0 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -2042,63 +2042,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.sess, span, E0529, - "expected an array or slice, found `{}`", - expected_ty + "expected an array or slice, found `{expected_ty}`" ); - if let ty::Ref(_, ty, _) = expected_ty.kind() { - if let ty::Array(..) | ty::Slice(..) = ty.kind() { - err.help("the semantics of slice patterns changed recently; see issue #62254"); - } + if let ty::Ref(_, ty, _) = expected_ty.kind() + && let ty::Array(..) | ty::Slice(..) = ty.kind() + { + err.help("the semantics of slice patterns changed recently; see issue #62254"); } else if Autoderef::new(&self.infcx, self.param_env, self.body_id, span, expected_ty, span) .any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..))) + && let (Some(span), true) = (ti.span, ti.origin_expr) + && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - if let (Some(span), true) = (ti.span, ti.origin_expr) { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - let applicability = Autoderef::new( - &self.infcx, - self.param_env, - self.body_id, - span, - self.resolve_vars_if_possible(ti.expected), + let ty = self.resolve_vars_if_possible(ti.expected); + let is_slice_or_array_or_vector = self.is_slice_or_array_or_vector(&mut err, snippet.clone(), ty); + match is_slice_or_array_or_vector.1.kind() { + ty::Adt(adt_def, _) + if self.tcx.is_diagnostic_item(sym::Option, adt_def.did()) + || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) => + { + // Slicing won't work here, but `.as_deref()` might (issue #91328). + err.span_suggestion( span, - ) - .find_map(|(ty, _)| { - match ty.kind() { - ty::Adt(adt_def, _) - if self.tcx.is_diagnostic_item(sym::Option, adt_def.did()) - || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) => - { - // Slicing won't work here, but `.as_deref()` might (issue #91328). - err.span_suggestion( - span, - "consider using `as_deref` here", - format!("{}.as_deref()", snippet), - Applicability::MaybeIncorrect, - ); - Some(None) - } - - ty::Slice(..) | ty::Array(..) => { - Some(Some(Applicability::MachineApplicable)) - } - - _ => None, - } - }) - .unwrap_or(Some(Applicability::MaybeIncorrect)); - - if let Some(applicability) = applicability { - err.span_suggestion( - span, - "consider slicing here", - format!("{}[..]", snippet), - applicability, - ); - } + "consider using `as_deref` here", + format!("{snippet}.as_deref()"), + Applicability::MaybeIncorrect, + ); } + _ => () + } + if is_slice_or_array_or_vector.0 { + err.span_suggestion( + span, + "consider slicing here", + format!("{snippet}[..]"), + Applicability::MachineApplicable, + ); } } - err.span_label(span, format!("pattern cannot match with input type `{}`", expected_ty)); + err.span_label(span, format!("pattern cannot match with input type `{expected_ty}`")); err.emit(); } + + fn is_slice_or_array_or_vector( + &self, + err: &mut Diagnostic, + snippet: String, + ty: Ty<'tcx>, + ) -> (bool, Ty<'tcx>) { + match ty.kind() { + ty::Adt(adt_def, _) if self.tcx.is_diagnostic_item(sym::Vec, adt_def.did()) => { + (true, ty) + } + ty::Ref(_, ty, _) => self.is_slice_or_array_or_vector(err, snippet, *ty), + ty::Slice(..) | ty::Array(..) => (true, ty), + _ => (false, ty), + } + } } |
