From 1433bfd74594919f38583a51822389d598a2c07f Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 8 Apr 2022 10:41:00 -0400 Subject: [PATCH 1/8] Fix typo in bootstrap.py --- src/bootstrap/bootstrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 0b6bdf474195d..81c239b62130b 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -812,7 +812,7 @@ def rustfmt_stamp(self): return os.path.join(self.bin_root(True), '.rustfmt-stamp') def llvm_stamp(self): - """Return the path for .rustfmt-stamp + """Return the path for .llvm-stamp >>> rb = RustBuild() >>> rb.build_dir = "build" From 1be1157d7551d3664b6f55d5eea85fb08b86761b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 14 Apr 2022 23:07:57 -0700 Subject: [PATCH 2/8] Remove `--extern-location` and all associated code `--extern-location` was an experiment to investigate the best way to generate useful diagnostics for unused dependency warnings by enabling a build system to identify the corresponding build config. While I did successfully use this, I've since been convinced the alternative `--json unused-externs` mechanism is the way to go, and there's no point in having two mechanisms with basically the same functionality. This effectively reverts https://github.com/rust-lang/rust/pull/72603 --- Cargo.lock | 1 - compiler/rustc_errors/src/diagnostic.rs | 25 +--- compiler/rustc_errors/src/json.rs | 67 +--------- compiler/rustc_errors/src/lib.rs | 39 +----- compiler/rustc_lint/Cargo.toml | 1 - compiler/rustc_lint/src/context.rs | 27 +--- compiler/rustc_lint_defs/src/lib.rs | 9 -- compiler/rustc_metadata/src/creader.rs | 20 +-- compiler/rustc_session/src/config.rs | 116 ------------------ compiler/rustc_session/src/options.rs | 1 - .../src/compiler-flags/extern-location.md | 31 ----- .../extern-loc-bad-loctype.rs | 8 -- .../extern-loc-bad-loctype.stderr | 2 - .../unused-crate-deps/extern-loc-defl-json.rs | 10 -- .../extern-loc-defl-json.stderr | 17 --- .../extern-loc-json-bad-json.rs | 8 -- .../extern-loc-json-bad-json.stderr | 2 - .../unused-crate-deps/extern-loc-json-json.rs | 10 -- .../extern-loc-json-json.stderr | 17 --- .../ui/unused-crate-deps/extern-loc-json.rs | 10 -- .../unused-crate-deps/extern-loc-json.stderr | 15 --- .../extern-loc-missing-loc.rs | 8 -- .../extern-loc-missing-loc.stderr | 2 - .../extern-loc-missing-loctype.rs | 8 -- .../extern-loc-missing-loctype.stderr | 2 - .../unused-crate-deps/extern-loc-raw-json.rs | 10 -- .../extern-loc-raw-json.stderr | 17 --- .../extern-loc-raw-missing-loc.rs | 8 -- .../extern-loc-raw-missing-loc.stderr | 2 - .../ui/unused-crate-deps/extern-loc-raw.rs | 10 -- .../unused-crate-deps/extern-loc-raw.stderr | 15 --- src/test/ui/unused-crate-deps/libfib.stderr | 1 - .../unused-crate-deps/unused-aliases.stderr | 1 - .../ui/unused-crate-deps/warn-attr.stderr | 1 - .../warn-cmdline-static.stderr | 1 - .../ui/unused-crate-deps/warn-cmdline.stderr | 1 - 36 files changed, 6 insertions(+), 517 deletions(-) delete mode 100644 src/doc/unstable-book/src/compiler-flags/extern-location.md delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-bad-loctype.stderr delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-defl-json.rs delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-defl-json.stderr delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-json-bad-json.stderr delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-json-json.rs delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-json-json.stderr delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-json.rs delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-json.stderr delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-missing-loc.rs delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-missing-loc.stderr delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-missing-loctype.stderr delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-raw-json.rs delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.stderr delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-raw.rs delete mode 100644 src/test/ui/unused-crate-deps/extern-loc-raw.stderr diff --git a/Cargo.lock b/Cargo.lock index 045fcbac80e2a..074a5cafbc8a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3924,7 +3924,6 @@ dependencies = [ "rustc_infer", "rustc_middle", "rustc_parse_format", - "rustc_serialize", "rustc_session", "rustc_span", "rustc_target", diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index ecb3cdd627cec..2ae599a134bf9 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, - 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>(&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 0139007da4261..d680e7fab7047 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, /// The message as rustc would render it. rendered: Option, - /// 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 Encodable 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 cfad1fc01abb0..9168705bcffae 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); - -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(&self, _state: &mut H) {} -} - -// Doesn't really need to round-trip -impl Decodable for ToolMetadata { - fn decode(_d: &mut D) -> Self { - ToolMetadata(None) - } -} - -impl Encodable 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_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index 8ea47dda928f5..02f747eeccc3e 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 3600b6ad21203..65201bb6e1347 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -32,8 +32,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; @@ -712,30 +711,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 031b01af5dd95..8ac92da9624ee 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 ToStableHashKey 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)] @@ -427,7 +419,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 a9e3b55aeeedf..c8ad4f88a0441 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}; @@ -919,20 +917,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 = - 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, @@ -941,7 +926,6 @@ impl<'a> CrateLoader<'a> { name, self.local_crate_name, name), - diag, ); } } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 5a447aa623734..86a078f4a3858 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); -#[derive(Clone)] -pub struct ExternDepSpecs(BTreeMap); - #[derive(Clone, Debug)] pub struct ExternEntry { pub location: ExternLocation, @@ -494,27 +489,6 @@ pub enum ExternLocation { ExactPaths(BTreeSet), } -/// 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) -> Externs { @@ -547,25 +521,6 @@ impl ExternEntry { } } -impl ExternDepSpecs { - pub fn new(data: BTreeMap) -> 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 { "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 4994f8eaeb2dc..df65409a8a063 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 [TRACKED], /// Indicates how the compiler should treat unstable features. unstable_features: UnstableFeatures [TRACKED], diff --git a/src/doc/unstable-book/src/compiler-flags/extern-location.md b/src/doc/unstable-book/src/compiler-flags/extern-location.md deleted file mode 100644 index 1c80d5426bf75..0000000000000 --- a/src/doc/unstable-book/src/compiler-flags/extern-location.md +++ /dev/null @@ -1,31 +0,0 @@ -# `extern-location` - -MCP for this feature: [#303] - -[#303]: https://github.com/rust-lang/compiler-team/issues/303 - ------------------------- - -The `unused-extern-crates` lint reports when a crate was specified on the rustc -command-line with `--extern name=path` but no symbols were referenced in it. -This is useful to know, but it's hard to map that back to a specific place a user -or tool could fix (ie, to remove the unused dependency). - -The `--extern-location` flag allows the build system to associate a location with -the `--extern` option, which is then emitted as part of the diagnostics. This location -is abstract and just round-tripped through rustc; the compiler never attempts to -interpret it in any way. - -There are two supported forms of location: a bare string, or a blob of json: -- `--extern-location foo=raw:Makefile:123` would associate the raw string `Makefile:123` -- `--extern-location 'bar=json:{"target":"//my_project:library","dep":"//common:serde"}` would - associate the json structure with `--extern bar=`, indicating which dependency of - which rule introduced the unused extern crate. - -This primarily intended to be used with tooling - for example a linter which can automatically -remove unused dependencies - rather than being directly presented to users. - -`raw` locations are presented as part of the normal rendered diagnostics and included in -the json form. `json` locations are only included in the json form of diagnostics, -as a `tool_metadata` field. For `raw` locations `tool_metadata` is simply a json string, -whereas `json` allows the rustc invoker to fully control its form and content. diff --git a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs b/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs deleted file mode 100644 index e69df0359fd91..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs +++ /dev/null @@ -1,8 +0,0 @@ -// --extern-location with bad location type - -// aux-crate:bar=bar.rs -// compile-flags:--extern-location bar=badloc:in-the-test-file -Z unstable-options - -#![warn(unused_crate_dependencies)] - -fn main() {} diff --git a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.stderr b/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.stderr deleted file mode 100644 index 12378f12557b7..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: unknown location type `badloc`: use `raw` or `json` - diff --git a/src/test/ui/unused-crate-deps/extern-loc-defl-json.rs b/src/test/ui/unused-crate-deps/extern-loc-defl-json.rs deleted file mode 100644 index a023f535b8198..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-defl-json.rs +++ /dev/null @@ -1,10 +0,0 @@ -// Default extern location from name and path if one isn't specified - -// check-pass -// aux-crate:bar=bar.rs -// compile-flags:--error-format json - -#![warn(unused_crate_dependencies)] -//~^ WARNING external crate `bar` unused in - -fn main() {} diff --git a/src/test/ui/unused-crate-deps/extern-loc-defl-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-defl-json.stderr deleted file mode 100644 index cee3f6c1495c7..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-defl-json.stderr +++ /dev/null @@ -1,17 +0,0 @@ -{"message":"external crate `bar` unused in `extern_loc_defl_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-defl-json.rs","byte_start":146,"byte_end":146,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-defl-json.rs","byte_start":154,"byte_end":179,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":{"name":"bar"}}],"rendered":"warning: external crate `bar` unused in `extern_loc_defl_json`: remove the dependency or add `use bar as _;` - --> $DIR/extern-loc-defl-json.rs:7:1 - | -LL | #![warn(unused_crate_dependencies)] - | ^ - | -note: the lint level is defined here - --> $DIR/extern-loc-defl-json.rs:7:9 - | -LL | #![warn(unused_crate_dependencies)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: remove unnecessary dependency `bar` - -"} -{"message":"1 warning emitted","code":null,"level":"warning","spans":[],"children":[],"rendered":"warning: 1 warning emitted - -"} diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs deleted file mode 100644 index aee6233e4283d..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs +++ /dev/null @@ -1,8 +0,0 @@ -// --extern-location with a raw reference - -// aux-crate:bar=bar.rs -// compile-flags:--extern-location bar=json:[{"malformed -Z unstable-options - -#![warn(unused_crate_dependencies)] - -fn main() {} diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.stderr deleted file mode 100644 index 20d606372e027..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: `--extern-location`: malformed json location `[{"malformed` - diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json-json.rs deleted file mode 100644 index c7988cd469e2d..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-json-json.rs +++ /dev/null @@ -1,10 +0,0 @@ -// --extern-location with a raw reference - -// check-pass -// aux-crate:bar=bar.rs -// compile-flags:--extern-location bar=json:{"key":123,"value":{}} --error-format json -Z unstable-options - -#![warn(unused_crate_dependencies)] -//~^ WARNING external crate `bar` unused in - -fn main() {} diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr deleted file mode 100644 index 001ec6a25549a..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr +++ /dev/null @@ -1,17 +0,0 @@ -{"message":"external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":189,"byte_end":189,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":197,"byte_end":222,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":{"key":123,"value":{}}}],"rendered":"warning: external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;` - --> $DIR/extern-loc-json-json.rs:7:1 - | -LL | #![warn(unused_crate_dependencies)] - | ^ - | -note: the lint level is defined here - --> $DIR/extern-loc-json-json.rs:7:9 - | -LL | #![warn(unused_crate_dependencies)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: remove unnecessary dependency `bar` - -"} -{"message":"1 warning emitted","code":null,"level":"warning","spans":[],"children":[],"rendered":"warning: 1 warning emitted - -"} diff --git a/src/test/ui/unused-crate-deps/extern-loc-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json.rs deleted file mode 100644 index c0d76c86b895c..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-json.rs +++ /dev/null @@ -1,10 +0,0 @@ -// --extern-location with a raw reference - -// check-pass -// aux-crate:bar=bar.rs -// compile-flags:--extern-location bar=json:{"key":123,"value":{}} -Z unstable-options - -#![warn(unused_crate_dependencies)] -//~^ WARNING external crate `bar` unused in - -fn main() {} diff --git a/src/test/ui/unused-crate-deps/extern-loc-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-json.stderr deleted file mode 100644 index a6bbc0da1c6b4..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-json.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: external crate `bar` unused in `extern_loc_json`: remove the dependency or add `use bar as _;` - --> $DIR/extern-loc-json.rs:7:1 - | -LL | #![warn(unused_crate_dependencies)] - | ^ - | -note: the lint level is defined here - --> $DIR/extern-loc-json.rs:7:9 - | -LL | #![warn(unused_crate_dependencies)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: remove unnecessary dependency `bar` - -warning: 1 warning emitted - diff --git a/src/test/ui/unused-crate-deps/extern-loc-missing-loc.rs b/src/test/ui/unused-crate-deps/extern-loc-missing-loc.rs deleted file mode 100644 index 6ac558974d0c5..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-missing-loc.rs +++ /dev/null @@ -1,8 +0,0 @@ -// --extern-location with a raw reference - -// aux-crate:bar=bar.rs -// compile-flags:--extern-location bar -Zunstable-options - -#![warn(unused_crate_dependencies)] - -fn main() {} diff --git a/src/test/ui/unused-crate-deps/extern-loc-missing-loc.stderr b/src/test/ui/unused-crate-deps/extern-loc-missing-loc.stderr deleted file mode 100644 index 4584fbfb67ff7..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-missing-loc.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: `--extern-location`: specify location for extern crate `bar` - diff --git a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs b/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs deleted file mode 100644 index 3590b9c2812c7..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs +++ /dev/null @@ -1,8 +0,0 @@ -// --extern-location with no type - -// aux-crate:bar=bar.rs -// compile-flags:--extern-location bar=missing-loc-type -Z unstable-options - -#![warn(unused_crate_dependencies)] - -fn main() {} diff --git a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.stderr b/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.stderr deleted file mode 100644 index d0c36ebeb142e..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: unknown location type `missing-loc-type`: use `raw` or `json` - diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs b/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs deleted file mode 100644 index 64c3d77ce0826..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs +++ /dev/null @@ -1,10 +0,0 @@ -// --extern-location with a raw reference - -// check-pass -// aux-crate:bar=bar.rs -// compile-flags:--extern-location bar=raw:in-the-test-file --error-format json -Z unstable-options - -#![warn(unused_crate_dependencies)] -//~^ WARNING external crate `bar` unused in - -fn main() {} diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr deleted file mode 100644 index 4083bd51835b0..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr +++ /dev/null @@ -1,17 +0,0 @@ -{"message":"external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":182,"byte_end":182,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":190,"byte_end":215,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar` at `in-the-test-file`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"raw extern location","code":null,"level":"help","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":0,"byte_end":0,"line_start":1,"line_end":1,"column_start":1,"column_end":1,"is_primary":true,"text":[],"label":null,"suggested_replacement":"in-the-test-file","suggestion_applicability":"Unspecified","expansion":null}],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":"in-the-test-file"}],"rendered":"warning: external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;` - --> $DIR/extern-loc-raw-json.rs:7:1 - | -LL | #![warn(unused_crate_dependencies)] - | ^ - | -note: the lint level is defined here - --> $DIR/extern-loc-raw-json.rs:7:9 - | -LL | #![warn(unused_crate_dependencies)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: remove unnecessary dependency `bar` at `in-the-test-file` - -"} -{"message":"1 warning emitted","code":null,"level":"warning","spans":[],"children":[],"rendered":"warning: 1 warning emitted - -"} diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs b/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs deleted file mode 100644 index a9e7afbda31e7..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs +++ /dev/null @@ -1,8 +0,0 @@ -// --extern-location with a raw reference - -// aux-crate:bar=bar.rs -// compile-flags:--extern-location bar=raw -Z unstable-options - -#![warn(unused_crate_dependencies)] - -fn main() {} diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.stderr b/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.stderr deleted file mode 100644 index 4b51266e4f6fa..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: `--extern-location`: missing `raw` location - diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw.rs b/src/test/ui/unused-crate-deps/extern-loc-raw.rs deleted file mode 100644 index 27d0975d01ada..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-raw.rs +++ /dev/null @@ -1,10 +0,0 @@ -// --extern-location with a raw reference - -// check-pass -// aux-crate:bar=bar.rs -// compile-flags:--extern-location bar=raw:in-the-test-file -Z unstable-options - -#![warn(unused_crate_dependencies)] -//~^ WARNING external crate `bar` unused in - -fn main() {} diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw.stderr b/src/test/ui/unused-crate-deps/extern-loc-raw.stderr deleted file mode 100644 index 2cdd005586673..0000000000000 --- a/src/test/ui/unused-crate-deps/extern-loc-raw.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: external crate `bar` unused in `extern_loc_raw`: remove the dependency or add `use bar as _;` - --> $DIR/extern-loc-raw.rs:7:1 - | -LL | #![warn(unused_crate_dependencies)] - | ^ - | -note: the lint level is defined here - --> $DIR/extern-loc-raw.rs:7:9 - | -LL | #![warn(unused_crate_dependencies)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: remove unnecessary dependency `bar` at `in-the-test-file` - -warning: 1 warning emitted - diff --git a/src/test/ui/unused-crate-deps/libfib.stderr b/src/test/ui/unused-crate-deps/libfib.stderr index 479f51bff464d..15833126bd620 100644 --- a/src/test/ui/unused-crate-deps/libfib.stderr +++ b/src/test/ui/unused-crate-deps/libfib.stderr @@ -5,7 +5,6 @@ LL | pub fn fib(n: u32) -> Vec { | ^ | = note: requested on the command line with `-W unused-crate-dependencies` - = help: remove unnecessary dependency `bar` warning: 1 warning emitted diff --git a/src/test/ui/unused-crate-deps/unused-aliases.stderr b/src/test/ui/unused-crate-deps/unused-aliases.stderr index 1142d156d0e96..c8c6c4507b0c5 100644 --- a/src/test/ui/unused-crate-deps/unused-aliases.stderr +++ b/src/test/ui/unused-crate-deps/unused-aliases.stderr @@ -9,7 +9,6 @@ note: the lint level is defined here | LL | #![warn(unused_crate_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: remove unnecessary dependency `barbar` warning: 1 warning emitted diff --git a/src/test/ui/unused-crate-deps/warn-attr.stderr b/src/test/ui/unused-crate-deps/warn-attr.stderr index 29667d9525cb4..0d38315704b11 100644 --- a/src/test/ui/unused-crate-deps/warn-attr.stderr +++ b/src/test/ui/unused-crate-deps/warn-attr.stderr @@ -9,7 +9,6 @@ note: the lint level is defined here | LL | #![warn(unused_crate_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: remove unnecessary dependency `bar` warning: 1 warning emitted diff --git a/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr b/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr index 2c0c921512986..65956461d6439 100644 --- a/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr +++ b/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr @@ -5,7 +5,6 @@ LL | fn main() {} | ^ | = note: requested on the command line with `-W unused-crate-dependencies` - = help: remove unnecessary dependency `bar` warning: 1 warning emitted diff --git a/src/test/ui/unused-crate-deps/warn-cmdline.stderr b/src/test/ui/unused-crate-deps/warn-cmdline.stderr index 2cd49218f5ad8..ea675ba9a1eb1 100644 --- a/src/test/ui/unused-crate-deps/warn-cmdline.stderr +++ b/src/test/ui/unused-crate-deps/warn-cmdline.stderr @@ -5,7 +5,6 @@ LL | fn main() {} | ^ | = note: requested on the command line with `-W unused-crate-dependencies` - = help: remove unnecessary dependency `bar` warning: 1 warning emitted From 8cec88ba76e1d6edc98f30101c40f9247c754898 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Fri, 15 Apr 2022 17:06:09 +0200 Subject: [PATCH 3/8] `alloc`: make `vec!` unavailable under `no_global_oom_handling` The `vec!` macro has 3 rules, but two are not usable under `no_global_oom_handling` builds of the standard library (even with a zero size): ```rust let _ = vec![42]; // Error: requires `exchange_malloc` lang_item. let _ = vec![42; 0]; // Error: cannot find function `from_elem`. ``` Thus those two rules should not be available to begin with. The remaining one, with an empty matcher, is just a shorthand for `new()` and may not make as much sense to have alone, since the idea behind `vec!` is to enable `Vec`s to be defined with the same syntax as array expressions. Furthermore, the documentation can be confusing since it shows the other rules. Thus perhaps it is better and simpler to disable `vec!` entirely under `no_global_oom_handling` environments, and let users call `new()` instead: ```rust let _: Vec = vec![]; let _: Vec = Vec::new(); ``` Notwithstanding this, a `try_vec!` macro would be useful, such as the one introduced in https://github.com/rust-lang/rust/pull/95051. If the shorthand for `new()` is deemed worth keeping on its own, then it may be interesting to have a separate `vec!` macro with a single rule and different, simpler documentation. Signed-off-by: Miguel Ojeda --- library/alloc/src/macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs index d3e9e65c3fe57..22c19243e7f53 100644 --- a/library/alloc/src/macros.rs +++ b/library/alloc/src/macros.rs @@ -34,7 +34,7 @@ /// be mindful of side effects. /// /// [`Vec`]: crate::vec::Vec -#[cfg(not(test))] +#[cfg(all(not(no_global_oom_handling), not(test)))] #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "vec_macro"] @@ -55,7 +55,7 @@ macro_rules! vec { // required for this macro definition, is not available. Instead use the // `slice::into_vec` function which is only available with cfg(test) // NB see the slice::hack module in slice.rs for more information -#[cfg(test)] +#[cfg(all(not(no_global_oom_handling), test))] macro_rules! vec { () => ( $crate::vec::Vec::new() From ebe3c56c6eeca6db4a62ebb99e2ffe35f33ea4de Mon Sep 17 00:00:00 2001 From: oribenshir Date: Sat, 5 Mar 2022 12:04:32 +0200 Subject: [PATCH 4/8] Provide a better diagnostic on failure to meet send bound on futures in a foreign crate Adding diagnostic data on generators to the crate metadata and using it to provide a better diagnostic on failure to meet send bound on futures originated from a foreign crate --- compiler/rustc_metadata/src/rmeta/decoder.rs | 19 ++ .../src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 7 +- compiler/rustc_metadata/src/rmeta/mod.rs | 2 + compiler/rustc_middle/src/query/mod.rs | 6 + compiler/rustc_middle/src/ty/context.rs | 32 +++ compiler/rustc_middle/src/ty/mod.rs | 5 +- compiler/rustc_middle/src/ty/query.rs | 10 +- .../src/traits/error_reporting/suggestions.rs | 200 ++++++++++++++---- src/test/ui/async-await/issues/issue-67893.rs | 2 +- .../ui/async-await/issues/issue-67893.stderr | 16 +- 11 files changed, 247 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 8d0e8467404ca..fd17d3ea0d5ff 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::{ @@ -1732,6 +1733,24 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .collect() }) } + + fn get_generator_diagnostic_data( + self, + tcx: TyCtxt<'tcx>, + id: DefIndex, + ) -> Option> { + 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 63bf929fb8639..ba6c4a2af77e1 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -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) { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index e967750aebb52..74f22e0179c2f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1550,16 +1550,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(..) => { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 43ccfc64e0563..e1a1589adb322 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>, def_path_hashes: Table, proc_macro_quoted_spans: Table>, + generator_diagnostic_data: Table>>, } #[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)] diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f38ade1076eac..3b61d91a10fd3 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1962,4 +1962,10 @@ rustc_queries! { eval_always desc { "computing the backend features for CLI flags" } } + + query generator_diagnostic_data(key: DefId) -> Option> { + 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 4e6be84ad7f8f..30fe3ffa7e3c4 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, } +// 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>>, + pub hir_owner: DefId, + pub nodes_types: ItemLocalMap>, + pub adjustments: ItemLocalMap>>, +} + #[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::>() + }); + 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 c2accea11ba2a..a0d0e4b9c2c64 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -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; diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 9e48c569c253a..7629d7a8259b8 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_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index ead1f0126c465..b49ee7b9446dc 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( + &self, + infer_context: &InferCtxt<'a, 'tcx>, + generator_did: DefId, + ty_matches: F, + ) -> Option + 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( + &self, + visitor: AwaitsVisitor, + hir: map::Map<'tcx>, + ty_matches: F, + ) -> Option + 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::, _, _>( + || { + 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>> { + 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, Option, Option)>, - inner_generator_body: Option<&hir::Body<'tcx>>, + is_async: bool, outer_generator: Option, 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> = 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, Option, Option)>, - inner_generator_body: Option<&hir::Body<'tcx>>, + is_async: bool, outer_generator: Option, 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/src/test/ui/async-await/issues/issue-67893.rs b/src/test/ui/async-await/issues/issue-67893.rs index 8b53408d758e1..d73772e5fa0d9 100644 --- a/src/test/ui/async-await/issues/issue-67893.rs +++ b/src/test/ui/async-await/issues/issue-67893.rs @@ -7,5 +7,5 @@ fn g(_: impl Send) {} fn main() { g(issue_67893::run()) - //~^ ERROR generator cannot be sent between threads safely + //~^ ERROR future cannot be sent between threads safely } diff --git a/src/test/ui/async-await/issues/issue-67893.stderr b/src/test/ui/async-await/issues/issue-67893.stderr index 0aa0d5d7ccdde..316b6d06f932a 100644 --- a/src/test/ui/async-await/issues/issue-67893.stderr +++ b/src/test/ui/async-await/issues/issue-67893.stderr @@ -1,10 +1,22 @@ -error: generator cannot be sent between threads safely +error: future cannot be sent between threads safely --> $DIR/issue-67893.rs:9:7 | LL | g(issue_67893::run()) - | ^^^^^^^^^^^^^^^^^^ generator is not `Send` + | ^^^^^^^^^^^^^^^^^^ future is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, ()>` +note: future is not `Send` as this value is used across an await + --> $DIR/auxiliary/issue_67893.rs:9:26 + | +LL | f(*x.lock().unwrap()).await; + | ----------------- ^^^^^^ await occurs here, with `x.lock().unwrap()` maybe used later + | | + | has type `MutexGuard<'_, ()>` which is not `Send` +note: `x.lock().unwrap()` is later dropped here + --> $DIR/auxiliary/issue_67893.rs:9:32 + | +LL | f(*x.lock().unwrap()).await; + | ^ note: required by a bound in `g` --> $DIR/issue-67893.rs:6:14 | From a59cc5774b2b599e697db5175c331f5f98e42001 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sun, 17 Apr 2022 01:20:11 +0900 Subject: [PATCH 5/8] fix an invalid error for a suggestion to add a slice in pattern-matching --- compiler/rustc_typeck/src/check/pat.rs | 93 ++++++++++--------- .../pattern-struct-with-slice-vec-field.rs | 13 +++ ...pattern-struct-with-slice-vec-field.stderr | 9 ++ 3 files changed, 69 insertions(+), 46 deletions(-) create mode 100644 src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs create mode 100644 src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 0baca9048b4cd..deaa0c7c7419e 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -2044,63 +2044,64 @@ 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), - 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 { + let any_target_ty = Autoderef::new( + &self.infcx, + self.param_env, + self.body_id, + span, + self.resolve_vars_if_possible(ti.expected), + span, + ) + .any(|(ty, _)| { + debug!("kind={:?}", ty.kind()); + 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 slicing here", - format!("{}[..]", snippet), - applicability, + "consider using `as_deref` here", + format!("{snippet}.as_deref()"), + Applicability::MaybeIncorrect, ); + false } + _ => self.is_slice_or_array_or_vector(ty), } + }); + + if any_target_ty { + 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, ty: Ty<'tcx>) -> bool { + match ty.kind() { + ty::Adt(adt_def, _) if self.tcx.is_diagnostic_item(sym::Vec, adt_def.did()) => true, + ty::Ref(_, ty, _) => self.is_slice_or_array_or_vector(*ty), + ty::Slice(..) | ty::Array(..) => true, + _ => false, + } + } } diff --git a/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs new file mode 100644 index 0000000000000..1a9fc2f0050a7 --- /dev/null +++ b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs @@ -0,0 +1,13 @@ +struct Foo { + v: Vec, +} + +fn f(foo: &Foo) { + match foo { + Foo { v: [1, 2] } => {} + //~^ ERROR expected an array or slice, found `Vec + _ => {} + } +} + +fn main() {} diff --git a/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr new file mode 100644 index 0000000000000..cb408d38fd276 --- /dev/null +++ b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr @@ -0,0 +1,9 @@ +error[E0529]: expected an array or slice, found `Vec` + --> $DIR/pattern-struct-with-slice-vec-field.rs:7:18 + | +LL | Foo { v: [1, 2] } => {} + | ^^^^^^ pattern cannot match with input type `Vec` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0529`. From 07ee0317638cf1f290a8dace1c7ccc8fea16a236 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 15 Apr 2022 19:27:53 +0200 Subject: [PATCH 6/8] Stop using CRATE_DEF_INDEX. `CRATE_DEF_ID` and `CrateNum::as_def_id` are almost always what we want. --- .../src/back/symbol_export.rs | 17 +----- compiler/rustc_hir/src/def.rs | 6 +-- compiler/rustc_hir/src/definitions.rs | 5 -- compiler/rustc_hir/src/hir_id.rs | 9 ++-- .../src/rmeta/decoder/cstore_impl.rs | 4 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- .../rustc_middle/src/dep_graph/dep_node.rs | 4 +- compiler/rustc_middle/src/middle/stability.rs | 5 +- compiler/rustc_middle/src/mir/mod.rs | 4 +- compiler/rustc_middle/src/ty/mod.rs | 8 +-- compiler/rustc_middle/src/ty/print/pretty.rs | 14 +++-- .../rustc_middle/src/ty/structural_impls.rs | 3 +- .../src/partitioning/default.rs | 6 +-- compiler/rustc_passes/src/entry.rs | 53 ++++++++----------- compiler/rustc_passes/src/hir_id_validator.rs | 4 +- compiler/rustc_passes/src/stability.rs | 4 +- .../rustc_query_impl/src/profiling_support.rs | 4 +- .../rustc_resolve/src/build_reduced_graph.rs | 16 +++--- compiler/rustc_resolve/src/diagnostics.rs | 4 +- compiler/rustc_resolve/src/late.rs | 4 +- .../rustc_resolve/src/late/diagnostics.rs | 10 ++-- compiler/rustc_resolve/src/lib.rs | 11 ++-- compiler/rustc_span/src/def_id.rs | 15 +++++- src/librustdoc/clean/mod.rs | 6 +-- src/librustdoc/clean/types.rs | 16 ++---- src/librustdoc/formats/cache.rs | 4 +- src/librustdoc/html/format.rs | 5 +- src/librustdoc/json/conversions.rs | 3 +- src/librustdoc/visit_lib.rs | 4 +- .../clippy/clippy_lints/src/missing_doc.rs | 6 +-- 30 files changed, 109 insertions(+), 147 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 765bd877db169..7b7c676c26cd1 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> = Default::default(); - let cnum_stable_ids: IndexVec = { - 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_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 53d60d280c001..324e110005717 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 4908992085a6e..bce9ba12ac0c4 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 3b5e4dcf5e011..e0ff28dff15cd 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_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 63bf929fb8639..9c88171d17566 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; @@ -324,7 +324,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 e967750aebb52..50010fb83cf3b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1633,7 +1633,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_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index d20be0a34d2d5..8402ca3028cce 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> 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 fd6e241346db8..758658c3d8c94 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 49769b7ae3d89..4f4b6cf704fa9 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>) -> 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/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c2accea11ba2a..2901772bc74ec 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; @@ -319,7 +319,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 +1992,8 @@ impl<'tcx> TyCtxt<'tcx> { } fn opt_item_name(self, def_id: DefId) -> Option { - 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 4379adb604e1f..d2c5bd1898614 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_hir::ItemKind; use rustc_session::config::TrimmedDefPaths; @@ -336,9 +336,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)); } @@ -2228,11 +2226,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( @@ -2258,7 +2256,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 })) @@ -2693,7 +2691,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/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 5c7910db362d2..4ef6ff1835ffd 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 c4ffb19f87a91..1677419887988 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 5a1373ad1a218..db083d0453bc0 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, } -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 56755d68686e3..379a6827c8aac 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 01ba9e35c24dc..35a858cb86c3f 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 acccf43f06285..b20aa7b53468a 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 54e8c03156d55..77995b60a557e 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 { @@ -759,7 +759,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 }; @@ -1108,7 +1108,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), }) }; @@ -1244,7 +1244,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); @@ -1490,7 +1490,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 f3b8c1e266c58..899980a4c0887 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 763f31622bc1f..1a98dd38fc97e 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::{bug, span_bug}; use rustc_session::lint; @@ -2210,7 +2210,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 0926f24ae70ef..17a9ef4b4db83 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -19,7 +19,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; @@ -351,7 +351,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } }) .collect::>(); - 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 @@ -1331,10 +1331,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 0335c40d70d8c..5389cb19b58e4 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -37,7 +37,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; @@ -755,7 +755,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, } } @@ -1207,18 +1207,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> = session .opts diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 6d1b36796d869..d5f806308cf41 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 { + 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/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 21016afbf5f99..a070cef227252 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -15,7 +15,7 @@ use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; -use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc_middle::middle::resolve_lifetime as rl; use rustc_middle::ty::fold::TypeFolder; @@ -1975,7 +1975,7 @@ fn clean_extern_crate( // this is the ID of the `extern crate` statement let cnum = cx.tcx.extern_mod_stmt_cnum(krate.def_id).unwrap_or(LOCAL_CRATE); // this is the ID of the crate itself - let crate_def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX }; + let crate_def_id = cnum.as_def_id(); let attrs = cx.tcx.hir().attrs(krate.hir_id()); let ty_vis = cx.tcx.visibility(krate.def_id); let please_inline = ty_vis.is_public() @@ -2094,7 +2094,7 @@ fn clean_use_statement( } else { if inline_attr.is_none() { if let Res::Def(DefKind::Mod, did) = path.res { - if !did.is_local() && did.index == CRATE_DEF_INDEX { + if !did.is_local() && did.is_crate_root() { // if we're `pub use`ing an extern crate root, don't inline it unless we // were specifically asked for it denied = true; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 4b473df155f58..e30bc6e0a97ee 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -20,7 +20,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::thin_vec::ThinVec; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; -use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; use rustc_hir::{BodyId, Mutability}; use rustc_index::vec::IndexVec; @@ -104,14 +104,6 @@ impl ItemId { ItemId::Primitive(_, krate) => krate, } } - - #[inline] - crate fn index(self) -> Option { - match self { - ItemId::DefId(id) => Some(id.index), - _ => None, - } - } } impl From for ItemId { @@ -160,7 +152,7 @@ impl ExternalCrate { #[inline] crate fn def_id(&self) -> DefId { - DefId { krate: self.crate_num, index: CRATE_DEF_INDEX } + self.crate_num.as_def_id() } crate fn src(&self, tcx: TyCtxt<'_>) -> FileName { @@ -217,7 +209,7 @@ impl ExternalCrate { // Failing that, see if there's an attribute specifying where to find this // external crate - let did = DefId { krate: self.crate_num, index: CRATE_DEF_INDEX }; + let did = self.crate_num.as_def_id(); tcx.get_attrs(did) .lists(sym::doc) .filter(|a| a.has_name(sym::html_root_url)) @@ -559,7 +551,7 @@ impl Item { } crate fn is_crate(&self) -> bool { - self.is_mod() && self.item_id.as_def_id().map_or(false, |did| did.index == CRATE_DEF_INDEX) + self.is_mod() && self.item_id.as_def_id().map_or(false, |did| did.is_crate_root()) } crate fn is_mod(&self) -> bool { self.type_() == ItemType::Module diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index e138e434c4e04..efd1a78a9d9a5 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -1,7 +1,7 @@ use std::mem; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{CrateNum, DefId}; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::TyCtxt; use rustc_span::{sym, Symbol}; @@ -293,7 +293,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // A crate has a module at its root, containing all items, // which should not be indexed. The crate-item itself is // inserted later on when serializing the search-index. - if item.item_id.index().map_or(false, |idx| idx != CRATE_DEF_INDEX) { + if item.item_id.as_def_id().map_or(false, |idx| !idx.is_crate_root()) { let desc = item.doc_value().map_or_else(String::new, |x| { short_markdown_summary(x.as_str(), &item.link_names(self.cache)) }); diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 55b0028180f66..6954e2363f5f0 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -18,7 +18,6 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty; use rustc_middle::ty::DefIdTree; use rustc_middle::ty::TyCtxt; -use rustc_span::def_id::CRATE_DEF_INDEX; use rustc_span::{sym, Symbol}; use rustc_target::spec::abi::Abi; @@ -1312,7 +1311,7 @@ impl clean::Visibility { // visibility, so it shouldn't matter. let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id()); - if vis_did.index == CRATE_DEF_INDEX { + if vis_did.is_crate_root() { "pub(crate) ".to_owned() } else if parent_module == Some(vis_did) { // `pub(in foo)` where `foo` is the parent module @@ -1360,7 +1359,7 @@ impl clean::Visibility { // visibility, so it shouldn't matter. let parent_module = find_nearest_parent_module(tcx, item_did); - if vis_did.index == CRATE_DEF_INDEX { + if vis_did.is_crate_root() { "pub(crate) ".to_owned() } else if parent_module == Some(vis_did) { // `pub(in foo)` where `foo` is the parent module diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 0b5fb48059579..56b02cd848041 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -10,7 +10,6 @@ use std::fmt; use rustc_ast::ast; use rustc_hir::{def::CtorKind, def_id::DefId}; use rustc_middle::ty::{self, TyCtxt}; -use rustc_span::def_id::CRATE_DEF_INDEX; use rustc_span::Pos; use rustc_target::spec::abi::Abi as RustcAbi; @@ -83,7 +82,7 @@ impl JsonRenderer<'_> { match v { Public => Visibility::Public, Inherited => Visibility::Default, - Restricted(did) if did.index == CRATE_DEF_INDEX => Visibility::Crate, + Restricted(did) if did.is_crate_root() => Visibility::Crate, Restricted(did) => Visibility::Restricted { parent: from_item_id(did.into()), path: self.tcx.def_path(did).to_string_no_crate_verbose(), diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index 5bcec779bc0e7..9723cdbe3345f 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{CrateNum, DefId}; use rustc_middle::middle::privacy::{AccessLevel, AccessLevels}; use rustc_middle::ty::TyCtxt; @@ -29,7 +29,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> { } crate fn visit_lib(&mut self, cnum: CrateNum) { - let did = DefId { krate: cnum, index: CRATE_DEF_INDEX }; + let did = cnum.as_def_id(); self.update(did, Some(AccessLevel::Public)); self.visit_mod(did); } diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index fc0483a929a7a..5816a95dcebff 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -10,7 +10,7 @@ use clippy_utils::diagnostics::span_lint; use rustc_ast::ast; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::ty; +use rustc_middle::ty::{self, DefIdTree}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::source_map::Span; @@ -114,8 +114,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { hir::ItemKind::Fn(..) => { // ignore main() if it.ident.name == sym::main { - let def_key = cx.tcx.hir().def_key(it.def_id); - if def_key.parent == Some(hir::def_id::CRATE_DEF_INDEX) { + let at_root = cx.tcx.local_parent(it.def_id) == Some(CRATE_DEF_ID); + if at_root { return; } } From 5924ef874ebee33894cd34be07f88ed762f32385 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda <41065217+TaKO8Ki@users.noreply.github.com> Date: Mon, 18 Apr 2022 12:51:12 +0900 Subject: [PATCH 7/8] stop using `Autoderef` --- compiler/rustc_typeck/src/check/pat.rs | 62 ++++++++++++-------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index deaa0c7c7419e..151adb69aa932 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -2055,35 +2055,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let (Some(span), true) = (ti.span, ti.origin_expr) && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - let any_target_ty = Autoderef::new( - &self.infcx, - self.param_env, - self.body_id, - span, - self.resolve_vars_if_possible(ti.expected), - span, - ) - .any(|(ty, _)| { - debug!("kind={:?}", ty.kind()); - 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!("{snippet}.as_deref()"), - Applicability::MaybeIncorrect, - ); - false - } - _ => self.is_slice_or_array_or_vector(ty), + 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, + "consider using `as_deref` here", + format!("{snippet}.as_deref()"), + Applicability::MaybeIncorrect, + ); } - }); - - if any_target_ty { + _ => () + } + if is_slice_or_array_or_vector.0 { err.span_suggestion( span, "consider slicing here", @@ -2096,12 +2085,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - fn is_slice_or_array_or_vector(&self, ty: Ty<'tcx>) -> bool { + 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::Ref(_, ty, _) => self.is_slice_or_array_or_vector(*ty), - ty::Slice(..) | ty::Array(..) => true, - _ => false, + 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), } } } From efe438b47441203c8e881e87f2f2e29db76d3ff7 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda <41065217+TaKO8Ki@users.noreply.github.com> Date: Mon, 18 Apr 2022 13:08:23 +0900 Subject: [PATCH 8/8] implement `Deref` for `Bar` --- .../pattern-struct-with-slice-vec-field.rs | 22 +++++++++++++++++++ ...pattern-struct-with-slice-vec-field.stderr | 10 +++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs index 1a9fc2f0050a7..5b223a91f508f 100644 --- a/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs +++ b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs @@ -1,7 +1,21 @@ +use std::ops::Deref; + struct Foo { v: Vec, } +struct Bar { + v: Vec, +} + +impl Deref for Bar { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.v + } +} + fn f(foo: &Foo) { match foo { Foo { v: [1, 2] } => {} @@ -10,4 +24,12 @@ fn f(foo: &Foo) { } } +fn bar(bar: &Bar) { + match bar { + Bar { v: [1, 2] } => {} + //~^ ERROR expected an array or slice, found `Vec + _ => {} + } +} + fn main() {} diff --git a/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr index cb408d38fd276..5b48a8b18a514 100644 --- a/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr +++ b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr @@ -1,9 +1,15 @@ error[E0529]: expected an array or slice, found `Vec` - --> $DIR/pattern-struct-with-slice-vec-field.rs:7:18 + --> $DIR/pattern-struct-with-slice-vec-field.rs:21:18 | LL | Foo { v: [1, 2] } => {} | ^^^^^^ pattern cannot match with input type `Vec` -error: aborting due to previous error +error[E0529]: expected an array or slice, found `Vec` + --> $DIR/pattern-struct-with-slice-vec-field.rs:29:18 + | +LL | Bar { v: [1, 2] } => {} + | ^^^^^^ pattern cannot match with input type `Vec` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0529`.