Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #125436

Merged
merged 29 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4be041a
Also apply `warn(for_loops_over_fallibles)` to &T and &mut T, not jus…
zachs18 May 15, 2024
7d7eb97
Fix new for_loops_over_fallibles hits in compiler.
zachs18 May 15, 2024
77f288c
Include reference in lint diagnostic
zachs18 May 15, 2024
ea549fd
Add tests for 'Also apply `warn(for_loops_over_fallibles)` to &T and …
zachs18 May 15, 2024
0e46759
Fix more new for_loops_over_fallibles hits in compiler.
zachs18 May 15, 2024
66573b7
Use 'a' article for &Option.
zachs18 May 15, 2024
6b818dd
Fix article in test
zachs18 May 15, 2024
376a8c0
Allow for_loops_over_fallibles in test that tests &mut Result as Into…
zachs18 May 15, 2024
a59d071
Fix `for_loops_over_fallibles` hits in compiletest/src/json.rs
zachs18 May 16, 2024
3a21fb5
Wrap Context.ext in AssertUnwindSafe
workingjubilee May 22, 2024
8fde7e3
For OutsideLoop we should not suggest add 'block label in if block, o…
surechen Apr 8, 2024
5da41f5
self-contained linker: retry without -fuse-ld=lld on older GCCs
lqd May 22, 2024
c8844df
Clarify the meaning of the span within `mbe::TokenTree::MetaVar`.
nnethercote May 19, 2024
3fc8f89
Clarify `parse` a little.
nnethercote May 19, 2024
b6de782
Clarify a comment.
nnethercote May 16, 2024
c679a55
Convert some `token_joint_hidden` calls to `token_joint`.
nnethercote May 16, 2024
a1b6d46
Use `JointHidden` in a couple of suitable places.
nnethercote May 16, 2024
4d513cb
Add some comments.
nnethercote May 20, 2024
07b7cd6
Add some tests for public-private dependencies.
ehuss Mar 17, 2024
5f4424b
Handle `ReVar` in `note_and_explain_region`.
nnethercote May 12, 2024
ddb81ce
rewrite and rename issue-46239
Oneirical May 17, 2024
5ee8267
Rollup merge of #122665 - ehuss:pub-priv-tests, r=davidtwco
matthiaskrgr May 23, 2024
96134e1
Rollup merge of #123623 - surechen:fix_123261, r=estebank
matthiaskrgr May 23, 2024
72fd85c
Rollup merge of #125054 - nnethercote:fix-124973, r=compiler-errors
matthiaskrgr May 23, 2024
4af1c31
Rollup merge of #125156 - zachs18:for_loops_over_fallibles_behind_ref…
matthiaskrgr May 23, 2024
f131ee6
Rollup merge of #125222 - Oneirical:fifth, r=jieyouxu
matthiaskrgr May 23, 2024
3c79f0c
Rollup merge of #125316 - nnethercote:tweak-Spacing, r=petrochenkov
matthiaskrgr May 23, 2024
5126d4b
Rollup merge of #125392 - workingjubilee:unwind-a-problem-in-context,…
matthiaskrgr May 23, 2024
748647f
Rollup merge of #125417 - lqd:lld-retry, r=petrochenkov
matthiaskrgr May 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/tokenstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,11 +661,11 @@ impl TokenStream {
if attr_style == AttrStyle::Inner {
vec![
TokenTree::token_joint(token::Pound, span),
TokenTree::token_alone(token::Not, span),
TokenTree::token_joint_hidden(token::Not, span),
body,
]
} else {
vec![TokenTree::token_alone(token::Pound, span), body]
vec![TokenTree::token_joint_hidden(token::Pound, span), body]
}
}
}
Expand Down
40 changes: 29 additions & 11 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,22 +681,40 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
}
}

// The easiest way to implement token stream pretty printing would be to
// print each token followed by a single space. But that would produce ugly
// output, so we go to some effort to do better.
//
// First, we track whether each token that appears in source code is
// followed by a space, with `Spacing`, and reproduce that in the output.
// This works well in a lot of cases. E.g. `stringify!(x + y)` produces
// "x + y" and `stringify!(x+y)` produces "x+y".
//
// But this doesn't work for code produced by proc macros (which have no
// original source text representation) nor for code produced by decl
// macros (which are tricky because the whitespace after tokens appearing
// in macro rules isn't always what you want in the produced output). For
// these we mostly use `Spacing::Alone`, which is the conservative choice.
//
// So we have a backup mechanism for when `Spacing::Alone` occurs between a
// pair of tokens: we check if that pair of tokens can obviously go
// together without a space between them. E.g. token `x` followed by token
// `,` is better printed as `x,` than `x ,`. (Even if the original source
// code was `x ,`.)
//
// Finally, we must be careful about changing the output. Token pretty
// printing is used by `stringify!` and `impl Display for
// proc_macro::TokenStream`, and some programs rely on the output having a
// particular form, even though they shouldn't. In particular, some proc
// macros do `format!({stream})` on a token stream and then "parse" the
// output with simple string matching that can't handle whitespace changes.
// E.g. we have seen cases where a proc macro can handle `a :: b` but not
// `a::b`. See #117433 for some examples.
fn print_tts(&mut self, tts: &TokenStream, convert_dollar_crate: bool) {
let mut iter = tts.trees().peekable();
while let Some(tt) = iter.next() {
let spacing = self.print_tt(tt, convert_dollar_crate);
if let Some(next) = iter.peek() {
// Should we print a space after `tt`? There are two guiding
// factors.
// - `spacing` is the more important and accurate one. Most
// tokens have good spacing information, and
// `Joint`/`JointHidden` get used a lot.
// - `space_between` is the backup. Code produced by proc
// macros has worse spacing information, with no
// `JointHidden` usage and too much `Alone` usage, which
// would result in over-spaced output such as
// `( x () , y . z )`. `space_between` avoids some of the
// excess whitespace.
if spacing == Spacing::Alone && space_between(tt, next) {
self.space();
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_builtin_macros/src/assert/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
fn build_panic(&self, expr_str: &str, panic_path: Path) -> P<Expr> {
let escaped_expr_str = escape_to_fmt(expr_str);
let initial = [
TokenTree::token_joint_hidden(
TokenTree::token_joint(
token::Literal(token::Lit {
kind: token::LitKind::Str,
symbol: Symbol::intern(&if self.fmt_string.is_empty() {
Expand All @@ -172,7 +172,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
];
let captures = self.capture_decls.iter().flat_map(|cap| {
[
TokenTree::token_joint_hidden(
TokenTree::token_joint(
token::Ident(cap.ident.name, IdentIsRaw::No),
cap.ident.span,
),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_builtin_macros/src/deriving/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::deriving::generic::*;
use crate::errors;
use core::ops::ControlFlow;
use rustc_ast as ast;
use rustc_ast::visit::walk_list;
use rustc_ast::visit::visit_opt;
use rustc_ast::{attr, EnumDef, VariantData};
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
use rustc_span::symbol::Ident;
Expand Down Expand Up @@ -224,7 +224,7 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, '
self.visit_ident(v.ident);
self.visit_vis(&v.vis);
self.visit_variant_data(&v.data);
walk_list!(self, visit_anon_const, &v.disr_expr);
visit_opt!(self, visit_anon_const, &v.disr_expr);
for attr in &v.attrs {
rustc_ast::visit::walk_attribute(self, attr);
}
Expand Down
21 changes: 21 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,27 @@ fn link_natively(
continue;
}

// Check if linking failed with an error message that indicates the driver didn't recognize
// the `-fuse-ld=lld` option. If so, re-perform the link step without it. This avoids having
// to spawn multiple instances on the happy path to do version checking, and ensures things
// keep working on the tier 1 baseline of GLIBC 2.17+. That is generally understood as GCCs
// circa RHEL/CentOS 7, 4.5 or so, whereas lld support was added in GCC 9.
if matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, Lld::Yes))
&& unknown_arg_regex.is_match(&out)
&& out.contains("-fuse-ld=lld")
&& cmd.get_args().iter().any(|e| e.to_string_lossy() == "-fuse-ld=lld")
{
info!("linker output: {:?}", out);
warn!("The linker driver does not support `-fuse-ld=lld`. Retrying without it.");
for arg in cmd.take_args() {
if arg.to_string_lossy() != "-fuse-ld=lld" {
cmd.arg(arg);
}
}
info!("{:?}", &cmd);
continue;
}

// Detect '-static-pie' used with an older version of gcc or clang not supporting it.
// Fallback from '-static-pie' to '-static' in that case.
if matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_expand/src/mbe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,15 @@ pub(crate) enum KleeneOp {
/// `MetaVarExpr` are "first-class" token trees. Useful for parsing macros.
#[derive(Debug, PartialEq, Encodable, Decodable)]
enum TokenTree {
/// A token. Unlike `tokenstream::TokenTree::Token` this lacks a `Spacing`.
/// See the comments about `Spacing` in the `transcribe` function.
Token(Token),
/// A delimited sequence, e.g. `($e:expr)` (RHS) or `{ $e }` (LHS).
Delimited(DelimSpan, DelimSpacing, Delimited),
/// A kleene-style repetition sequence, e.g. `$($e:expr)*` (RHS) or `$($e),*` (LHS).
Sequence(DelimSpan, SequenceRepetition),
/// e.g., `$var`.
/// e.g., `$var`. The span covers the leading dollar and the ident. (The span within the ident
/// only covers the ident, e.g. `var`.)
MetaVar(Span, Ident),
/// e.g., `$var:expr`. Only appears on the LHS.
MetaVarDecl(Span, Ident /* name to bind */, Option<NonterminalKind>),
Expand Down
30 changes: 19 additions & 11 deletions compiler/rustc_expand/src/mbe/quoted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ pub(super) fn parse(
match tree {
TokenTree::MetaVar(start_sp, ident) if parsing_patterns => {
let span = match trees.next() {
Some(&tokenstream::TokenTree::Token(Token { kind: token::Colon, span }, _)) => {
Some(&tokenstream::TokenTree::Token(
Token { kind: token::Colon, span: colon_span },
_,
)) => {
match trees.next() {
Some(tokenstream::TokenTree::Token(token, _)) => match token.ident() {
Some((fragment, _)) => {
Expand Down Expand Up @@ -126,10 +129,12 @@ pub(super) fn parse(
}
_ => token.span,
},
tree => tree.map_or(span, tokenstream::TokenTree::span),
Some(tree) => tree.span(),
None => colon_span,
}
}
tree => tree.map_or(start_sp, tokenstream::TokenTree::span),
Some(tree) => tree.span(),
None => start_sp,
};

result.push(TokenTree::MetaVarDecl(span, ident, None));
Expand Down Expand Up @@ -176,7 +181,7 @@ fn parse_tree<'a>(
// Depending on what `tree` is, we could be parsing different parts of a macro
match tree {
// `tree` is a `$` token. Look at the next token in `trees`
&tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _) => {
&tokenstream::TokenTree::Token(Token { kind: token::Dollar, span: dollar_span }, _) => {
// FIXME: Handle `Invisible`-delimited groups in a more systematic way
// during parsing.
let mut next = outer_trees.next();
Expand Down Expand Up @@ -209,7 +214,7 @@ fn parse_tree<'a>(
err.emit();
// Returns early the same read `$` to avoid spanning
// unrelated diagnostics that could be performed afterwards
return TokenTree::token(token::Dollar, span);
return TokenTree::token(token::Dollar, dollar_span);
}
Ok(elem) => {
maybe_emit_macro_metavar_expr_feature(
Expand Down Expand Up @@ -251,7 +256,7 @@ fn parse_tree<'a>(
// special metavariable that names the crate of the invocation.
Some(tokenstream::TokenTree::Token(token, _)) if token.is_ident() => {
let (ident, is_raw) = token.ident().unwrap();
let span = ident.span.with_lo(span.lo());
let span = ident.span.with_lo(dollar_span.lo());
if ident.name == kw::Crate && matches!(is_raw, IdentIsRaw::No) {
TokenTree::token(token::Ident(kw::DollarCrate, is_raw), span)
} else {
Expand All @@ -260,16 +265,19 @@ fn parse_tree<'a>(
}

// `tree` is followed by another `$`. This is an escaped `$`.
Some(&tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _)) => {
Some(&tokenstream::TokenTree::Token(
Token { kind: token::Dollar, span: dollar_span2 },
_,
)) => {
if parsing_patterns {
span_dollar_dollar_or_metavar_in_the_lhs_err(
sess,
&Token { kind: token::Dollar, span },
&Token { kind: token::Dollar, span: dollar_span2 },
);
} else {
maybe_emit_macro_metavar_expr_feature(features, sess, span);
maybe_emit_macro_metavar_expr_feature(features, sess, dollar_span2);
}
TokenTree::token(token::Dollar, span)
TokenTree::token(token::Dollar, dollar_span2)
}

// `tree` is followed by some other token. This is an error.
Expand All @@ -281,7 +289,7 @@ fn parse_tree<'a>(
}

// There are no more tokens. Just return the `$` we already have.
None => TokenTree::token(token::Dollar, span),
None => TokenTree::token(token::Dollar, dollar_span),
}
}

Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_expand/src/mbe/transcribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,23 @@ pub(super) fn transcribe<'a>(
mbe::TokenTree::MetaVar(mut sp, mut original_ident) => {
// Find the matched nonterminal from the macro invocation, and use it to replace
// the meta-var.
//
// We use `Spacing::Alone` everywhere here, because that's the conservative choice
// and spacing of declarative macros is tricky. E.g. in this macro:
// ```
// macro_rules! idents {
// ($($a:ident,)*) => { stringify!($($a)*) }
// }
// ```
// `$a` has no whitespace after it and will be marked `JointHidden`. If you then
// call `idents!(x,y,z,)`, each of `x`, `y`, and `z` will be marked as `Joint`. So
// if you choose to use `$x`'s spacing or the identifier's spacing, you'll end up
// producing "xyz", which is bad because it effectively merges tokens.
// `Spacing::Alone` is the safer option. Fortunately, `space_between` will avoid
// some of the unnecessary whitespace.
let ident = MacroRulesNormalizedIdent::new(original_ident);
if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
// njn: explain the use of alone here
let tt = match cur_matched {
MatchedSingle(ParseNtResult::Tt(tt)) => {
// `tt`s are emitted into the output stream directly as "raw tokens",
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,10 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>>
use rustc_ast::token::*;

// The code below is conservative, using `token_alone`/`Spacing::Alone`
// in most places. When the resulting code is pretty-printed by
// `print_tts` it ends up with spaces between most tokens, which is
// safe but ugly. It's hard in general to do better when working at the
// token level.
// in most places. It's hard in general to do better when working at
// the token level. When the resulting code is pretty-printed by
// `print_tts` the `space_between` function helps avoid a lot of
// unnecessary whitespace, so the results aren't too bad.
let (tree, rustc) = self;
match tree {
TokenTree::Punct(Punct { ch, joint, span }) => {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html

use rustc_ast::visit::walk_list;
use rustc_ast::visit::visit_opt;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
Expand Down Expand Up @@ -168,7 +168,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => visitor.visit_stmt(statement),
}
}
walk_list!(visitor, visit_expr, &blk.expr);
visit_opt!(visitor, visit_expr, &blk.expr);
}

visitor.cx = prev_cx;
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,10 @@ pub(super) fn note_and_explain_region<'tcx>(

ty::ReError(_) => return,

ty::ReVar(_) | ty::ReBound(..) | ty::ReErased => {
// FIXME(#125431): `ReVar` shouldn't reach here.
ty::ReVar(_) => (format!("lifetime `{region}`"), alt_span),

ty::ReBound(..) | ty::ReErased => {
bug!("unexpected region for note_and_explain_region: {:?}", region);
}
};
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ lint_extern_without_abi = extern declarations without an explicit ABI are deprec
.help = the default ABI is {$default_abi}

lint_for_loops_over_fallibles =
for loop over {$article} `{$ty}`. This is more readably written as an `if let` statement
for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement
.suggestion = consider using `if let` to clear intent
.remove_next = to iterate over `{$recv_snip}` remove the call to `next`
.use_while_let = to check pattern in a loop use `while let`
Expand Down
17 changes: 15 additions & 2 deletions compiler/rustc_lint/src/for_loops_over_fallibles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,27 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {

let ty = cx.typeck_results().expr_ty(arg);

let &ty::Adt(adt, args) = ty.kind() else { return };
let (adt, args, ref_mutability) = match ty.kind() {
&ty::Adt(adt, args) => (adt, args, None),
&ty::Ref(_, ty, mutability) => match ty.kind() {
&ty::Adt(adt, args) => (adt, args, Some(mutability)),
_ => return,
},
_ => return,
};

let (article, ty, var) = match adt.did() {
did if cx.tcx.is_diagnostic_item(sym::Option, did) && ref_mutability.is_some() => ("a", "Option", "Some"),
did if cx.tcx.is_diagnostic_item(sym::Option, did) => ("an", "Option", "Some"),
did if cx.tcx.is_diagnostic_item(sym::Result, did) => ("a", "Result", "Ok"),
_ => return,
};

let ref_prefix = match ref_mutability {
None => "",
Some(ref_mutability) => ref_mutability.ref_prefix_str(),
};

let sub = if let Some(recv) = extract_iterator_next_call(cx, arg)
&& let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span)
{
Expand All @@ -85,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
cx.emit_span_lint(
FOR_LOOPS_OVER_FALLIBLES,
arg.span,
ForLoopsOverFalliblesDiag { article, ty, sub, question_mark, suggestion },
ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion },
);
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ pub enum PtrNullChecksDiag<'a> {
#[diag(lint_for_loops_over_fallibles)]
pub struct ForLoopsOverFalliblesDiag<'a> {
pub article: &'static str,
pub ref_prefix: &'static str,
pub ty: &'static str,
#[subdiagnostic]
pub sub: ForLoopsOverFalliblesLoopSub<'a>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
for subpattern in prefix.iter() {
self.visit_primary_bindings(subpattern, pattern_user_ty.clone().index(), f);
}
for subpattern in slice {
if let Some(subpattern) = slice {
self.visit_primary_bindings(
subpattern,
pattern_user_ty.clone().subslice(from, to),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ pub struct BreakInsideCoroutine<'a> {
pub struct OutsideLoop<'a> {
#[primary_span]
#[label]
pub span: Span,
pub spans: Vec<Span>,
pub name: &'a str,
pub is_break: bool,
#[subdiagnostic]
Expand All @@ -1112,7 +1112,7 @@ pub struct OutsideLoopSuggestion {
#[suggestion_part(code = "'block: ")]
pub block_span: Span,
#[suggestion_part(code = " 'block")]
pub break_span: Span,
pub break_spans: Vec<Span>,
}

#[derive(Diagnostic)]
Expand Down
Loading
Loading