Rollup merge of #142687 - cjgillot:less-hir_crate, r=oli-obk
Reduce uses of `hir_crate`. I tried rebasing my old incremental-HIR branch. This is a by-product, which is required if we want to get rid of `hir_crate` entirely. The second commit is a drive-by cleanup. It can be pulled into its own PR. r? ````@oli-obk````
This commit is contained in:
@@ -463,12 +463,6 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn crate_inject_span(&self) -> Option<Span> {
|
|
||||||
self.tcx.hir_crate_items(()).definitions().next().and_then(|id| {
|
|
||||||
self.tcx.crate_level_attribute_injection_span(self.tcx.local_def_id_to_hir_id(id))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check the const stability of the given item (fn or trait).
|
/// Check the const stability of the given item (fn or trait).
|
||||||
fn check_callee_stability(&mut self, def_id: DefId) {
|
fn check_callee_stability(&mut self, def_id: DefId) {
|
||||||
match self.tcx.lookup_const_stability(def_id) {
|
match self.tcx.lookup_const_stability(def_id) {
|
||||||
@@ -543,7 +537,6 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
|||||||
feature,
|
feature,
|
||||||
feature_enabled,
|
feature_enabled,
|
||||||
safe_to_expose_on_stable: callee_safe_to_expose_on_stable,
|
safe_to_expose_on_stable: callee_safe_to_expose_on_stable,
|
||||||
suggestion_span: self.crate_inject_span(),
|
|
||||||
is_function_call: self.tcx.def_kind(def_id) != DefKind::Trait,
|
is_function_call: self.tcx.def_kind(def_id) != DefKind::Trait,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -919,7 +912,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||||||
name: intrinsic.name,
|
name: intrinsic.name,
|
||||||
feature,
|
feature,
|
||||||
const_stable_indirect: is_const_stable,
|
const_stable_indirect: is_const_stable,
|
||||||
suggestion: self.crate_inject_span(),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some(attrs::ConstStability {
|
Some(attrs::ConstStability {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
//! Concrete error types for all operations which may be invalid in a certain const context.
|
//! Concrete error types for all operations which may be invalid in a certain const context.
|
||||||
|
|
||||||
use hir::{ConstContext, LangItem};
|
use hir::{ConstContext, LangItem};
|
||||||
|
use rustc_errors::Diag;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{Applicability, Diag};
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
@@ -384,7 +384,6 @@ pub(crate) struct CallUnstable {
|
|||||||
/// expose on stable.
|
/// expose on stable.
|
||||||
pub feature_enabled: bool,
|
pub feature_enabled: bool,
|
||||||
pub safe_to_expose_on_stable: bool,
|
pub safe_to_expose_on_stable: bool,
|
||||||
pub suggestion_span: Option<Span>,
|
|
||||||
/// true if `def_id` is the function we are calling, false if `def_id` is an unstable trait.
|
/// true if `def_id` is the function we are calling, false if `def_id` is an unstable trait.
|
||||||
pub is_function_call: bool,
|
pub is_function_call: bool,
|
||||||
}
|
}
|
||||||
@@ -412,20 +411,7 @@ impl<'tcx> NonConstOp<'tcx> for CallUnstable {
|
|||||||
def_path: ccx.tcx.def_path_str(self.def_id),
|
def_path: ccx.tcx.def_path_str(self.def_id),
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
// FIXME: make this translatable
|
ccx.tcx.disabled_nightly_features(&mut err, [(String::new(), self.feature)]);
|
||||||
let msg = format!("add `#![feature({})]` to the crate attributes to enable", self.feature);
|
|
||||||
#[allow(rustc::untranslatable_diagnostic)]
|
|
||||||
if let Some(span) = self.suggestion_span {
|
|
||||||
err.span_suggestion_verbose(
|
|
||||||
span,
|
|
||||||
msg,
|
|
||||||
format!("#![feature({})]\n", self.feature),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
err.help(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -452,7 +438,6 @@ pub(crate) struct IntrinsicUnstable {
|
|||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
pub feature: Symbol,
|
pub feature: Symbol,
|
||||||
pub const_stable_indirect: bool,
|
pub const_stable_indirect: bool,
|
||||||
pub suggestion: Option<Span>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable {
|
impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable {
|
||||||
@@ -472,8 +457,7 @@ impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable {
|
|||||||
span,
|
span,
|
||||||
name: self.name,
|
name: self.name,
|
||||||
feature: self.feature,
|
feature: self.feature,
|
||||||
suggestion: self.suggestion,
|
suggestion: ccx.tcx.crate_level_attribute_injection_span(),
|
||||||
help: self.suggestion.is_none(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,9 +136,7 @@ pub(crate) struct UnstableIntrinsic {
|
|||||||
code = "#![feature({feature})]\n",
|
code = "#![feature({feature})]\n",
|
||||||
applicability = "machine-applicable"
|
applicability = "machine-applicable"
|
||||||
)]
|
)]
|
||||||
pub suggestion: Option<Span>,
|
pub suggestion: Span,
|
||||||
#[help(const_eval_unstable_intrinsic_suggestion)]
|
|
||||||
pub help: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
|||||||
@@ -292,7 +292,11 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
|
|||||||
}
|
}
|
||||||
HirTree => {
|
HirTree => {
|
||||||
debug!("pretty printing HIR tree");
|
debug!("pretty printing HIR tree");
|
||||||
format!("{:#?}", ex.tcx().hir_crate(()))
|
ex.tcx()
|
||||||
|
.hir_crate_items(())
|
||||||
|
.owners()
|
||||||
|
.map(|owner| format!("{:#?} => {:#?}\n", owner, ex.tcx().hir_owner_nodes(owner)))
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
Mir => {
|
Mir => {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
|
|||||||
@@ -311,9 +311,7 @@ fn default_body_is_unstable(
|
|||||||
reason: reason_str,
|
reason: reason_str,
|
||||||
});
|
});
|
||||||
|
|
||||||
let inject_span = item_did
|
let inject_span = item_did.is_local().then(|| tcx.crate_level_attribute_injection_span());
|
||||||
.as_local()
|
|
||||||
.and_then(|id| tcx.crate_level_attribute_injection_span(tcx.local_def_id_to_hir_id(id)));
|
|
||||||
rustc_session::parse::add_feature_diagnostics_for_issue(
|
rustc_session::parse::add_feature_diagnostics_for_issue(
|
||||||
&mut err,
|
&mut err,
|
||||||
&tcx.sess,
|
&tcx.sess,
|
||||||
|
|||||||
@@ -1064,7 +1064,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
|
|||||||
Ok(..) => Some(vec![(adt_const_params_feature_string, sym::adt_const_params)]),
|
Ok(..) => Some(vec![(adt_const_params_feature_string, sym::adt_const_params)]),
|
||||||
};
|
};
|
||||||
if let Some(features) = may_suggest_feature {
|
if let Some(features) = may_suggest_feature {
|
||||||
tcx.disabled_nightly_features(&mut diag, Some(param.hir_id), features);
|
tcx.disabled_nightly_features(&mut diag, features);
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(diag.emit())
|
Err(diag.emit())
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ pub(crate) struct BaseExpressionDoubleDot {
|
|||||||
)]
|
)]
|
||||||
pub default_field_values_suggestion: Option<Span>,
|
pub default_field_values_suggestion: Option<Span>,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
pub default_field_values_help: Option<BaseExpressionDoubleDotEnableDefaultFieldValues>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
pub add_expr: Option<BaseExpressionDoubleDotAddExpr>,
|
pub add_expr: Option<BaseExpressionDoubleDotAddExpr>,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
pub remove_dots: Option<BaseExpressionDoubleDotRemove>,
|
pub remove_dots: Option<BaseExpressionDoubleDotRemove>,
|
||||||
@@ -61,10 +59,6 @@ pub(crate) struct BaseExpressionDoubleDotAddExpr {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
|
||||||
#[help(hir_typeck_base_expression_double_dot_enable_default_field_values)]
|
|
||||||
pub(crate) struct BaseExpressionDoubleDotEnableDefaultFieldValues;
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)]
|
#[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)]
|
||||||
pub(crate) struct FieldMultiplySpecifiedInInitializer {
|
pub(crate) struct FieldMultiplySpecifiedInInitializer {
|
||||||
|
|||||||
@@ -43,10 +43,9 @@ use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectatio
|
|||||||
use crate::coercion::{CoerceMany, DynamicCoerceMany};
|
use crate::coercion::{CoerceMany, DynamicCoerceMany};
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr,
|
AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr,
|
||||||
BaseExpressionDoubleDotEnableDefaultFieldValues, BaseExpressionDoubleDotRemove,
|
BaseExpressionDoubleDotRemove, CantDereference, FieldMultiplySpecifiedInInitializer,
|
||||||
CantDereference, FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
|
FunctionalRecordUpdateOnNonStruct, HelpUseLatestEdition, NakedAsmOutsideNakedFn, NoFieldOnType,
|
||||||
HelpUseLatestEdition, NakedAsmOutsideNakedFn, NoFieldOnType, NoFieldOnVariant,
|
NoFieldOnVariant, ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive,
|
||||||
ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive,
|
|
||||||
TypeMismatchFruTypo, YieldExprOutsideOfCoroutine,
|
TypeMismatchFruTypo, YieldExprOutsideOfCoroutine,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -2158,7 +2157,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !self.tcx.features().default_field_values() {
|
if !self.tcx.features().default_field_values() {
|
||||||
let sugg = self.tcx.crate_level_attribute_injection_span(expr.hir_id);
|
let sugg = self.tcx.crate_level_attribute_injection_span();
|
||||||
self.dcx().emit_err(BaseExpressionDoubleDot {
|
self.dcx().emit_err(BaseExpressionDoubleDot {
|
||||||
span: span.shrink_to_hi(),
|
span: span.shrink_to_hi(),
|
||||||
// We only mention enabling the feature if this is a nightly rustc *and* the
|
// We only mention enabling the feature if this is a nightly rustc *and* the
|
||||||
@@ -2166,18 +2165,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
default_field_values_suggestion: if self.tcx.sess.is_nightly_build()
|
default_field_values_suggestion: if self.tcx.sess.is_nightly_build()
|
||||||
&& missing_mandatory_fields.is_empty()
|
&& missing_mandatory_fields.is_empty()
|
||||||
&& !missing_optional_fields.is_empty()
|
&& !missing_optional_fields.is_empty()
|
||||||
&& sugg.is_some()
|
|
||||||
{
|
{
|
||||||
sugg
|
Some(sugg)
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
default_field_values_help: if self.tcx.sess.is_nightly_build()
|
|
||||||
&& missing_mandatory_fields.is_empty()
|
|
||||||
&& !missing_optional_fields.is_empty()
|
|
||||||
&& sugg.is_none()
|
|
||||||
{
|
|
||||||
Some(BaseExpressionDoubleDotEnableDefaultFieldValues)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1727,7 +1727,6 @@ impl<'tcx> Pick<'tcx> {
|
|||||||
}
|
}
|
||||||
tcx.disabled_nightly_features(
|
tcx.disabled_nightly_features(
|
||||||
lint,
|
lint,
|
||||||
Some(scope_expr_id),
|
|
||||||
self.unstable_candidates.iter().map(|(candidate, feature)| {
|
self.unstable_candidates.iter().map(|(candidate, feature)| {
|
||||||
(format!(" `{}`", tcx.def_path_str(candidate.item.def_id)), *feature)
|
(format!(" `{}`", tcx.def_path_str(candidate.item.def_id)), *feature)
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1011,8 +1011,8 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
|
|||||||
|
|
||||||
// Prefetch this to prevent multiple threads from blocking on it later.
|
// Prefetch this to prevent multiple threads from blocking on it later.
|
||||||
// This is needed since the `hir_id_validator::check_crate` call above is not guaranteed
|
// This is needed since the `hir_id_validator::check_crate` call above is not guaranteed
|
||||||
// to use `hir_crate`.
|
// to use `hir_crate_items`.
|
||||||
tcx.ensure_done().hir_crate(());
|
tcx.ensure_done().hir_crate_items(());
|
||||||
|
|
||||||
let sess = tcx.sess;
|
let sess = tcx.sess;
|
||||||
sess.time("misc_checking_1", || {
|
sess.time("misc_checking_1", || {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_hir::CRATE_OWNER_ID;
|
|
||||||
use rustc_middle::lint::LintExpectation;
|
use rustc_middle::lint::LintExpectation;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
@@ -18,7 +17,7 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
|
|||||||
|
|
||||||
let mut expectations = Vec::new();
|
let mut expectations = Vec::new();
|
||||||
|
|
||||||
for owner in std::iter::once(CRATE_OWNER_ID).chain(krate.owners()) {
|
for owner in krate.owners() {
|
||||||
let lints = tcx.shallow_lint_levels_on(owner);
|
let lints = tcx.shallow_lint_levels_on(owner);
|
||||||
expectations.extend_from_slice(&lints.expectations);
|
expectations.extend_from_slice(&lints.expectations);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -328,8 +328,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator of the `DefId`s for all body-owners in this
|
/// Returns an iterator of the `DefId`s for all body-owners in this
|
||||||
/// crate. If you would prefer to iterate over the bodies
|
/// crate.
|
||||||
/// themselves, you can do `self.hir_crate(()).body_ids.iter()`.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hir_body_owners(self) -> impl Iterator<Item = LocalDefId> {
|
pub fn hir_body_owners(self) -> impl Iterator<Item = LocalDefId> {
|
||||||
self.hir_crate_items(()).body_owners.iter().copied()
|
self.hir_crate_items(()).body_owners.iter().copied()
|
||||||
@@ -396,14 +395,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
where
|
where
|
||||||
V: Visitor<'tcx>,
|
V: Visitor<'tcx>,
|
||||||
{
|
{
|
||||||
let krate = self.hir_crate(());
|
let krate = self.hir_crate_items(());
|
||||||
for info in krate.owners.iter() {
|
for owner in krate.owners() {
|
||||||
if let MaybeOwner::Owner(info) = info {
|
let attrs = self.hir_attr_map(owner);
|
||||||
for attrs in info.attrs.map.values() {
|
for attrs in attrs.map.values() {
|
||||||
walk_list!(visitor, visit_attribute, *attrs);
|
walk_list!(visitor, visit_attribute, *attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
V::Result::output()
|
V::Result::output()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1225,6 +1223,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
|
|||||||
..
|
..
|
||||||
} = collector;
|
} = collector;
|
||||||
ModuleItems {
|
ModuleItems {
|
||||||
|
add_root: false,
|
||||||
submodules: submodules.into_boxed_slice(),
|
submodules: submodules.into_boxed_slice(),
|
||||||
free_items: items.into_boxed_slice(),
|
free_items: items.into_boxed_slice(),
|
||||||
trait_items: trait_items.into_boxed_slice(),
|
trait_items: trait_items.into_boxed_slice(),
|
||||||
@@ -1260,6 +1259,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
|
|||||||
} = collector;
|
} = collector;
|
||||||
|
|
||||||
ModuleItems {
|
ModuleItems {
|
||||||
|
add_root: true,
|
||||||
submodules: submodules.into_boxed_slice(),
|
submodules: submodules.into_boxed_slice(),
|
||||||
free_items: items.into_boxed_slice(),
|
free_items: items.into_boxed_slice(),
|
||||||
trait_items: trait_items.into_boxed_slice(),
|
trait_items: trait_items.into_boxed_slice(),
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ use crate::ty::{EarlyBinder, ImplSubject, TyCtxt};
|
|||||||
/// bodies. The Ids are in visitor order. This is used to partition a pass between modules.
|
/// bodies. The Ids are in visitor order. This is used to partition a pass between modules.
|
||||||
#[derive(Debug, HashStable, Encodable, Decodable)]
|
#[derive(Debug, HashStable, Encodable, Decodable)]
|
||||||
pub struct ModuleItems {
|
pub struct ModuleItems {
|
||||||
|
/// Whether this represents the whole crate, in which case we need to add `CRATE_OWNER_ID` to
|
||||||
|
/// the iterators if we want to account for the crate root.
|
||||||
|
add_root: bool,
|
||||||
submodules: Box<[OwnerId]>,
|
submodules: Box<[OwnerId]>,
|
||||||
free_items: Box<[ItemId]>,
|
free_items: Box<[ItemId]>,
|
||||||
trait_items: Box<[TraitItemId]>,
|
trait_items: Box<[TraitItemId]>,
|
||||||
@@ -66,9 +69,10 @@ impl ModuleItems {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn owners(&self) -> impl Iterator<Item = OwnerId> {
|
pub fn owners(&self) -> impl Iterator<Item = OwnerId> {
|
||||||
self.free_items
|
self.add_root
|
||||||
.iter()
|
.then_some(CRATE_OWNER_ID)
|
||||||
.map(|id| id.owner_id)
|
.into_iter()
|
||||||
|
.chain(self.free_items.iter().map(|id| id.owner_id))
|
||||||
.chain(self.trait_items.iter().map(|id| id.owner_id))
|
.chain(self.trait_items.iter().map(|id| id.owner_id))
|
||||||
.chain(self.impl_items.iter().map(|id| id.owner_id))
|
.chain(self.impl_items.iter().map(|id| id.owner_id))
|
||||||
.chain(self.foreign_items.iter().map(|id| id.owner_id))
|
.chain(self.foreign_items.iter().map(|id| id.owner_id))
|
||||||
|
|||||||
@@ -2113,7 +2113,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
|
) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
|
||||||
// Create a dependency to the crate to be sure we re-execute this when the amount of
|
// Create a dependency to the crate to be sure we re-execute this when the amount of
|
||||||
// definitions change.
|
// definitions change.
|
||||||
self.ensure_ok().hir_crate(());
|
self.ensure_ok().hir_crate_items(());
|
||||||
// Freeze definitions once we start iterating on them, to prevent adding new ones
|
// Freeze definitions once we start iterating on them, to prevent adding new ones
|
||||||
// while iterating. If some query needs to add definitions, it should be `ensure`d above.
|
// while iterating. If some query needs to add definitions, it should be `ensure`d above.
|
||||||
self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
|
self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
|
||||||
@@ -3160,42 +3160,33 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
lint_level(self.sess, lint, level, Some(span.into()), decorate);
|
lint_level(self.sess, lint, level, Some(span.into()), decorate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the crate root and the appropriate span where `use` and outer attributes can be
|
/// Find the appropriate span where `use` and outer attributes can be inserted at.
|
||||||
/// inserted at.
|
pub fn crate_level_attribute_injection_span(self) -> Span {
|
||||||
pub fn crate_level_attribute_injection_span(self, hir_id: HirId) -> Option<Span> {
|
let node = self.hir_node(hir::CRATE_HIR_ID);
|
||||||
for (_hir_id, node) in self.hir_parent_iter(hir_id) {
|
let hir::Node::Crate(m) = node else { bug!() };
|
||||||
if let hir::Node::Crate(m) = node {
|
m.spans.inject_use_span.shrink_to_lo()
|
||||||
return Some(m.spans.inject_use_span.shrink_to_lo());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
|
pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
|
||||||
self,
|
self,
|
||||||
diag: &mut Diag<'_, E>,
|
diag: &mut Diag<'_, E>,
|
||||||
hir_id: Option<HirId>,
|
|
||||||
features: impl IntoIterator<Item = (String, Symbol)>,
|
features: impl IntoIterator<Item = (String, Symbol)>,
|
||||||
) {
|
) {
|
||||||
if !self.sess.is_nightly_build() {
|
if !self.sess.is_nightly_build() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = hir_id.and_then(|id| self.crate_level_attribute_injection_span(id));
|
let span = self.crate_level_attribute_injection_span();
|
||||||
for (desc, feature) in features {
|
for (desc, feature) in features {
|
||||||
// FIXME: make this string translatable
|
// FIXME: make this string translatable
|
||||||
let msg =
|
let msg =
|
||||||
format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
|
format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
|
||||||
if let Some(span) = span {
|
|
||||||
diag.span_suggestion_verbose(
|
diag.span_suggestion_verbose(
|
||||||
span,
|
span,
|
||||||
msg,
|
msg,
|
||||||
format!("#![feature({feature})]\n"),
|
format!("#![feature({feature})]\n"),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
diag.help(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3575,11 +3575,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
ObligationCauseCode::TrivialBound => {
|
ObligationCauseCode::TrivialBound => {
|
||||||
err.help("see issue #48214");
|
err.help("see issue #48214");
|
||||||
tcx.disabled_nightly_features(
|
tcx.disabled_nightly_features(err, [(String::new(), sym::trivial_bounds)]);
|
||||||
err,
|
|
||||||
Some(tcx.local_def_id_to_hir_id(body_id)),
|
|
||||||
[(String::new(), sym::trivial_bounds)],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
ObligationCauseCode::OpaqueReturnType(expr_info) => {
|
ObligationCauseCode::OpaqueReturnType(expr_info) => {
|
||||||
let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info {
|
let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info {
|
||||||
|
|||||||
@@ -387,8 +387,6 @@ pub(crate) fn run_global_ctxt(
|
|||||||
ctxt.external_traits.insert(sized_trait_did, sized_trait);
|
ctxt.external_traits.insert(sized_trait_did, sized_trait);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("crate: {:?}", tcx.hir_crate(()));
|
|
||||||
|
|
||||||
let mut krate = tcx.sess.time("clean_crate", || clean::krate(&mut ctxt));
|
let mut krate = tcx.sess.time("clean_crate", || clean::krate(&mut ctxt));
|
||||||
|
|
||||||
if krate.module.doc_value().is_empty() {
|
if krate.module.doc_value().is_empty() {
|
||||||
|
|||||||
Reference in New Issue
Block a user