Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 354e098

Browse files
committedDec 14, 2024·
Auto merge of rust-lang#134282 - matthiaskrgr:rollup-txnn8yz, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#132150 (Fix powerpc64 big-endian FreeBSD ABI) - rust-lang#133633 (don't show the full linker args unless `--verbose` is passed) - rust-lang#133942 (Clarify how to use `black_box()`) - rust-lang#134081 (Try to evaluate constants in legacy mangling) - rust-lang#134192 (Remove `Lexer`'s dependency on `Parser`.) - rust-lang#134208 (coverage: Tidy up creation of covmap and covfun records) - rust-lang#134211 (On Neutrino QNX, reduce the need to set archiver via environment variables) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4a204be + 9668539 commit 354e098

File tree

28 files changed

+453
-263
lines changed

28 files changed

+453
-263
lines changed
 

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

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
7575

7676
// Encode all filenames referenced by coverage mappings in this CGU.
7777
let filenames_buffer = global_file_table.make_filenames_buffer(tcx);
78-
79-
let filenames_size = filenames_buffer.len();
80-
let filenames_val = cx.const_bytes(&filenames_buffer);
81-
let filenames_ref = llvm_cov::hash_bytes(&filenames_buffer);
78+
// The `llvm-cov` tool uses this hash to associate each covfun record with
79+
// its corresponding filenames table, since the final binary will typically
80+
// contain multiple covmap records from different compilation units.
81+
let filenames_hash = llvm_cov::hash_bytes(&filenames_buffer);
8282

8383
let mut unused_function_names = Vec::new();
8484

@@ -101,7 +101,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
101101
for covfun in &covfun_records {
102102
unused_function_names.extend(covfun.mangled_function_name_if_unused());
103103

104-
covfun::generate_covfun_record(cx, filenames_ref, covfun)
104+
covfun::generate_covfun_record(cx, filenames_hash, covfun)
105105
}
106106

107107
// For unused functions, we need to take their mangled names and store them
@@ -126,7 +126,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
126126
// Generate the coverage map header, which contains the filenames used by
127127
// this CGU's coverage mappings, and store it in a well-known global.
128128
// (This is skipped if we returned early due to having no covfun records.)
129-
generate_covmap_record(cx, covmap_version, filenames_size, filenames_val);
129+
generate_covmap_record(cx, covmap_version, &filenames_buffer);
130130
}
131131

132132
/// Maps "global" (per-CGU) file ID numbers to their underlying filenames.
@@ -225,38 +225,35 @@ fn span_file_name(tcx: TyCtxt<'_>, span: Span) -> Symbol {
225225
/// Generates the contents of the covmap record for this CGU, which mostly
226226
/// consists of a header and a list of filenames. The record is then stored
227227
/// as a global variable in the `__llvm_covmap` section.
228-
fn generate_covmap_record<'ll>(
229-
cx: &CodegenCx<'ll, '_>,
230-
version: u32,
231-
filenames_size: usize,
232-
filenames_val: &'ll llvm::Value,
233-
) {
234-
debug!("cov map: filenames_size = {}, 0-based version = {}", filenames_size, version);
235-
236-
// Create the coverage data header (Note, fields 0 and 2 are now always zero,
237-
// as of `llvm::coverage::CovMapVersion::Version4`.)
238-
let zero_was_n_records_val = cx.const_u32(0);
239-
let filenames_size_val = cx.const_u32(filenames_size as u32);
240-
let zero_was_coverage_size_val = cx.const_u32(0);
241-
let version_val = cx.const_u32(version);
242-
let cov_data_header_val = cx.const_struct(
243-
&[zero_was_n_records_val, filenames_size_val, zero_was_coverage_size_val, version_val],
244-
/*packed=*/ false,
228+
fn generate_covmap_record<'ll>(cx: &CodegenCx<'ll, '_>, version: u32, filenames_buffer: &[u8]) {
229+
// A covmap record consists of four target-endian u32 values, followed by
230+
// the encoded filenames table. Two of the header fields are unused in
231+
// modern versions of the LLVM coverage mapping format, and are always 0.
232+
// <https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation>
233+
// See also `src/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp`.
234+
let covmap_header = cx.const_struct(
235+
&[
236+
cx.const_u32(0), // (unused)
237+
cx.const_u32(filenames_buffer.len() as u32),
238+
cx.const_u32(0), // (unused)
239+
cx.const_u32(version),
240+
],
241+
/* packed */ false,
245242
);
246-
247-
// Create the complete LLVM coverage data value to add to the LLVM IR
248-
let covmap_data =
249-
cx.const_struct(&[cov_data_header_val, filenames_val], /*packed=*/ false);
250-
251-
let llglobal = llvm::add_global(cx.llmod, cx.val_ty(covmap_data), &llvm_cov::covmap_var_name());
252-
llvm::set_initializer(llglobal, covmap_data);
253-
llvm::set_global_constant(llglobal, true);
254-
llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
255-
llvm::set_section(llglobal, &llvm_cov::covmap_section_name(cx.llmod));
243+
let covmap_record = cx
244+
.const_struct(&[covmap_header, cx.const_bytes(filenames_buffer)], /* packed */ false);
245+
246+
let covmap_global =
247+
llvm::add_global(cx.llmod, cx.val_ty(covmap_record), &llvm_cov::covmap_var_name());
248+
llvm::set_initializer(covmap_global, covmap_record);
249+
llvm::set_global_constant(covmap_global, true);
250+
llvm::set_linkage(covmap_global, llvm::Linkage::PrivateLinkage);
251+
llvm::set_section(covmap_global, &llvm_cov::covmap_section_name(cx.llmod));
256252
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
257253
// <https://llvm.org/docs/CoverageMappingFormat.html>
258-
llvm::set_alignment(llglobal, Align::EIGHT);
259-
cx.add_used_global(llglobal);
254+
llvm::set_alignment(covmap_global, Align::EIGHT);
255+
256+
cx.add_used_global(covmap_global);
260257
}
261258

262259
/// Each CGU will normally only emit coverage metadata for the functions that it actually generates.

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

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ fn fill_region_tables<'tcx>(
136136
/// as a global variable in the `__llvm_covfun` section.
137137
pub(crate) fn generate_covfun_record<'tcx>(
138138
cx: &CodegenCx<'_, 'tcx>,
139-
filenames_ref: u64,
139+
filenames_hash: u64,
140140
covfun: &CovfunRecord<'tcx>,
141141
) {
142142
let &CovfunRecord {
@@ -155,46 +155,45 @@ pub(crate) fn generate_covfun_record<'tcx>(
155155
regions,
156156
);
157157

158-
// Concatenate the encoded coverage mappings
159-
let coverage_mapping_size = coverage_mapping_buffer.len();
160-
let coverage_mapping_val = cx.const_bytes(&coverage_mapping_buffer);
161-
158+
// A covfun record consists of four target-endian integers, followed by the
159+
// encoded mapping data in bytes. Note that the length field is 32 bits.
160+
// <https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation>
161+
// See also `src/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp` and
162+
// `COVMAP_V3` in `src/llvm-project/llvm/include/llvm/ProfileData/InstrProfData.inc`.
162163
let func_name_hash = llvm_cov::hash_bytes(mangled_function_name.as_bytes());
163-
let func_name_hash_val = cx.const_u64(func_name_hash);
164-
let coverage_mapping_size_val = cx.const_u32(coverage_mapping_size as u32);
165-
let source_hash_val = cx.const_u64(source_hash);
166-
let filenames_ref_val = cx.const_u64(filenames_ref);
167-
let func_record_val = cx.const_struct(
164+
let covfun_record = cx.const_struct(
168165
&[
169-
func_name_hash_val,
170-
coverage_mapping_size_val,
171-
source_hash_val,
172-
filenames_ref_val,
173-
coverage_mapping_val,
166+
cx.const_u64(func_name_hash),
167+
cx.const_u32(coverage_mapping_buffer.len() as u32),
168+
cx.const_u64(source_hash),
169+
cx.const_u64(filenames_hash),
170+
cx.const_bytes(&coverage_mapping_buffer),
174171
],
175-
/*packed=*/ true,
172+
// This struct needs to be packed, so that the 32-bit length field
173+
// doesn't have unexpected padding.
174+
true,
176175
);
177176

178177
// Choose a variable name to hold this function's covfun data.
179178
// Functions that are used have a suffix ("u") to distinguish them from
180179
// unused copies of the same function (from different CGUs), so that if a
181180
// linker sees both it won't discard the used copy's data.
182-
let func_record_var_name =
183-
CString::new(format!("__covrec_{:X}{}", func_name_hash, if is_used { "u" } else { "" }))
184-
.unwrap();
185-
debug!("function record var name: {:?}", func_record_var_name);
186-
187-
let llglobal = llvm::add_global(cx.llmod, cx.val_ty(func_record_val), &func_record_var_name);
188-
llvm::set_initializer(llglobal, func_record_val);
189-
llvm::set_global_constant(llglobal, true);
190-
llvm::set_linkage(llglobal, llvm::Linkage::LinkOnceODRLinkage);
191-
llvm::set_visibility(llglobal, llvm::Visibility::Hidden);
192-
llvm::set_section(llglobal, cx.covfun_section_name());
181+
let u = if is_used { "u" } else { "" };
182+
let covfun_var_name = CString::new(format!("__covrec_{func_name_hash:X}{u}")).unwrap();
183+
debug!("function record var name: {covfun_var_name:?}");
184+
185+
let covfun_global = llvm::add_global(cx.llmod, cx.val_ty(covfun_record), &covfun_var_name);
186+
llvm::set_initializer(covfun_global, covfun_record);
187+
llvm::set_global_constant(covfun_global, true);
188+
llvm::set_linkage(covfun_global, llvm::Linkage::LinkOnceODRLinkage);
189+
llvm::set_visibility(covfun_global, llvm::Visibility::Hidden);
190+
llvm::set_section(covfun_global, cx.covfun_section_name());
193191
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
194192
// <https://llvm.org/docs/CoverageMappingFormat.html>
195-
llvm::set_alignment(llglobal, Align::EIGHT);
193+
llvm::set_alignment(covfun_global, Align::EIGHT);
196194
if cx.target_spec().supports_comdat() {
197-
llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name);
195+
llvm::set_comdat(cx.llmod, covfun_global, &covfun_var_name);
198196
}
199-
cx.add_used_global(llglobal);
197+
198+
cx.add_used_global(covfun_global);
200199
}

‎compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -992,12 +992,12 @@ fn link_natively(
992992
let mut output = prog.stderr.clone();
993993
output.extend_from_slice(&prog.stdout);
994994
let escaped_output = escape_linker_output(&output, flavor);
995-
// FIXME: Add UI tests for this error.
996995
let err = errors::LinkingFailed {
997996
linker_path: &linker_path,
998997
exit_status: prog.status,
999-
command: &cmd,
998+
command: cmd,
1000999
escaped_output,
1000+
verbose: sess.opts.verbose,
10011001
};
10021002
sess.dcx().emit_err(err);
10031003
// If MSVC's `link.exe` was expected but the return code

‎compiler/rustc_codegen_ssa/src/errors.rs

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Errors emitted by codegen_ssa
22
33
use std::borrow::Cow;
4+
use std::ffi::OsString;
45
use std::io::Error;
56
use std::num::ParseIntError;
67
use std::path::{Path, PathBuf};
@@ -345,21 +346,82 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ThorinErrorWrapper {
345346
}
346347

347348
pub(crate) struct LinkingFailed<'a> {
348-
pub linker_path: &'a PathBuf,
349+
pub linker_path: &'a Path,
349350
pub exit_status: ExitStatus,
350-
pub command: &'a Command,
351+
pub command: Command,
351352
pub escaped_output: String,
353+
pub verbose: bool,
352354
}
353355

354356
impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
355-
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
357+
fn into_diag(mut self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
356358
let mut diag = Diag::new(dcx, level, fluent::codegen_ssa_linking_failed);
357359
diag.arg("linker_path", format!("{}", self.linker_path.display()));
358360
diag.arg("exit_status", format!("{}", self.exit_status));
359361

360362
let contains_undefined_ref = self.escaped_output.contains("undefined reference to");
361363

362-
diag.note(format!("{:?}", self.command)).note(self.escaped_output);
364+
if self.verbose {
365+
diag.note(format!("{:?}", self.command));
366+
} else {
367+
enum ArgGroup {
368+
Regular(OsString),
369+
Objects(usize),
370+
Rlibs(PathBuf, Vec<OsString>),
371+
}
372+
373+
// Omit rust object files and fold rlibs in the error by default to make linker errors a
374+
// bit less verbose.
375+
let orig_args = self.command.take_args();
376+
let mut args: Vec<ArgGroup> = vec![];
377+
for arg in orig_args {
378+
if arg.as_encoded_bytes().ends_with(b".rcgu.o") {
379+
if let Some(ArgGroup::Objects(n)) = args.last_mut() {
380+
*n += 1;
381+
} else {
382+
args.push(ArgGroup::Objects(1));
383+
}
384+
} else if arg.as_encoded_bytes().ends_with(b".rlib") {
385+
let rlib_path = Path::new(&arg);
386+
let dir = rlib_path.parent().unwrap();
387+
let filename = rlib_path.file_name().unwrap().to_owned();
388+
if let Some(ArgGroup::Rlibs(parent, rlibs)) = args.last_mut() {
389+
if parent == dir {
390+
rlibs.push(filename);
391+
} else {
392+
args.push(ArgGroup::Rlibs(dir.to_owned(), vec![filename]));
393+
}
394+
} else {
395+
args.push(ArgGroup::Rlibs(dir.to_owned(), vec![filename]));
396+
}
397+
} else {
398+
args.push(ArgGroup::Regular(arg));
399+
}
400+
}
401+
self.command.args(args.into_iter().map(|arg_group| match arg_group {
402+
ArgGroup::Regular(arg) => arg,
403+
ArgGroup::Objects(n) => OsString::from(format!("<{n} object files omitted>")),
404+
ArgGroup::Rlibs(dir, rlibs) => {
405+
let mut arg = dir.into_os_string();
406+
arg.push("/{");
407+
let mut first = true;
408+
for rlib in rlibs {
409+
if !first {
410+
arg.push(",");
411+
}
412+
first = false;
413+
arg.push(rlib);
414+
}
415+
arg.push("}");
416+
arg
417+
}
418+
}));
419+
420+
diag.note(format!("{:?}", self.command));
421+
diag.note("some arguments are omitted. use `--verbose` to show all linker arguments");
422+
}
423+
424+
diag.note(self.escaped_output);
363425

364426
// Trying to match an error from OS linkers
365427
// which by now we have no way to translate.

‎compiler/rustc_parse/src/lexer/mod.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,30 @@ pub(crate) fn lex_token_trees<'psess, 'src>(
6969
token: Token::dummy(),
7070
diag_info: TokenTreeDiagInfo::default(),
7171
};
72-
let (_open_spacing, stream, res) = lexer.lex_token_trees(/* is_delimited */ false);
73-
let unmatched_delims = lexer.diag_info.unmatched_delims;
74-
75-
if res.is_ok() && unmatched_delims.is_empty() {
76-
Ok(stream)
77-
} else {
78-
// Return error if there are unmatched delimiters or unclosed delimiters.
79-
// We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch
80-
// because the delimiter mismatch is more likely to be the root cause of error
81-
let mut buffer: Vec<_> = unmatched_delims
82-
.into_iter()
83-
.filter_map(|unmatched_delim| make_unclosed_delims_error(unmatched_delim, psess))
84-
.collect();
85-
if let Err(errs) = res {
86-
// Add unclosing delimiter or diff marker errors
87-
buffer.extend(errs);
72+
let res = lexer.lex_token_trees(/* is_delimited */ false);
73+
74+
let mut unmatched_delims: Vec<_> = lexer
75+
.diag_info
76+
.unmatched_delims
77+
.into_iter()
78+
.filter_map(|unmatched_delim| make_unclosed_delims_error(unmatched_delim, psess))
79+
.collect();
80+
81+
match res {
82+
Ok((_open_spacing, stream)) => {
83+
if unmatched_delims.is_empty() {
84+
Ok(stream)
85+
} else {
86+
// Return error if there are unmatched delimiters or unclosed delimiters.
87+
Err(unmatched_delims)
88+
}
89+
}
90+
Err(errs) => {
91+
// We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch
92+
// because the delimiter mismatch is more likely to be the root cause of error
93+
unmatched_delims.extend(errs);
94+
Err(unmatched_delims)
8895
}
89-
Err(buffer)
9096
}
9197
}
9298

‎compiler/rustc_parse/src/lexer/tokentrees.rs

Lines changed: 14 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
use rustc_ast::token::{self, Delimiter, Token};
22
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
33
use rustc_ast_pretty::pprust::token_to_string;
4-
use rustc_errors::{Applicability, Diag};
5-
use rustc_span::symbol::kw;
4+
use rustc_errors::Diag;
65

76
use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level};
87
use super::{Lexer, UnmatchedDelim};
9-
use crate::Parser;
108

119
impl<'psess, 'src> Lexer<'psess, 'src> {
1210
// Lex into a token stream. The `Spacing` in the result is that of the
1311
// opening delimiter.
1412
pub(super) fn lex_token_trees(
1513
&mut self,
1614
is_delimited: bool,
17-
) -> (Spacing, TokenStream, Result<(), Vec<Diag<'psess>>>) {
15+
) -> Result<(Spacing, TokenStream), Vec<Diag<'psess>>> {
1816
// Move past the opening delimiter.
1917
let open_spacing = self.bump_minimal();
2018

@@ -27,25 +25,25 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
2725
debug_assert!(!matches!(delim, Delimiter::Invisible(_)));
2826
buf.push(match self.lex_token_tree_open_delim(delim) {
2927
Ok(val) => val,
30-
Err(errs) => return (open_spacing, TokenStream::new(buf), Err(errs)),
28+
Err(errs) => return Err(errs),
3129
})
3230
}
3331
token::CloseDelim(delim) => {
3432
// Invisible delimiters cannot occur here because `TokenTreesReader` parses
3533
// code directly from strings, with no macro expansion involved.
3634
debug_assert!(!matches!(delim, Delimiter::Invisible(_)));
37-
return (
38-
open_spacing,
39-
TokenStream::new(buf),
40-
if is_delimited { Ok(()) } else { Err(vec![self.close_delim_err(delim)]) },
41-
);
35+
return if is_delimited {
36+
Ok((open_spacing, TokenStream::new(buf)))
37+
} else {
38+
Err(vec![self.close_delim_err(delim)])
39+
};
4240
}
4341
token::Eof => {
44-
return (
45-
open_spacing,
46-
TokenStream::new(buf),
47-
if is_delimited { Err(vec![self.eof_err()]) } else { Ok(()) },
48-
);
42+
return if is_delimited {
43+
Err(vec![self.eof_err()])
44+
} else {
45+
Ok((open_spacing, TokenStream::new(buf)))
46+
};
4947
}
5048
_ => {
5149
// Get the next normal token.
@@ -107,10 +105,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
107105
// Lex the token trees within the delimiters.
108106
// We stop at any delimiter so we can try to recover if the user
109107
// uses an incorrect delimiter.
110-
let (open_spacing, tts, res) = self.lex_token_trees(/* is_delimited */ true);
111-
if let Err(errs) = res {
112-
return Err(self.unclosed_delim_err(tts, errs));
113-
}
108+
let (open_spacing, tts) = self.lex_token_trees(/* is_delimited */ true)?;
114109

115110
// Expand to cover the entire delimited token tree.
116111
let delim_span = DelimSpan::from_pair(pre_span, self.token.span);
@@ -247,67 +242,6 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
247242
this_spacing
248243
}
249244

250-
fn unclosed_delim_err(
251-
&mut self,
252-
tts: TokenStream,
253-
mut errs: Vec<Diag<'psess>>,
254-
) -> Vec<Diag<'psess>> {
255-
// If there are unclosed delims, see if there are diff markers and if so, point them
256-
// out instead of complaining about the unclosed delims.
257-
let mut parser = Parser::new(self.psess, tts, None);
258-
let mut diff_errs = vec![];
259-
// Suggest removing a `{` we think appears in an `if`/`while` condition.
260-
// We want to suggest removing a `{` only if we think we're in an `if`/`while` condition,
261-
// but we have no way of tracking this in the lexer itself, so we piggyback on the parser.
262-
let mut in_cond = false;
263-
while parser.token != token::Eof {
264-
if let Err(diff_err) = parser.err_vcs_conflict_marker() {
265-
diff_errs.push(diff_err);
266-
} else if parser.is_keyword_ahead(0, &[kw::If, kw::While]) {
267-
in_cond = true;
268-
} else if matches!(
269-
parser.token.kind,
270-
token::CloseDelim(Delimiter::Brace) | token::FatArrow
271-
) {
272-
// End of the `if`/`while` body, or the end of a `match` guard.
273-
in_cond = false;
274-
} else if in_cond && parser.token == token::OpenDelim(Delimiter::Brace) {
275-
// Store the `&&` and `let` to use their spans later when creating the diagnostic
276-
let maybe_andand = parser.look_ahead(1, |t| t.clone());
277-
let maybe_let = parser.look_ahead(2, |t| t.clone());
278-
if maybe_andand == token::OpenDelim(Delimiter::Brace) {
279-
// This might be the beginning of the `if`/`while` body (i.e., the end of the
280-
// condition).
281-
in_cond = false;
282-
} else if maybe_andand == token::AndAnd && maybe_let.is_keyword(kw::Let) {
283-
let mut err = parser.dcx().struct_span_err(
284-
parser.token.span,
285-
"found a `{` in the middle of a let-chain",
286-
);
287-
err.span_suggestion(
288-
parser.token.span,
289-
"consider removing this brace to parse the `let` as part of the same chain",
290-
"",
291-
Applicability::MachineApplicable,
292-
);
293-
err.span_label(
294-
maybe_andand.span.to(maybe_let.span),
295-
"you might have meant to continue the let-chain here",
296-
);
297-
errs.push(err);
298-
}
299-
}
300-
parser.bump();
301-
}
302-
if !diff_errs.is_empty() {
303-
for err in errs {
304-
err.cancel();
305-
}
306-
return diff_errs;
307-
}
308-
errs
309-
}
310-
311245
fn close_delim_err(&mut self, delim: Delimiter) -> Diag<'psess> {
312246
// An unexpected closing delimiter (i.e., there is no matching opening delimiter).
313247
let token_str = token_to_string(&self.token);

‎compiler/rustc_symbol_mangling/src/legacy.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::fmt::{self, Write};
22
use std::mem::{self, discriminant};
33

44
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
5-
use rustc_hir::def_id::CrateNum;
5+
use rustc_hir::def_id::{CrateNum, DefId};
66
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
77
use rustc_middle::bug;
88
use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer};
@@ -378,6 +378,33 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
378378
Ok(())
379379
}
380380
}
381+
382+
fn print_impl_path(
383+
&mut self,
384+
impl_def_id: DefId,
385+
args: &'tcx [GenericArg<'tcx>],
386+
mut self_ty: Ty<'tcx>,
387+
mut impl_trait_ref: Option<ty::TraitRef<'tcx>>,
388+
) -> Result<(), PrintError> {
389+
let mut typing_env = ty::TypingEnv::post_analysis(self.tcx, impl_def_id);
390+
if !args.is_empty() {
391+
typing_env.param_env =
392+
ty::EarlyBinder::bind(typing_env.param_env).instantiate(self.tcx, args);
393+
}
394+
395+
match &mut impl_trait_ref {
396+
Some(impl_trait_ref) => {
397+
assert_eq!(impl_trait_ref.self_ty(), self_ty);
398+
*impl_trait_ref = self.tcx.normalize_erasing_regions(typing_env, *impl_trait_ref);
399+
self_ty = impl_trait_ref.self_ty();
400+
}
401+
None => {
402+
self_ty = self.tcx.normalize_erasing_regions(typing_env, self_ty);
403+
}
404+
}
405+
406+
self.default_print_impl_path(impl_def_id, args, self_ty, impl_trait_ref)
407+
}
381408
}
382409

383410
impl<'tcx> PrettyPrinter<'tcx> for SymbolPrinter<'tcx> {

‎compiler/rustc_target/src/callconv/powerpc64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ where
9999
Ty: TyAbiInterface<'a, C> + Copy,
100100
C: HasDataLayout + HasTargetSpec,
101101
{
102-
let abi = if cx.target_spec().env == "musl" {
102+
let abi = if cx.target_spec().env == "musl" || cx.target_spec().os == "freebsd" {
103103
ELFv2
104104
} else if cx.target_spec().os == "aix" {
105105
AIX

‎compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub(crate) fn target() -> Target {
1111
Target {
1212
llvm_target: "powerpc64-unknown-freebsd".into(),
1313
metadata: crate::spec::TargetMetadata {
14-
description: Some("PPC64 FreeBSD (ELFv1 and ELFv2)".into()),
14+
description: Some("PPC64 FreeBSD (ELFv2)".into()),
1515
tier: Some(3),
1616
host_tools: Some(true),
1717
std: Some(true),

‎library/core/src/hint.rs

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,13 +310,17 @@ pub fn spin_loop() {
310310
/// behavior in the calling code. This property makes `black_box` useful for writing code in which
311311
/// certain optimizations are not desired, such as benchmarks.
312312
///
313+
/// <div class="warning">
314+
///
313315
/// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The
314316
/// extent to which it can block optimisations may vary depending upon the platform and code-gen
315317
/// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the
316318
/// identity function. As such, it **must not be relied upon to control critical program behavior.**
317319
/// This also means that this function does not offer any guarantees for cryptographic or security
318320
/// purposes.
319321
///
322+
/// </div>
323+
///
320324
/// [`std::convert::identity`]: crate::convert::identity
321325
///
322326
/// # When is this useful?
@@ -357,7 +361,7 @@ pub fn spin_loop() {
357361
/// ```
358362
/// use std::hint::black_box;
359363
///
360-
/// // Same `contains` function
364+
/// // Same `contains` function.
361365
/// fn contains(haystack: &[&str], needle: &str) -> bool {
362366
/// haystack.iter().any(|x| x == &needle)
363367
/// }
@@ -366,8 +370,13 @@ pub fn spin_loop() {
366370
/// let haystack = vec!["abc", "def", "ghi", "jkl", "mno"];
367371
/// let needle = "ghi";
368372
/// for _ in 0..10 {
369-
/// // Adjust our benchmark loop contents
370-
/// black_box(contains(black_box(&haystack), black_box(needle)));
373+
/// // Force the compiler to run `contains`, even though it is a pure function whose
374+
/// // results are unused.
375+
/// black_box(contains(
376+
/// // Prevent the compiler from making assumptions about the input.
377+
/// black_box(&haystack),
378+
/// black_box(needle),
379+
/// ));
371380
/// }
372381
/// }
373382
/// ```
@@ -382,6 +391,83 @@ pub fn spin_loop() {
382391
///
383392
/// This makes our benchmark much more realistic to how the function would actually be used, where
384393
/// arguments are usually not known at compile time and the result is used in some way.
394+
///
395+
/// # How to use this
396+
///
397+
/// In practice, `black_box` serves two purposes:
398+
///
399+
/// 1. It prevents the compiler from making optimizations related to the value returned by `black_box`
400+
/// 2. It forces the value passed to `black_box` to be calculated, even if the return value of `black_box` is unused
401+
///
402+
/// ```
403+
/// use std::hint::black_box;
404+
///
405+
/// let zero = 0;
406+
/// let five = 5;
407+
///
408+
/// // The compiler will see this and remove the `* five` call, because it knows that multiplying
409+
/// // any integer by 0 will result in 0.
410+
/// let c = zero * five;
411+
///
412+
/// // Adding `black_box` here disables the compiler's ability to reason about the first operand in the multiplication.
413+
/// // It is forced to assume that it can be any possible number, so it cannot remove the `* five`
414+
/// // operation.
415+
/// let c = black_box(zero) * five;
416+
/// ```
417+
///
418+
/// While most cases will not be as clear-cut as the above example, it still illustrates how
419+
/// `black_box` can be used. When benchmarking a function, you usually want to wrap its inputs in
420+
/// `black_box` so the compiler cannot make optimizations that would be unrealistic in real-life
421+
/// use.
422+
///
423+
/// ```
424+
/// use std::hint::black_box;
425+
///
426+
/// // This is a simple function that increments its input by 1. Note that it is pure, meaning it
427+
/// // has no side-effects. This function has no effect if its result is unused. (An example of a
428+
/// // function *with* side-effects is `println!()`.)
429+
/// fn increment(x: u8) -> u8 {
430+
/// x + 1
431+
/// }
432+
///
433+
/// // Here, we call `increment` but discard its result. The compiler, seeing this and knowing that
434+
/// // `increment` is pure, will eliminate this function call entirely. This may not be desired,
435+
/// // though, especially if we're trying to track how much time `increment` takes to execute.
436+
/// let _ = increment(black_box(5));
437+
///
438+
/// // Here, we force `increment` to be executed. This is because the compiler treats `black_box`
439+
/// // as if it has side-effects, and thus must compute its input.
440+
/// let _ = black_box(increment(black_box(5)));
441+
/// ```
442+
///
443+
/// There may be additional situations where you want to wrap the result of a function in
444+
/// `black_box` to force its execution. This is situational though, and may not have any effect
445+
/// (such as when the function returns a zero-sized type such as [`()` unit][unit]).
446+
///
447+
/// Note that `black_box` has no effect on how its input is treated, only its output. As such,
448+
/// expressions passed to `black_box` may still be optimized:
449+
///
450+
/// ```
451+
/// use std::hint::black_box;
452+
///
453+
/// // The compiler sees this...
454+
/// let y = black_box(5 * 10);
455+
///
456+
/// // ...as this. As such, it will likely simplify `5 * 10` to just `50`.
457+
/// let _0 = 5 * 10;
458+
/// let y = black_box(_0);
459+
/// ```
460+
///
461+
/// In the above example, the `5 * 10` expression is considered distinct from the `black_box` call,
462+
/// and thus is still optimized by the compiler. You can prevent this by moving the multiplication
463+
/// operation outside of `black_box`:
464+
///
465+
/// ```
466+
/// use std::hint::black_box;
467+
///
468+
/// // No assumptions can be made about either operand, so the multiplication is not optimized out.
469+
/// let y = black_box(5) * black_box(10);
470+
/// ```
385471
#[inline]
386472
#[stable(feature = "bench_black_box", since = "1.66.0")]
387473
#[rustc_const_unstable(feature = "const_black_box", issue = "none")]

‎src/bootstrap/src/utils/cc_detect.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ fn cc2ar(cc: &Path, target: TargetSelection) -> Option<PathBuf> {
4444
Some(PathBuf::from("ar"))
4545
} else if target.contains("vxworks") {
4646
Some(PathBuf::from("wr-ar"))
47+
} else if target.contains("-nto-") {
48+
if target.starts_with("i586") {
49+
Some(PathBuf::from("ntox86-ar"))
50+
} else if target.starts_with("aarch64") {
51+
Some(PathBuf::from("ntoaarch64-ar"))
52+
} else if target.starts_with("x86_64") {
53+
Some(PathBuf::from("ntox86_64-ar"))
54+
} else {
55+
panic!("Unknown architecture, cannot determine archiver for Neutrino QNX");
56+
}
4757
} else if target.contains("android") || target.contains("-wasi") {
4858
Some(cc.parent().unwrap().join(PathBuf::from("llvm-ar")))
4959
} else {

‎src/doc/rustc/src/platform-support.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ target | std | host | notes
343343
[`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * | |
344344
[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | |
345345
[`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ | |
346-
`powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2)
346+
`powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv2)
347347
`powerpc64le-unknown-freebsd` | ✓ | ✓ | PPC64LE FreeBSD
348348
`powerpc-unknown-freebsd` | ? | | PowerPC FreeBSD
349349
`powerpc64-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3

‎src/tools/run-make-support/src/external_deps/rustc.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,12 @@ impl Rustc {
325325
self
326326
}
327327

328+
/// Pass the `--verbose` flag.
329+
pub fn verbose(&mut self) -> &mut Self {
330+
self.cmd.arg("--verbose");
331+
self
332+
}
333+
328334
/// `EXTRARSCXXFLAGS`
329335
pub fn extra_rs_cxx_flags(&mut self) -> &mut Self {
330336
// Adapted from tools.mk (trimmed):

‎tests/run-make/link-args-order/rmake.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,17 @@ fn main() {
1515
.link_args("b c")
1616
.link_args("d e")
1717
.link_arg("f")
18+
.arg("--print=link-args")
1819
.run_fail()
19-
.assert_stderr_contains(r#""a" "b" "c" "d" "e" "f""#);
20+
.assert_stdout_contains(r#""a" "b" "c" "d" "e" "f""#);
2021
rustc()
2122
.input("empty.rs")
2223
.linker_flavor(linker)
2324
.arg("-Zpre-link-arg=a")
2425
.arg("-Zpre-link-args=b c")
2526
.arg("-Zpre-link-args=d e")
2627
.arg("-Zpre-link-arg=f")
28+
.arg("--print=link-args")
2729
.run_fail()
28-
.assert_stderr_contains(r#""a" "b" "c" "d" "e" "f""#);
30+
.assert_stdout_contains(r#""a" "b" "c" "d" "e" "f""#);
2931
}

‎tests/run-make/link-dedup/rmake.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ fn main() {
1414
rustc().input("depb.rs").run();
1515
rustc().input("depc.rs").run();
1616

17-
let output = rustc().input("empty.rs").cfg("bar").run_fail();
18-
output.assert_stderr_contains(needle_from_libs(&["testa", "testb", "testa"]));
17+
let output = rustc().input("empty.rs").cfg("bar").arg("--print=link-args").run_fail();
18+
output.assert_stdout_contains(needle_from_libs(&["testa", "testb", "testa"]));
1919

20-
let output = rustc().input("empty.rs").run_fail();
21-
output.assert_stderr_contains(needle_from_libs(&["testa"]));
22-
output.assert_stderr_not_contains(needle_from_libs(&["testb"]));
23-
output.assert_stderr_not_contains(needle_from_libs(&["testa", "testa", "testa"]));
20+
let output = rustc().input("empty.rs").arg("--print=link-args").run_fail();
21+
output.assert_stdout_contains(needle_from_libs(&["testa"]));
22+
output.assert_stdout_not_contains(needle_from_libs(&["testb"]));
23+
output.assert_stdout_not_contains(needle_from_libs(&["testa", "testa", "testa"]));
2424
// Adjacent identical native libraries are no longer deduplicated if
2525
// they come from different crates (https://github.com/rust-lang/rust/pull/103311)
2626
// so the following will fail:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
fn main() {
2+
for arg in std::env::args() {
3+
match &*arg {
4+
"run_make_info" => println!("foo"),
5+
"run_make_warn" => eprintln!("warning: bar"),
6+
"run_make_error" => {
7+
eprintln!("error: baz");
8+
std::process::exit(1);
9+
}
10+
_ => (),
11+
}
12+
}
13+
}

‎tests/run-make/linker-warning/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use run_make_support::{Rustc, rustc};
2+
3+
fn run_rustc() -> Rustc {
4+
let mut rustc = rustc();
5+
rustc.arg("main.rs").output("main").linker("./fake-linker");
6+
rustc
7+
}
8+
9+
fn main() {
10+
// first, compile our linker
11+
rustc().arg("fake-linker.rs").output("fake-linker").run();
12+
13+
// Make sure we don't show the linker args unless `--verbose` is passed
14+
run_rustc()
15+
.link_arg("run_make_error")
16+
.verbose()
17+
.run_fail()
18+
.assert_stderr_contains_regex("fake-linker.*run_make_error")
19+
.assert_stderr_not_contains("object files omitted")
20+
.assert_stderr_contains_regex(r"lib[/\\]libstd");
21+
run_rustc()
22+
.link_arg("run_make_error")
23+
.run_fail()
24+
.assert_stderr_contains("fake-linker")
25+
.assert_stderr_contains("object files omitted")
26+
.assert_stderr_contains_regex(r"\{")
27+
.assert_stderr_not_contains_regex(r"lib[/\\]libstd");
28+
}

‎tests/ui/parser/brace-in-let-chain.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
#![feature(let_chains)]
44
fn main() {
55
if let () = ()
6-
&& let () = () { //~ERROR: found a `{` in the middle of a let-chain
6+
&& let () = () {
77
&& let () = ()
88
{
99
}
1010
}
1111

1212
fn quux() {
1313
while let () = ()
14-
&& let () = () { //~ERROR: found a `{` in the middle of a let-chain
14+
&& let () = () {
1515
&& let () = ()
1616
{
1717
}

‎tests/ui/parser/brace-in-let-chain.stderr

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,33 +27,5 @@ LL | }
2727
LL | }
2828
| ^
2929

30-
error: found a `{` in the middle of a let-chain
31-
--> $DIR/brace-in-let-chain.rs:14:24
32-
|
33-
LL | && let () = () {
34-
| ^
35-
LL | && let () = ()
36-
| ------ you might have meant to continue the let-chain here
37-
|
38-
help: consider removing this brace to parse the `let` as part of the same chain
39-
|
40-
LL - && let () = () {
41-
LL + && let () = ()
42-
|
43-
44-
error: found a `{` in the middle of a let-chain
45-
--> $DIR/brace-in-let-chain.rs:6:24
46-
|
47-
LL | && let () = () {
48-
| ^
49-
LL | && let () = ()
50-
| ------ you might have meant to continue the let-chain here
51-
|
52-
help: consider removing this brace to parse the `let` as part of the same chain
53-
|
54-
LL - && let () = () {
55-
LL + && let () = ()
56-
|
57-
58-
error: aborting due to 3 previous errors
30+
error: aborting due to 1 previous error
5931

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
// The diff marker detection was removed for this example, because it relied on
2+
// the lexer having a dependency on the parser, which was horrible.
3+
14
macro_rules! foo {
25
<<<<<<< HEAD
3-
//~^ ERROR encountered diff marker
46
() {
57
=======
68
() { //
79
>>>>>>> 7a4f13c blah blah blah
810
}
9-
}
11+
} //~ this file contains an unclosed delimiter
Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
1-
error: encountered diff marker
2-
--> $DIR/unclosed-delims-in-macro.rs:2:1
1+
error: this file contains an unclosed delimiter
2+
--> $DIR/unclosed-delims-in-macro.rs:11:48
33
|
4+
LL | macro_rules! foo {
5+
| - unclosed delimiter
46
LL | <<<<<<< HEAD
5-
| ^^^^^^^ between this marker and `=======` is the code that we're merging into
7+
LL | () {
8+
| - this delimiter might not be properly closed...
69
...
7-
LL | =======
8-
| ------- between this marker and `>>>>>>>` is the incoming code
9-
LL | () { //
10-
LL | >>>>>>> 7a4f13c blah blah blah
11-
| ^^^^^^^ this marker concludes the conflict region
12-
|
13-
= note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
14-
to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
15-
= help: if you're having merge conflicts after pulling new code:
16-
the top section is the code you already had and the bottom section is the remote code
17-
if you're in the middle of a rebase:
18-
the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased
19-
= note: for an explanation on these markers from the `git` documentation:
20-
visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>
10+
LL | }
11+
| - ^
12+
| |
13+
| ...as it matches this but it has different indentation
2114

2215
error: aborting due to 1 previous error
2316

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1+
// The diff marker detection was removed for this example, because it relied on
2+
// the lexer having a dependency on the parser, which was horrible.
3+
14
mod tests {
25
#[test]
36
<<<<<<< HEAD
4-
//~^ ERROR encountered diff marker
5-
//~| NOTE between this marker and `=======`
6-
7-
//~| NOTE conflict markers indicate that
8-
//~| HELP if you're having merge conflicts
9-
//~| NOTE for an explanation on these markers
10-
117
fn test1() {
128
=======
13-
//~^ NOTE between this marker and `>>>>>>>`
149
fn test2() {
1510
>>>>>>> 7a4f13c blah blah blah
16-
//~^ NOTE this marker concludes the conflict region
1711
}
18-
}
12+
} //~ this file contains an unclosed delimiter
Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
1-
error: encountered diff marker
2-
--> $DIR/unclosed-delims.rs:3:1
1+
error: this file contains an unclosed delimiter
2+
--> $DIR/unclosed-delims.rs:12:48
33
|
4-
LL | <<<<<<< HEAD
5-
| ^^^^^^^ between this marker and `=======` is the code that we're merging into
4+
LL | mod tests {
5+
| - unclosed delimiter
66
...
7-
LL | =======
8-
| ------- between this marker and `>>>>>>>` is the incoming code
7+
LL | fn test1() {
8+
| - this delimiter might not be properly closed...
99
...
10-
LL | >>>>>>> 7a4f13c blah blah blah
11-
| ^^^^^^^ this marker concludes the conflict region
12-
|
13-
= note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
14-
to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
15-
= help: if you're having merge conflicts after pulling new code:
16-
the top section is the code you already had and the bottom section is the remote code
17-
if you're in the middle of a rebase:
18-
the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased
19-
= note: for an explanation on these markers from the `git` documentation:
20-
visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>
10+
LL | }
11+
| - ^
12+
| |
13+
| ...as it matches this but it has different indentation
2114

2215
error: aborting due to 1 previous error
2316

‎tests/ui/symbol-names/types.legacy.stderr

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,5 +502,23 @@ error: demangling-alt(a::b::Type<[T; N]>)
502502
LL | #[rustc_symbol_name]
503503
| ^^^^^^^^^^^^^^^^^^^^
504504

505-
error: aborting due to 84 previous errors
505+
error: symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$17h[HASH]E)
506+
--> $DIR/types.rs:272:5
507+
|
508+
LL | #[rustc_symbol_name]
509+
| ^^^^^^^^^^^^^^^^^^^^
510+
511+
error: demangling(a::b::Type<[u8; 0]>::h[HASH])
512+
--> $DIR/types.rs:272:5
513+
|
514+
LL | #[rustc_symbol_name]
515+
| ^^^^^^^^^^^^^^^^^^^^
516+
517+
error: demangling-alt(a::b::Type<[u8; 0]>)
518+
--> $DIR/types.rs:272:5
519+
|
520+
LL | #[rustc_symbol_name]
521+
| ^^^^^^^^^^^^^^^^^^^^
522+
523+
error: aborting due to 87 previous errors
506524

‎tests/ui/symbol-names/types.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,17 @@ pub fn b() {
266266
//[v0]~| ERROR ::b::Type<[_; _]>>)
267267
//[v0]~| ERROR demangling-alt(<a::b::Type<[_; _]>>)
268268
impl<const N: usize, T> Type<[T; N]> {}
269+
270+
const ZERO: usize = 0;
271+
272+
#[rustc_symbol_name]
273+
//[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$
274+
//[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<[u8; 0]>::
275+
//[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<[u8; 0]>)
276+
//[v0]~^^^^ ERROR symbol-name(_RMsq_NvCsCRATE_HASH_1a1bINtB<REF>_4TypeAhj0_E)
277+
//[v0]~| ERROR ::b::Type<[u8; 0usize]>>)
278+
//[v0]~| ERROR demangling-alt(<a::b::Type<[u8; 0]>>)
279+
impl Type<[u8; ZERO]> {}
269280
}
270281

271282
fn main() {}

‎tests/ui/symbol-names/types.v0.stderr

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,5 +502,23 @@ error: demangling-alt(<a::b::Type<[_; _]>>)
502502
LL | #[rustc_symbol_name]
503503
| ^^^^^^^^^^^^^^^^^^^^
504504

505-
error: aborting due to 84 previous errors
505+
error: symbol-name(_RMsq_NvCsCRATE_HASH_1a1bINtB<REF>_4TypeAhj0_E)
506+
--> $DIR/types.rs:272:5
507+
|
508+
LL | #[rustc_symbol_name]
509+
| ^^^^^^^^^^^^^^^^^^^^
510+
511+
error: demangling(<a[HASH]::b::Type<[u8; 0usize]>>)
512+
--> $DIR/types.rs:272:5
513+
|
514+
LL | #[rustc_symbol_name]
515+
| ^^^^^^^^^^^^^^^^^^^^
516+
517+
error: demangling-alt(<a::b::Type<[u8; 0]>>)
518+
--> $DIR/types.rs:272:5
519+
|
520+
LL | #[rustc_symbol_name]
521+
| ^^^^^^^^^^^^^^^^^^^^
522+
523+
error: aborting due to 87 previous errors
506524

‎tests/ui/symbol-names/types.verbose-legacy.stderr

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,5 +502,23 @@ error: demangling-alt(a::b::Type<[T; N]>)
502502
LL | #[rustc_symbol_name]
503503
| ^^^^^^^^^^^^^^^^^^^^
504504

505-
error: aborting due to 84 previous errors
505+
error: symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$17h[HASH]E)
506+
--> $DIR/types.rs:272:5
507+
|
508+
LL | #[rustc_symbol_name]
509+
| ^^^^^^^^^^^^^^^^^^^^
510+
511+
error: demangling(a::b::Type<[u8; 0]>::h[HASH])
512+
--> $DIR/types.rs:272:5
513+
|
514+
LL | #[rustc_symbol_name]
515+
| ^^^^^^^^^^^^^^^^^^^^
516+
517+
error: demangling-alt(a::b::Type<[u8; 0]>)
518+
--> $DIR/types.rs:272:5
519+
|
520+
LL | #[rustc_symbol_name]
521+
| ^^^^^^^^^^^^^^^^^^^^
522+
523+
error: aborting due to 87 previous errors
506524

0 commit comments

Comments
 (0)
This repository has been archived.