mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
const-eval: make lint scope computation consistent
This commit is contained in:
parent
b316033dd8
commit
54e24c1573
@ -1,7 +1,6 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, Diagnostic, IntoDiagArg};
|
use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, Diagnostic, IntoDiagArg};
|
||||||
use rustc_hir::CRATE_HIR_ID;
|
|
||||||
use rustc_middle::mir::interpret::{Provenance, ReportedErrorInfo};
|
use rustc_middle::mir::interpret::{Provenance, ReportedErrorInfo};
|
||||||
use rustc_middle::mir::AssertKind;
|
use rustc_middle::mir::AssertKind;
|
||||||
use rustc_middle::query::TyCtxtAt;
|
use rustc_middle::query::TyCtxtAt;
|
||||||
@ -156,7 +155,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit a lint from a const-eval situation.
|
/// Emit a lint from a const-eval situation, with a backtrace.
|
||||||
// Even if this is unused, please don't remove it -- chances are we will need to emit a lint during const-eval again in the future!
|
// Even if this is unused, please don't remove it -- chances are we will need to emit a lint during const-eval again in the future!
|
||||||
pub(super) fn lint<'tcx, L>(
|
pub(super) fn lint<'tcx, L>(
|
||||||
tcx: TyCtxtAt<'tcx>,
|
tcx: TyCtxtAt<'tcx>,
|
||||||
@ -168,12 +167,5 @@ pub(super) fn lint<'tcx, L>(
|
|||||||
{
|
{
|
||||||
let (span, frames) = get_span_and_frames(tcx, &machine.stack);
|
let (span, frames) = get_span_and_frames(tcx, &machine.stack);
|
||||||
|
|
||||||
tcx.emit_node_span_lint(
|
tcx.emit_node_span_lint(lint, machine.best_lint_scope(*tcx), span, decorator(frames));
|
||||||
lint,
|
|
||||||
// We use the root frame for this so the crate that defines the const defines whether the
|
|
||||||
// lint is emitted.
|
|
||||||
machine.stack.first().and_then(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID),
|
|
||||||
span,
|
|
||||||
decorator(frames),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
|
|||||||
let err_diag = errors::MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind };
|
let err_diag = errors::MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind };
|
||||||
ecx.tcx.emit_node_span_lint(
|
ecx.tcx.emit_node_span_lint(
|
||||||
lint::builtin::CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
|
lint::builtin::CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
|
||||||
ecx.best_lint_scope(),
|
ecx.machine.best_lint_scope(*ecx.tcx),
|
||||||
err_diag.span,
|
err_diag.span,
|
||||||
err_diag,
|
err_diag,
|
||||||
)
|
)
|
||||||
|
@ -9,12 +9,13 @@ use rustc_data_structures::fx::IndexEntry;
|
|||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::LangItem;
|
use rustc_hir::LangItem;
|
||||||
|
use rustc_hir::{self as hir, CRATE_HIR_ID};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::mir::AssertMessage;
|
use rustc_middle::mir::AssertMessage;
|
||||||
use rustc_middle::query::TyCtxtAt;
|
use rustc_middle::query::TyCtxtAt;
|
||||||
use rustc_middle::ty;
|
|
||||||
use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout};
|
use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout};
|
||||||
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_session::lint::builtin::WRITES_THROUGH_IMMUTABLE_POINTER;
|
use rustc_session::lint::builtin::WRITES_THROUGH_IMMUTABLE_POINTER;
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
@ -369,6 +370,15 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> CompileTimeMachine<'tcx> {
|
||||||
|
#[inline(always)]
|
||||||
|
/// Find the first stack frame that is within the current crate, if any.
|
||||||
|
/// Otherwise, return the crate's HirId
|
||||||
|
pub fn best_lint_scope(&self, tcx: TyCtxt<'tcx>) -> hir::HirId {
|
||||||
|
self.stack.iter().find_map(|frame| frame.lint_root(tcx)).unwrap_or(CRATE_HIR_ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
||||||
compile_time_machine!(<'tcx>);
|
compile_time_machine!(<'tcx>);
|
||||||
|
|
||||||
@ -600,7 +610,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
|||||||
// By default, we stop after a million steps, but the user can disable this lint
|
// By default, we stop after a million steps, but the user can disable this lint
|
||||||
// to be able to run until the heat death of the universe or power loss, whichever
|
// to be able to run until the heat death of the universe or power loss, whichever
|
||||||
// comes first.
|
// comes first.
|
||||||
let hir_id = ecx.best_lint_scope();
|
let hir_id = ecx.machine.best_lint_scope(*ecx.tcx);
|
||||||
let is_error = ecx
|
let is_error = ecx
|
||||||
.tcx
|
.tcx
|
||||||
.lint_level_at_node(
|
.lint_level_at_node(
|
||||||
|
@ -4,7 +4,6 @@ use std::{fmt, mem};
|
|||||||
use either::{Either, Left, Right};
|
use either::{Either, Left, Right};
|
||||||
use tracing::{debug, info, info_span, instrument, trace};
|
use tracing::{debug, info, info_span, instrument, trace};
|
||||||
|
|
||||||
use hir::CRATE_HIR_ID;
|
|
||||||
use rustc_errors::DiagCtxt;
|
use rustc_errors::DiagCtxt;
|
||||||
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
|
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
@ -271,13 +270,18 @@ impl<'tcx, Prov: Provenance, Extra> Frame<'tcx, Prov, Extra> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lint_root(&self) -> Option<hir::HirId> {
|
pub fn lint_root(&self, tcx: TyCtxt<'tcx>) -> Option<hir::HirId> {
|
||||||
self.current_source_info().and_then(|source_info| {
|
// We first try to get a HirId via the current source scope,
|
||||||
match &self.body.source_scopes[source_info.scope].local_data {
|
// and fall back to `body.source`.
|
||||||
|
self.current_source_info()
|
||||||
|
.and_then(|source_info| match &self.body.source_scopes[source_info.scope].local_data {
|
||||||
mir::ClearCrossCrate::Set(data) => Some(data.lint_root),
|
mir::ClearCrossCrate::Set(data) => Some(data.lint_root),
|
||||||
mir::ClearCrossCrate::Clear => None,
|
mir::ClearCrossCrate::Clear => None,
|
||||||
}
|
})
|
||||||
})
|
.or_else(|| {
|
||||||
|
let def_id = self.body.source.def_id().as_local();
|
||||||
|
def_id.map(|def_id| tcx.local_def_id_to_hir_id(def_id))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the address of the buffer where the locals are stored. This is used by `Place` as a
|
/// Returns the address of the buffer where the locals are stored. This is used by `Place` as a
|
||||||
@ -509,17 +513,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||||||
self.stack().last().map_or(self.tcx.span, |f| f.current_span())
|
self.stack().last().map_or(self.tcx.span, |f| f.current_span())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the first stack frame that is within the current crate, if any;
|
|
||||||
/// otherwise return the crate's HirId.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn best_lint_scope(&self) -> hir::HirId {
|
|
||||||
self.stack()
|
|
||||||
.iter()
|
|
||||||
.find_map(|frame| frame.body.source.def_id().as_local())
|
|
||||||
.map_or(CRATE_HIR_ID, |def_id| self.tcx.local_def_id_to_hir_id(def_id))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub(crate) fn stack(&self) -> &[Frame<'tcx, M::Provenance, M::FrameExtra>] {
|
pub(crate) fn stack(&self) -> &[Frame<'tcx, M::Provenance, M::FrameExtra>] {
|
||||||
M::stack(self)
|
M::stack(self)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user