Skip to content

Commit eda7820

Browse files
committed
Auto merge of rust-lang#138747 - matthiaskrgr:rollup-68x44rw, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#138435 (Add support for postfix yield expressions) - rust-lang#138685 (Use `Option<Ident>` for lowered param names.) - rust-lang#138700 (Suggest `-Whelp` when pass `--print lints` to rustc) - rust-lang#138727 (Do not rely on `type_var_origin` in `OrphanCheckErr::NonLocalInputType`) - rust-lang#138729 (Clean up `FnCtxt::resolve_coroutine_interiors`) - rust-lang#138731 (coverage: Add LLVM plumbing for expansion regions) - rust-lang#138732 (Use `def_path_str` for def id arg in `UnsupportedOpInfo`) - rust-lang#138735 (Remove `llvm` and `llvms` triagebot ping aliases for `icebreakers-llvm` ping group) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 78948ac + b79f816 commit eda7820

File tree

62 files changed

+499
-240
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+499
-240
lines changed

compiler/rustc_ast/src/ast.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,7 @@ pub enum ExprKind {
16571657
Try(P<Expr>),
16581658

16591659
/// A `yield`, with an optional value to be yielded.
1660-
Yield(Option<P<Expr>>),
1660+
Yield(YieldKind),
16611661

16621662
/// A `do yeet` (aka `throw`/`fail`/`bail`/`raise`/whatever),
16631663
/// with an optional value to be returned.
@@ -1903,6 +1903,44 @@ pub enum MatchKind {
19031903
Postfix,
19041904
}
19051905

1906+
/// The kind of yield expression
1907+
#[derive(Clone, Encodable, Decodable, Debug)]
1908+
pub enum YieldKind {
1909+
/// yield expr { ... }
1910+
Prefix(Option<P<Expr>>),
1911+
/// expr.yield { ... }
1912+
Postfix(P<Expr>),
1913+
}
1914+
1915+
impl YieldKind {
1916+
/// Returns the expression inside the yield expression, if any.
1917+
///
1918+
/// For postfix yields, this is guaranteed to be `Some`.
1919+
pub const fn expr(&self) -> Option<&P<Expr>> {
1920+
match self {
1921+
YieldKind::Prefix(expr) => expr.as_ref(),
1922+
YieldKind::Postfix(expr) => Some(expr),
1923+
}
1924+
}
1925+
1926+
/// Returns a mutable reference to the expression being yielded, if any.
1927+
pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
1928+
match self {
1929+
YieldKind::Prefix(expr) => expr.as_mut(),
1930+
YieldKind::Postfix(expr) => Some(expr),
1931+
}
1932+
}
1933+
1934+
/// Returns true if both yields are prefix or both are postfix.
1935+
pub const fn same_kind(&self, other: &Self) -> bool {
1936+
match (self, other) {
1937+
(YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
1938+
(YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
1939+
_ => false,
1940+
}
1941+
}
1942+
}
1943+
19061944
/// A literal in a meta item.
19071945
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
19081946
pub struct MetaItemLit {

compiler/rustc_ast/src/mut_visit.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1813,8 +1813,11 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token
18131813
ExprKind::Paren(expr) => {
18141814
vis.visit_expr(expr);
18151815
}
1816-
ExprKind::Yield(expr) => {
1817-
visit_opt(expr, |expr| vis.visit_expr(expr));
1816+
ExprKind::Yield(kind) => {
1817+
let expr = kind.expr_mut();
1818+
if let Some(expr) = expr {
1819+
vis.visit_expr(expr);
1820+
}
18181821
}
18191822
ExprKind::Try(expr) => vis.visit_expr(expr),
18201823
ExprKind::TryBlock(body) => vis.visit_block(body),

compiler/rustc_ast/src/util/classify.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,14 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
182182
| Range(_, Some(e), _)
183183
| Ret(Some(e))
184184
| Unary(_, e)
185-
| Yield(Some(e))
186185
| Yeet(Some(e))
187186
| Become(e) => {
188187
expr = e;
189188
}
189+
Yield(kind) => match kind.expr() {
190+
Some(e) => expr = e,
191+
None => break None,
192+
},
190193
Closure(closure) => {
191194
expr = &closure.body;
192195
}
@@ -217,7 +220,6 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
217220
Break(_, None)
218221
| Range(_, None, _)
219222
| Ret(None)
220-
| Yield(None)
221223
| Array(_)
222224
| Call(_, _)
223225
| MethodCall(_)
@@ -237,7 +239,9 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
237239
| Yeet(None)
238240
| UnsafeBinderCast(..)
239241
| Err(_)
240-
| Dummy => break None,
242+
| Dummy => {
243+
break None;
244+
}
241245
}
242246
}
243247
}

compiler/rustc_ast/src/visit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1269,8 +1269,8 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
12691269
try_visit!(visitor.visit_ty(container));
12701270
walk_list!(visitor, visit_ident, fields.iter());
12711271
}
1272-
ExprKind::Yield(optional_expression) => {
1273-
visit_opt!(visitor, visit_expr, optional_expression);
1272+
ExprKind::Yield(kind) => {
1273+
visit_opt!(visitor, visit_expr, kind.expr());
12741274
}
12751275
ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)),
12761276
ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)),

compiler/rustc_ast_lowering/src/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
351351
rest,
352352
)
353353
}
354-
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
354+
ExprKind::Yield(kind) => self.lower_expr_yield(e.span, kind.expr().map(|x| &**x)),
355355
ExprKind::Err(guar) => hir::ExprKind::Err(*guar),
356356

357357
ExprKind::UnsafeBinderCast(kind, expr, ty) => hir::ExprKind::UnsafeBinderCast(

compiler/rustc_ast_lowering/src/lib.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -1513,16 +1513,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15131513
}))
15141514
}
15151515

1516-
fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
1516+
fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
15171517
self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1518-
PatKind::Ident(_, ident, _) => self.lower_ident(ident),
1519-
PatKind::Wild => Ident::new(kw::Underscore, self.lower_span(param.pat.span)),
1518+
PatKind::Ident(_, ident, _) => {
1519+
if ident.name != kw::Empty {
1520+
Some(self.lower_ident(ident))
1521+
} else {
1522+
None
1523+
}
1524+
}
1525+
PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
15201526
_ => {
15211527
self.dcx().span_delayed_bug(
15221528
param.pat.span,
15231529
"non-ident/wild param pat must trigger an error",
15241530
);
1525-
Ident::new(kw::Empty, self.lower_span(param.pat.span))
1531+
None
15261532
}
15271533
}))
15281534
}

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
88
use rustc_ast::util::parser::{self, ExprPrecedence, Fixity};
99
use rustc_ast::{
1010
self as ast, BlockCheckMode, FormatAlignment, FormatArgPosition, FormatArgsPiece, FormatCount,
11-
FormatDebugHex, FormatSign, FormatTrait, token,
11+
FormatDebugHex, FormatSign, FormatTrait, YieldKind, token,
1212
};
1313

1414
use crate::pp::Breaks::Inconsistent;
@@ -761,7 +761,7 @@ impl<'a> State<'a> {
761761
self.print_expr(e, FixupContext::default());
762762
self.pclose();
763763
}
764-
ast::ExprKind::Yield(e) => {
764+
ast::ExprKind::Yield(YieldKind::Prefix(e)) => {
765765
self.word("yield");
766766

767767
if let Some(expr) = e {
@@ -773,6 +773,14 @@ impl<'a> State<'a> {
773773
);
774774
}
775775
}
776+
ast::ExprKind::Yield(YieldKind::Postfix(e)) => {
777+
self.print_expr_cond_paren(
778+
e,
779+
e.precedence() < ExprPrecedence::Unambiguous,
780+
fixup.leftmost_subexpression_with_dot(),
781+
);
782+
self.word(".yield");
783+
}
776784
ast::ExprKind::Try(e) => {
777785
self.print_expr_cond_paren(
778786
e,

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -2514,12 +2514,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
25142514
let ty::Tuple(params) = tupled_params.kind() else { return };
25152515

25162516
// Find the first argument with a matching type, get its name
2517-
let Some((_, this_name)) =
2518-
params.iter().zip(tcx.hir_body_param_names(closure.body)).find(|(param_ty, name)| {
2517+
let Some(this_name) = params.iter().zip(tcx.hir_body_param_names(closure.body)).find_map(
2518+
|(param_ty, name)| {
25192519
// FIXME: also support deref for stuff like `Rc` arguments
2520-
param_ty.peel_refs() == local_ty && name != &Ident::empty()
2521-
})
2522-
else {
2520+
if param_ty.peel_refs() == local_ty { name } else { None }
2521+
},
2522+
) else {
25232523
return;
25242524
};
25252525

@@ -3787,7 +3787,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
37873787
method_args,
37883788
*fn_span,
37893789
call_source.from_hir_call(),
3790-
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
3790+
self.infcx.tcx.fn_arg_names(method_did)[0],
37913791
)
37923792
{
37933793
err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));

compiler/rustc_borrowck/src/diagnostics/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1029,7 +1029,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
10291029
method_args,
10301030
*fn_span,
10311031
call_source.from_hir_call(),
1032-
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
1032+
self.infcx.tcx.fn_arg_names(method_did)[0],
10331033
);
10341034

10351035
return FnSelfUse {

compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ pub(crate) struct CoverageSpan {
146146
#[derive(Clone, Debug, Default)]
147147
pub(crate) struct Regions {
148148
pub(crate) code_regions: Vec<CodeRegion>,
149+
pub(crate) expansion_regions: Vec<ExpansionRegion>,
149150
pub(crate) branch_regions: Vec<BranchRegion>,
150151
pub(crate) mcdc_branch_regions: Vec<MCDCBranchRegion>,
151152
pub(crate) mcdc_decision_regions: Vec<MCDCDecisionRegion>,
@@ -154,10 +155,16 @@ pub(crate) struct Regions {
154155
impl Regions {
155156
/// Returns true if none of this structure's tables contain any regions.
156157
pub(crate) fn has_no_regions(&self) -> bool {
157-
let Self { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
158-
self;
158+
let Self {
159+
code_regions,
160+
expansion_regions,
161+
branch_regions,
162+
mcdc_branch_regions,
163+
mcdc_decision_regions,
164+
} = self;
159165

160166
code_regions.is_empty()
167+
&& expansion_regions.is_empty()
161168
&& branch_regions.is_empty()
162169
&& mcdc_branch_regions.is_empty()
163170
&& mcdc_decision_regions.is_empty()
@@ -172,6 +179,14 @@ pub(crate) struct CodeRegion {
172179
pub(crate) counter: Counter,
173180
}
174181

182+
/// Must match the layout of `LLVMRustCoverageExpansionRegion`.
183+
#[derive(Clone, Debug)]
184+
#[repr(C)]
185+
pub(crate) struct ExpansionRegion {
186+
pub(crate) cov_span: CoverageSpan,
187+
pub(crate) expanded_file_id: u32,
188+
}
189+
175190
/// Must match the layout of `LLVMRustCoverageBranchRegion`.
176191
#[derive(Clone, Debug)]
177192
#[repr(C)]

compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,18 @@ pub(crate) fn write_function_mappings_to_buffer(
6363
expressions: &[ffi::CounterExpression],
6464
regions: &ffi::Regions,
6565
) -> Vec<u8> {
66-
let ffi::Regions { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
67-
regions;
66+
let ffi::Regions {
67+
code_regions,
68+
expansion_regions,
69+
branch_regions,
70+
mcdc_branch_regions,
71+
mcdc_decision_regions,
72+
} = regions;
73+
74+
// SAFETY:
75+
// - All types are FFI-compatible and have matching representations in Rust/C++.
76+
// - For pointer/length pairs, the pointer and length come from the same vector or slice.
77+
// - C++ code does not retain any pointers after the call returns.
6878
llvm::build_byte_buffer(|buffer| unsafe {
6979
llvm::LLVMRustCoverageWriteFunctionMappingsToBuffer(
7080
virtual_file_mapping.as_ptr(),
@@ -73,6 +83,8 @@ pub(crate) fn write_function_mappings_to_buffer(
7383
expressions.len(),
7484
code_regions.as_ptr(),
7585
code_regions.len(),
86+
expansion_regions.as_ptr(),
87+
expansion_regions.len(),
7688
branch_regions.as_ptr(),
7789
branch_regions.len(),
7890
mcdc_branch_regions.as_ptr(),

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs

+17-16
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,22 @@ fn fill_region_tables<'tcx>(
120120
// Associate that global file ID with a local file ID for this function.
121121
let local_file_id = covfun.virtual_file_mapping.local_id_for_global(global_file_id);
122122

123-
let ffi::Regions { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
124-
&mut covfun.regions;
125-
126-
let make_cov_span =
127-
|span: Span| spans::make_coverage_span(local_file_id, source_map, &source_file, span);
123+
// In rare cases, _all_ of a function's spans are discarded, and coverage
124+
// codegen needs to handle that gracefully to avoid #133606.
125+
// It's hard for tests to trigger this organically, so instead we set
126+
// `-Zcoverage-options=discard-all-spans-in-codegen` to force it to occur.
128127
let discard_all = tcx.sess.coverage_discard_all_spans_in_codegen();
128+
let make_coords = |span: Span| {
129+
if discard_all { None } else { spans::make_coords(source_map, &source_file, span) }
130+
};
131+
132+
let ffi::Regions {
133+
code_regions,
134+
expansion_regions: _, // FIXME(Zalathar): Fill out support for expansion regions
135+
branch_regions,
136+
mcdc_branch_regions,
137+
mcdc_decision_regions,
138+
} = &mut covfun.regions;
129139

130140
// For each counter/region pair in this function+file, convert it to a
131141
// form suitable for FFI.
@@ -140,17 +150,8 @@ fn fill_region_tables<'tcx>(
140150
ffi::Counter::from_term(term)
141151
};
142152

143-
// Convert the `Span` into coordinates that we can pass to LLVM, or
144-
// discard the span if conversion fails. In rare, cases _all_ of a
145-
// function's spans are discarded, and the rest of coverage codegen
146-
// needs to handle that gracefully to avoid a repeat of #133606.
147-
// We don't have a good test case for triggering that organically, so
148-
// instead we set `-Zcoverage-options=discard-all-spans-in-codegen`
149-
// to force it to occur.
150-
let Some(cov_span) = make_cov_span(span) else { continue };
151-
if discard_all {
152-
continue;
153-
}
153+
let Some(coords) = make_coords(span) else { continue };
154+
let cov_span = coords.make_coverage_span(local_file_id);
154155

155156
match *kind {
156157
MappingKind::Code { bcb } => {

0 commit comments

Comments
 (0)