Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #117400

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
351d532
interpret: call caller_location logic the same way codegen does, and …
RalfJung Oct 28, 2023
04fa124
share the track_caller handling within a mir::Body
RalfJung Oct 28, 2023
552abdc
Rename a few remaining references to abort terminator
tmiasko Oct 29, 2023
4b14048
improve and fix x install
onur-ozkan Oct 30, 2023
745c600
Talk about `gen fn` in diagnostics about `gen fn`
oli-obk Oct 30, 2023
bc926f7
Add a custom panic message for resuming `gen` blocks after they panicked
oli-obk Oct 30, 2023
a2486db
Fix missing leading space in suggestion
gurry Oct 30, 2023
82f34fd
Fix #117284, Fix unused variables lint issue for args in macro
chenyukang Oct 30, 2023
972ee01
Add regression test
oli-obk Oct 30, 2023
8d03e13
Don't treat closures/coroutines as part of the public API
oli-obk Oct 30, 2023
251021c
Merge two equal match arms
oli-obk Oct 30, 2023
43ff2a7
Some manual rustfmt as rustfmt is broken on this file
oli-obk Oct 30, 2023
006e43c
Rollup merge of #117317 - RalfJung:track-caller, r=oli-obk
matthiaskrgr Oct 30, 2023
dfe0a6a
Rollup merge of #117357 - tmiasko:terminate, r=wesleywiser
matthiaskrgr Oct 30, 2023
b4269e1
Rollup merge of #117383 - onur-ozkan:fix-x-install, r=albertlarsan68
matthiaskrgr Oct 30, 2023
399aae3
Rollup merge of #117389 - oli-obk:gen_fn, r=compiler-errors
matthiaskrgr Oct 30, 2023
da5475b
Rollup merge of #117390 - chenyukang:yukang-fix-117284-unused-macro, …
matthiaskrgr Oct 30, 2023
7730b41
Rollup merge of #117395 - gurry:117380-wrong-parent-sugg, r=Nilstrieb
matthiaskrgr Oct 30, 2023
3f4edea
Rollup merge of #117396 - oli-obk:privacy_visitor_types, r=compiler-e…
matthiaskrgr Oct 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1640,7 +1640,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
TerminatorKind::UnwindTerminate(_) => {
if !is_cleanup {
span_mirbug!(self, block_data, "abort on non-cleanup block!")
span_mirbug!(self, block_data, "terminate on non-cleanup block!")
}
}
TerminatorKind::Return => {
Expand Down
46 changes: 5 additions & 41 deletions compiler/rustc_codegen_cranelift/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,47 +430,11 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
}
}

// Note: must be kept in sync with get_caller_location from cg_ssa
pub(crate) fn get_caller_location(&mut self, mut source_info: mir::SourceInfo) -> CValue<'tcx> {
let span_to_caller_location = |fx: &mut FunctionCx<'_, '_, 'tcx>, span: Span| {
use rustc_session::RemapFileNameExt;
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
let caller = fx.tcx.sess.source_map().lookup_char_pos(topmost.lo());
let const_loc = fx.tcx.const_caller_location((
rustc_span::symbol::Symbol::intern(
&caller.file.name.for_codegen(&fx.tcx.sess).to_string_lossy(),
),
caller.line as u32,
caller.col_display as u32 + 1,
));
crate::constant::codegen_const_value(fx, const_loc, fx.tcx.caller_location_ty())
};

// Walk up the `SourceScope`s, in case some of them are from MIR inlining.
// If so, the starting `source_info.span` is in the innermost inlined
// function, and will be replaced with outer callsite spans as long
// as the inlined functions were `#[track_caller]`.
loop {
let scope_data = &self.mir.source_scopes[source_info.scope];

if let Some((callee, callsite_span)) = scope_data.inlined {
// Stop inside the most nested non-`#[track_caller]` function,
// before ever reaching its caller (which is irrelevant).
if !callee.def.requires_caller_location(self.tcx) {
return span_to_caller_location(self, source_info.span);
}
source_info.span = callsite_span;
}

// Skip past all of the parents with `inlined: None`.
match scope_data.inlined_parent_scope {
Some(parent) => source_info.scope = parent,
None => break,
}
}

// No inlined `SourceScope`s, or all of them were `#[track_caller]`.
self.caller_location.unwrap_or_else(|| span_to_caller_location(self, source_info.span))
pub(crate) fn get_caller_location(&mut self, source_info: mir::SourceInfo) -> CValue<'tcx> {
self.mir.caller_location_span(source_info, self.caller_location, self.tcx, |span| {
let const_loc = self.tcx.span_as_caller_location(span);
crate::constant::codegen_const_value(self, const_loc, self.tcx.caller_location_ty())
})
}

pub(crate) fn anonymous_str(&mut self, msg: &str) -> Value {
Expand Down
43 changes: 4 additions & 39 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1449,47 +1449,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
fn get_caller_location(
&mut self,
bx: &mut Bx,
mut source_info: mir::SourceInfo,
source_info: mir::SourceInfo,
) -> OperandRef<'tcx, Bx::Value> {
let tcx = bx.tcx();

let mut span_to_caller_location = |span: Span| {
use rustc_session::RemapFileNameExt;
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
let caller = tcx.sess.source_map().lookup_char_pos(topmost.lo());
let const_loc = tcx.const_caller_location((
Symbol::intern(&caller.file.name.for_codegen(self.cx.sess()).to_string_lossy()),
caller.line as u32,
caller.col_display as u32 + 1,
));
self.mir.caller_location_span(source_info, self.caller_location, bx.tcx(), |span: Span| {
let const_loc = bx.tcx().span_as_caller_location(span);
OperandRef::from_const(bx, const_loc, bx.tcx().caller_location_ty())
};

// Walk up the `SourceScope`s, in case some of them are from MIR inlining.
// If so, the starting `source_info.span` is in the innermost inlined
// function, and will be replaced with outer callsite spans as long
// as the inlined functions were `#[track_caller]`.
loop {
let scope_data = &self.mir.source_scopes[source_info.scope];

if let Some((callee, callsite_span)) = scope_data.inlined {
// Stop inside the most nested non-`#[track_caller]` function,
// before ever reaching its caller (which is irrelevant).
if !callee.def.requires_caller_location(tcx) {
return span_to_caller_location(source_info.span);
}
source_info.span = callsite_span;
}

// Skip past all of the parents with `inlined: None`.
match scope_data.inlined_parent_scope {
Some(parent) => source_info.scope = parent,
None => break,
}
}

// No inlined `SourceScope`s, or all of them were `#[track_caller]`.
self.caller_location.unwrap_or_else(|| span_to_caller_location(source_info.span))
})
}

fn get_personality_slot(&mut self, bx: &mut Bx) -> PlaceRef<'tcx, Bx::Value> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
/// that inform us about the generic bounds of the constant. E.g., using an associated constant
/// of a function's generic parameter will require knowledge about the bounds on the generic
/// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument.
pub(super) fn mk_eval_cx<'mir, 'tcx>(
pub(crate) fn mk_eval_cx<'mir, 'tcx>(
tcx: TyCtxt<'tcx>,
root_span: Span,
param_env: ty::ParamEnv<'tcx>,
Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use rustc_middle::mir;
use rustc_middle::mir::interpret::PointerArithmetic;
use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout};
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::Span;
use std::borrow::Borrow;
use std::hash::Hash;
use std::ops::ControlFlow;
Expand Down Expand Up @@ -181,6 +182,24 @@ impl interpret::MayLeak for ! {
}

impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());

use rustc_session::{config::RemapPathScopeComponents, RemapFileNameExt};
(
Symbol::intern(
&caller
.file
.name
.for_scope(&self.tcx.sess, RemapPathScopeComponents::DIAGNOSTICS)
.to_string_lossy(),
),
u32::try_from(caller.line).unwrap(),
u32::try_from(caller.col_display).unwrap().checked_add(1).unwrap(),
)
}

/// "Intercept" a function call, because we have something special to do for it.
/// All `#[rustc_do_not_const_check]` functions should be hooked here.
/// If this returns `Some` function, which may be `instance` or a different function with
Expand Down
18 changes: 2 additions & 16 deletions compiler/rustc_const_eval/src/const_eval/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Not in interpret to make sure we do not use private implementation details

use crate::errors::MaxNumNodesInConstErr;
use crate::interpret::{intern_const_alloc_recursive, InternKind, InterpCx, Scalar};
use crate::interpret::InterpCx;
use rustc_middle::mir;
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::{source_map::DUMMY_SP, symbol::Symbol};
use rustc_span::source_map::DUMMY_SP;

mod error;
mod eval_queries;
Expand All @@ -20,20 +20,6 @@ pub use fn_queries::*;
pub use machine::*;
pub(crate) use valtrees::{const_to_valtree_inner, valtree_to_const_value};

pub(crate) fn const_caller_location(
tcx: TyCtxt<'_>,
(file, line, col): (Symbol, u32, u32),
) -> mir::ConstValue<'_> {
trace!("const_caller_location: {}:{}:{}", file, line, col);
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), CanAccessStatics::No);

let loc_place = ecx.alloc_caller_location(file, line, col);
if intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &loc_place).is_err() {
bug!("intern_const_alloc_recursive should not error in this case")
}
mir::ConstValue::Scalar(Scalar::from_maybe_pointer(loc_place.ptr(), &tcx))
}

// We forbid type-level constants that contain more than `VALTREE_MAX_NODES` nodes.
const VALTREE_MAX_NODES: usize = 100000;

Expand Down
44 changes: 44 additions & 0 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,50 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}

/// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
/// frame which is not `#[track_caller]`. This is the fancy version of `cur_span`.
pub(crate) fn find_closest_untracked_caller_location(&self) -> Span {
for frame in self.stack().iter().rev() {
debug!("find_closest_untracked_caller_location: checking frame {:?}", frame.instance);

// Assert that the frame we look at is actually executing code currently
// (`loc` is `Right` when we are unwinding and the frame does not require cleanup).
let loc = frame.loc.left().unwrap();

// This could be a non-`Call` terminator (such as `Drop`), or not a terminator at all
// (such as `box`). Use the normal span by default.
let mut source_info = *frame.body.source_info(loc);

// If this is a `Call` terminator, use the `fn_span` instead.
let block = &frame.body.basic_blocks[loc.block];
if loc.statement_index == block.statements.len() {
debug!(
"find_closest_untracked_caller_location: got terminator {:?} ({:?})",
block.terminator(),
block.terminator().kind,
);
if let mir::TerminatorKind::Call { fn_span, .. } = block.terminator().kind {
source_info.span = fn_span;
}
}

let caller_location = if frame.instance.def.requires_caller_location(*self.tcx) {
// We use `Err(())` as indication that we should continue up the call stack since
// this is a `#[track_caller]` function.
Some(Err(()))
} else {
None
};
if let Ok(span) =
frame.body.caller_location_span(source_info, caller_location, *self.tcx, Ok)
{
return span;
}
}

span_bug!(self.cur_span(), "no non-`#[track_caller]` frame found")
}

#[inline(always)]
pub fn layout_of_local(
&self,
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ use super::{

use crate::fluent_generated as fluent;

mod caller_location;

fn numeric_intrinsic<Prov>(name: Symbol, bits: u128, kind: Primitive) -> Scalar<Prov> {
let size = match kind {
Primitive::Int(integer, _) => integer.size(),
Expand Down Expand Up @@ -130,8 +128,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match intrinsic_name {
sym::caller_location => {
let span = self.find_closest_untracked_caller_location();
let location = self.alloc_caller_location_for_span(span);
self.write_immediate(location.to_ref(self), dest)?;
let val = self.tcx.span_as_caller_location(span);
let val =
self.const_val_to_op(val, self.tcx.caller_location_ty(), Some(dest.layout))?;
self.copy_op(&val, dest, /* allow_transmute */ false)?;
}

sym::min_align_of_val | sym::size_of_val => {
Expand Down
Loading