Skip to content

Commit b76bac2

Browse files
committed
Auto merge of rust-lang#134257 - matthiaskrgr:rollup-l8uh1ee, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#132038 (Add lint rule for `#[deprecated]` on re-exports) - 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#134211 (On Neutrino QNX, reduce the need to set archiver via environment variables) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4847d6a + 3149de6 commit b76bac2

File tree

34 files changed

+413
-207
lines changed

34 files changed

+413
-207
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+2-2
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

+66-4
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

+23-17
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

+14-80
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_passes/src/stability.rs

+3
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
411411
kind = AnnotationKind::DeprecationProhibited;
412412
const_stab_inherit = InheritConstStability::Yes;
413413
}
414+
hir::ItemKind::Use(_, _) => {
415+
kind = AnnotationKind::DeprecationProhibited;
416+
}
414417
hir::ItemKind::Struct(ref sd, _) => {
415418
if let Some(ctor_def_id) = sd.ctor_def_id() {
416419
self.annotate(

compiler/rustc_symbol_mangling/src/legacy.rs

+28-1
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

+1-1
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

+1-1
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/alloc/mod.rs

-5
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ pub use self::global::GlobalAlloc;
1010
#[stable(feature = "alloc_layout", since = "1.28.0")]
1111
pub use self::layout::Layout;
1212
#[stable(feature = "alloc_layout", since = "1.28.0")]
13-
#[deprecated(
14-
since = "1.52.0",
15-
note = "Name does not follow std convention, use LayoutError",
16-
suggestion = "LayoutError"
17-
)]
1813
#[allow(deprecated, deprecated_in_future)]
1914
pub use self::layout::LayoutErr;
2015
#[stable(feature = "alloc_layout_error", since = "1.50.0")]

0 commit comments

Comments
 (0)