Skip to content

Commit e004adb

Browse files
committed
Auto merge of rust-lang#119069 - matthiaskrgr:rollup-xxk4m30, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#118852 (coverage: Skip instrumenting a function if no spans were extracted from MIR) - rust-lang#118905 ([AIX] Fix XCOFF metadata) - rust-lang#118967 (Add better ICE messages for some undescriptive panics) - rust-lang#119051 (Replace `FileAllocationInfo` with `FileEndOfFileInfo`) - rust-lang#119059 (Deny `~const` trait bounds in inherent impl headers) r? `@ghost` `@rustbot` modify labels: rollup
2 parents cda4736 + c088f6a commit e004adb

File tree

18 files changed

+162
-47
lines changed

18 files changed

+162
-47
lines changed

Diff for: compiler/rustc_ast_lowering/src/path.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_ast::{self as ast, *};
99
use rustc_hir as hir;
1010
use rustc_hir::def::{DefKind, PartialRes, Res};
1111
use rustc_hir::GenericArg;
12+
use rustc_middle::span_bug;
1213
use rustc_span::symbol::{kw, sym, Ident};
1314
use rustc_span::{BytePos, Span, DUMMY_SP};
1415

@@ -285,7 +286,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
285286
let (start, end) = match self.resolver.get_lifetime_res(segment_id) {
286287
Some(LifetimeRes::ElidedAnchor { start, end }) => (start, end),
287288
None => return,
288-
Some(_) => panic!(),
289+
Some(res) => {
290+
span_bug!(path_span, "expected an elided lifetime to insert. found {res:?}")
291+
}
289292
};
290293
let expected_lifetimes = end.as_usize() - start.as_usize();
291294
debug!(expected_lifetimes);

Diff for: compiler/rustc_ast_passes/messages.ftl

+2-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,8 @@ ast_passes_tilde_const_disallowed = `~const` is not allowed here
225225
.closure = closures cannot have `~const` trait bounds
226226
.function = this function is not `const`, so it cannot have `~const` trait bounds
227227
.trait = this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
228-
.impl = this impl is not `const`, so it cannot have `~const` trait bounds
228+
.trait_impl = this impl is not `const`, so it cannot have `~const` trait bounds
229+
.impl = inherent impls cannot have `~const` trait bounds
229230
.object = trait objects cannot have `~const` trait bounds
230231
.item = this item cannot have `~const` trait bounds
231232

Diff for: compiler/rustc_ast_passes/src/ast_validation.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum DisallowTildeConstContext<'a> {
4141
TraitObject,
4242
Fn(FnKind<'a>),
4343
Trait(Span),
44+
TraitImpl(Span),
4445
Impl(Span),
4546
Item,
4647
}
@@ -836,7 +837,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
836837
this.visit_vis(&item.vis);
837838
this.visit_ident(item.ident);
838839
let disallowed = matches!(constness, Const::No)
839-
.then(|| DisallowTildeConstContext::Impl(item.span));
840+
.then(|| DisallowTildeConstContext::TraitImpl(item.span));
840841
this.with_tilde_const(disallowed, |this| this.visit_generics(generics));
841842
this.visit_trait_ref(t);
842843
this.visit_ty(self_ty);
@@ -889,7 +890,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
889890

890891
self.visit_vis(&item.vis);
891892
self.visit_ident(item.ident);
892-
self.with_tilde_const(None, |this| this.visit_generics(generics));
893+
self.with_tilde_const(Some(DisallowTildeConstContext::Impl(item.span)), |this| {
894+
this.visit_generics(generics)
895+
});
893896
self.visit_ty(self_ty);
894897
walk_list!(self, visit_assoc_item, items, AssocCtxt::Impl);
895898
walk_list!(self, visit_attribute, &item.attrs);
@@ -1215,7 +1218,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12151218
&DisallowTildeConstContext::Trait(span) => {
12161219
errors::TildeConstReason::Trait { span }
12171220
}
1221+
&DisallowTildeConstContext::TraitImpl(span) => {
1222+
errors::TildeConstReason::TraitImpl { span }
1223+
}
12181224
&DisallowTildeConstContext::Impl(span) => {
1225+
// FIXME(effects): Consider providing a help message or even a structured
1226+
// suggestion for moving such bounds to the assoc const fns if available.
12191227
errors::TildeConstReason::Impl { span }
12201228
}
12211229
DisallowTildeConstContext::TraitObject => {

Diff for: compiler/rustc_ast_passes/src/errors.rs

+5
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,11 @@ pub enum TildeConstReason {
563563
#[primary_span]
564564
span: Span,
565565
},
566+
#[note(ast_passes_trait_impl)]
567+
TraitImpl {
568+
#[primary_span]
569+
span: Span,
570+
},
566571
#[note(ast_passes_impl)]
567572
Impl {
568573
#[primary_span]

Diff for: compiler/rustc_ast_pretty/src/pprust/state.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1597,7 +1597,9 @@ impl<'a> State<'a> {
15971597
}
15981598
match bound {
15991599
ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt),
1600-
_ => panic!(),
1600+
_ => {
1601+
panic!("expected a lifetime bound, found a trait bound")
1602+
}
16011603
}
16021604
}
16031605
}

Diff for: compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
8585

8686
let bx = self;
8787

88+
match coverage.kind {
89+
// Marker statements have no effect during codegen,
90+
// so return early and don't create `func_coverage`.
91+
CoverageKind::SpanMarker => return,
92+
// Match exhaustively to ensure that newly-added kinds are classified correctly.
93+
CoverageKind::CounterIncrement { .. } | CoverageKind::ExpressionUsed { .. } => {}
94+
}
95+
8896
let Some(function_coverage_info) =
8997
bx.tcx.instance_mir(instance.def).function_coverage_info.as_deref()
9098
else {
@@ -100,9 +108,9 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
100108

101109
let Coverage { kind } = coverage;
102110
match *kind {
103-
// Span markers are only meaningful during MIR instrumentation,
104-
// and have no effect during codegen.
105-
CoverageKind::SpanMarker => {}
111+
CoverageKind::SpanMarker => unreachable!(
112+
"unexpected marker statement {kind:?} should have caused an early return"
113+
),
106114
CoverageKind::CounterIncrement { id } => {
107115
func_coverage.mark_counter_id_seen(id);
108116
// We need to explicitly drop the `RefMut` before calling into `instrprof_increment`,

Diff for: compiler/rustc_codegen_ssa/src/back/metadata.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,13 @@ pub(super) fn get_metadata_xcoff<'a>(path: &Path, data: &'a [u8]) -> Result<&'a
158158
file.symbols().find(|sym| sym.name() == Ok(AIX_METADATA_SYMBOL_NAME))
159159
{
160160
let offset = metadata_symbol.address() as usize;
161-
if offset < 8 {
161+
// The offset specifies the location of rustc metadata in the .info section of XCOFF.
162+
// Each string stored in .info section of XCOFF is preceded by a 4-byte length field.
163+
if offset < 4 {
162164
return Err(format!("Invalid metadata symbol offset: {offset}"));
163165
}
164-
// The offset specifies the location of rustc metadata in the comment section.
165-
// The metadata is preceded by a 8-byte length field.
166-
let len = u64::from_le_bytes(info_data[(offset - 8)..offset].try_into().unwrap()) as usize;
166+
// XCOFF format uses big-endian byte order.
167+
let len = u32::from_be_bytes(info_data[(offset - 4)..offset].try_into().unwrap()) as usize;
167168
if offset + len > (info_data.len() as usize) {
168169
return Err(format!(
169170
"Metadata at offset {offset} with size {len} is beyond .info section"
@@ -478,9 +479,12 @@ pub fn create_wrapper_file(
478479
file.add_section(Vec::new(), b".text".to_vec(), SectionKind::Text);
479480
file.section_mut(section).flags =
480481
SectionFlags::Xcoff { s_flags: xcoff::STYP_INFO as u32 };
481-
482-
let len = data.len() as u64;
483-
let offset = file.append_section_data(section, &len.to_le_bytes(), 1);
482+
// Encode string stored in .info section of XCOFF.
483+
// FIXME: The length of data here is not guaranteed to fit in a u32.
484+
// We may have to split the data into multiple pieces in order to
485+
// store in .info section.
486+
let len: u32 = data.len().try_into().unwrap();
487+
let offset = file.append_section_data(section, &len.to_be_bytes(), 1);
484488
// Add a symbol referring to the data in .info section.
485489
file.add_symbol(Symbol {
486490
name: AIX_METADATA_SYMBOL_NAME.into(),
@@ -599,12 +603,12 @@ pub fn create_compressed_metadata_file_for_xcoff(
599603
section: SymbolSection::Section(data_section),
600604
flags: SymbolFlags::None,
601605
});
602-
let len = data.len() as u64;
603-
let offset = file.append_section_data(section, &len.to_le_bytes(), 1);
606+
let len: u32 = data.len().try_into().unwrap();
607+
let offset = file.append_section_data(section, &len.to_be_bytes(), 1);
604608
// Add a symbol referring to the rustc metadata.
605609
file.add_symbol(Symbol {
606610
name: AIX_METADATA_SYMBOL_NAME.into(),
607-
value: offset + 8, // The metadata is preceded by a 8-byte length field.
611+
value: offset + 4, // The metadata is preceded by a 4-byte length field.
608612
size: 0,
609613
kind: SymbolKind::Unknown,
610614
scope: SymbolScope::Dynamic,

Diff for: compiler/rustc_mir_transform/src/coverage/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,15 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
9999
fn inject_counters(&'a mut self) {
100100
////////////////////////////////////////////////////
101101
// Compute coverage spans from the `CoverageGraph`.
102-
let coverage_spans = CoverageSpans::generate_coverage_spans(
102+
let Some(coverage_spans) = CoverageSpans::generate_coverage_spans(
103103
self.mir_body,
104104
self.fn_sig_span,
105105
self.body_span,
106106
&self.basic_coverage_blocks,
107-
);
107+
) else {
108+
// No relevant spans were found in MIR, so skip instrumenting this function.
109+
return;
110+
};
108111

109112
////////////////////////////////////////////////////
110113
// Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure

Diff for: compiler/rustc_mir_transform/src/coverage/spans.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,34 @@ pub(super) struct CoverageSpans {
1515
}
1616

1717
impl CoverageSpans {
18+
/// Extracts coverage-relevant spans from MIR, and associates them with
19+
/// their corresponding BCBs.
20+
///
21+
/// Returns `None` if no coverage-relevant spans could be extracted.
1822
pub(super) fn generate_coverage_spans(
1923
mir_body: &mir::Body<'_>,
2024
fn_sig_span: Span,
2125
body_span: Span,
2226
basic_coverage_blocks: &CoverageGraph,
23-
) -> Self {
27+
) -> Option<Self> {
2428
let coverage_spans = CoverageSpansGenerator::generate_coverage_spans(
2529
mir_body,
2630
fn_sig_span,
2731
body_span,
2832
basic_coverage_blocks,
2933
);
3034

35+
if coverage_spans.is_empty() {
36+
return None;
37+
}
38+
3139
// Group the coverage spans by BCB, with the BCBs in sorted order.
3240
let mut bcb_to_spans = IndexVec::from_elem_n(Vec::new(), basic_coverage_blocks.num_nodes());
3341
for CoverageSpan { bcb, span, .. } in coverage_spans {
3442
bcb_to_spans[bcb].push(span);
3543
}
3644

37-
Self { bcb_to_spans }
45+
Some(Self { bcb_to_spans })
3846
}
3947

4048
pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool {

Diff for: compiler/rustc_span/src/caching_source_map_view.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl<'sm> CachingSourceMapView<'sm> {
117117
self.time_stamp += 1;
118118

119119
// Check if lo and hi are in the cached lines.
120-
let lo_cache_idx = self.cache_entry_index(span_data.lo);
120+
let lo_cache_idx: isize = self.cache_entry_index(span_data.lo);
121121
let hi_cache_idx = self.cache_entry_index(span_data.hi);
122122

123123
if lo_cache_idx != -1 && hi_cache_idx != -1 {
@@ -205,7 +205,9 @@ impl<'sm> CachingSourceMapView<'sm> {
205205
(lo_cache_idx as usize, oldest)
206206
}
207207
_ => {
208-
panic!();
208+
panic!(
209+
"the case of neither value being equal to -1 was handled above and the function returns."
210+
);
209211
}
210212
};
211213

Diff for: library/std/src/sys/windows/fs.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -309,14 +309,16 @@ impl File {
309309
&& unsafe { c::GetLastError() } == c::ERROR_ALREADY_EXISTS
310310
{
311311
unsafe {
312-
// Setting the allocation size to zero also sets the
313-
// EOF position to zero.
314-
let alloc = c::FILE_ALLOCATION_INFO { AllocationSize: 0 };
312+
// This originally used `FileAllocationInfo` instead of
313+
// `FileEndOfFileInfo` but that wasn't supported by WINE.
314+
// It's arguable which fits the semantics of `OpenOptions`
315+
// better so let's just use the more widely supported method.
316+
let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 };
315317
let result = c::SetFileInformationByHandle(
316318
handle.as_raw_handle(),
317-
c::FileAllocationInfo,
318-
ptr::addr_of!(alloc).cast::<c_void>(),
319-
mem::size_of::<c::FILE_ALLOCATION_INFO>() as u32,
319+
c::FileEndOfFileInfo,
320+
ptr::addr_of!(eof).cast::<c_void>(),
321+
mem::size_of::<c::FILE_END_OF_FILE_INFO>() as u32,
320322
);
321323
if result == 0 {
322324
return Err(io::Error::last_os_error());

Diff for: tests/coverage/no_spans_if_not.cov-map

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Function name: no_spans_if_not::main
2+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2)
8+

Diff for: tests/coverage/no_spans_if_not.coverage

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
LL| |// edition: 2021
2+
LL| |
3+
LL| |// If the span extractor can't find any relevant spans for a function,
4+
LL| |// but the function contains coverage span-marker statements (e.g. inserted
5+
LL| |// for `if !`), coverage codegen may think that it is instrumented and
6+
LL| |// consequently complain that it has no spans.
7+
LL| |//
8+
LL| |// Regression test for <https://github.com/rust-lang/rust/issues/118850>,
9+
LL| |// "A used function should have had coverage mapping data but did not".
10+
LL| |
11+
LL| 1|fn main() {
12+
LL| 1| affected_function();
13+
LL| 1|}
14+
LL| |
15+
LL| |macro_rules! macro_that_defines_a_function {
16+
LL| | (fn $name:ident () $body:tt) => {
17+
LL| | fn $name () $body
18+
LL| | }
19+
LL| |}
20+
LL| |
21+
LL| |macro_that_defines_a_function! {
22+
LL| | fn affected_function() {
23+
LL| | if !false {
24+
LL| | ()
25+
LL| | } else {
26+
LL| | ()
27+
LL| | }
28+
LL| | }
29+
LL| |}
30+

Diff for: tests/coverage/no_spans_if_not.rs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// edition: 2021
2+
3+
// If the span extractor can't find any relevant spans for a function,
4+
// but the function contains coverage span-marker statements (e.g. inserted
5+
// for `if !`), coverage codegen may think that it is instrumented and
6+
// consequently complain that it has no spans.
7+
//
8+
// Regression test for <https://github.com/rust-lang/rust/issues/118850>,
9+
// "A used function should have had coverage mapping data but did not".
10+
11+
fn main() {
12+
affected_function();
13+
}
14+
15+
macro_rules! macro_that_defines_a_function {
16+
(fn $name:ident () $body:tt) => {
17+
fn $name () $body
18+
}
19+
}
20+
21+
macro_that_defines_a_function! {
22+
fn affected_function() {
23+
if !false {
24+
()
25+
} else {
26+
()
27+
}
28+
}
29+
}

Diff for: tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs

+3
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,7 @@ trait Child1 where Self: ~const Trait {} //~ ERROR `~const` is not allowed
5252
// non-const impl
5353
impl<T: ~const Trait> Trait for T {} //~ ERROR `~const` is not allowed
5454

55+
// inherent impl (regression test for issue #117004)
56+
impl<T: ~const Trait> Struct<T> {} //~ ERROR `~const` is not allowed
57+
5558
fn main() {}

Diff for: tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,18 @@ note: this impl is not `const`, so it cannot have `~const` trait bounds
194194
LL | impl<T: ~const Trait> Trait for T {}
195195
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
196196

197+
error: `~const` is not allowed here
198+
--> $DIR/tilde-const-invalid-places.rs:56:9
199+
|
200+
LL | impl<T: ~const Trait> Struct<T> {}
201+
| ^^^^^^
202+
|
203+
note: inherent impls cannot have `~const` trait bounds
204+
--> $DIR/tilde-const-invalid-places.rs:56:1
205+
|
206+
LL | impl<T: ~const Trait> Struct<T> {}
207+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
208+
197209
error[E0658]: generic const items are experimental
198210
--> $DIR/tilde-const-invalid-places.rs:19:15
199211
|
@@ -239,6 +251,6 @@ LL | type Type<T: ~const Trait> = ();
239251
= note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
240252
= help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
241253

242-
error: aborting due to 26 previous errors
254+
error: aborting due to 27 previous errors
243255

244256
For more information about this error, try `rustc --explain E0658`.

Diff for: tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// known-bug: #110395
2-
// FIXME check-pass
1+
// check-pass
32
#![feature(const_trait_impl, effects)]
43

54
#[const_trait]
@@ -9,8 +8,8 @@ trait Foo {
98

109
struct Bar<T>(T);
1110

12-
impl<T: ~const Foo> Bar<T> {
13-
const fn foo(&self) {
11+
impl<T> Bar<T> {
12+
const fn foo(&self) where T: ~const Foo {
1413
self.0.foo()
1514
}
1615
}

0 commit comments

Comments
 (0)