Skip to content

Commit 7f2863f

Browse files
committed
Auto merge of rust-lang#119565 - compiler-errors:rollup-mqab1vy, r=compiler-errors
Rollup of 10 pull requests Successful merges: - rust-lang#118521 (Enable address sanitizer for MSVC targets using INFERASANLIBS linker flag) - rust-lang#119026 (std::net::bind using -1 for openbsd which in turn sets it to somaxconn.) - rust-lang#119195 (Make named_asm_labels lint not trigger on unicode and trigger on format args) - rust-lang#119204 (macro_rules: Less hacky heuristic for using `tt` metavariable spans) - rust-lang#119362 (Make `derive(Trait)` suggestion more accurate) - rust-lang#119397 (Recover parentheses in range patterns) - rust-lang#119414 (bootstrap: Move -Clto= setting from Rustc::run to rustc_cargo) - rust-lang#119417 (Uplift some miscellaneous coroutine-specific machinery into `check_closure`) - rust-lang#119540 (Don't synthesize host effect args inside trait object types) - rust-lang#119555 (Add codegen test for RVO on MaybeUninit) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 090d5ea + 4880f2b commit 7f2863f

Some content is hidden

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

54 files changed

+789
-376
lines changed

compiler/rustc_ast/src/tokenstream.rs

+1-22
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc_span::{sym, Span, Symbol, DUMMY_SP};
2626
use smallvec::{smallvec, SmallVec};
2727

2828
use std::borrow::Cow;
29-
use std::{cmp, fmt, iter, mem};
29+
use std::{cmp, fmt, iter};
3030

3131
/// When the main Rust parser encounters a syntax-extension invocation, it
3232
/// parses the arguments to the invocation as a token tree. This is a very
@@ -81,14 +81,6 @@ impl TokenTree {
8181
}
8282
}
8383

84-
/// Modify the `TokenTree`'s span in-place.
85-
pub fn set_span(&mut self, span: Span) {
86-
match self {
87-
TokenTree::Token(token, _) => token.span = span,
88-
TokenTree::Delimited(dspan, ..) => *dspan = DelimSpan::from_single(span),
89-
}
90-
}
91-
9284
/// Create a `TokenTree::Token` with alone spacing.
9385
pub fn token_alone(kind: TokenKind, span: Span) -> TokenTree {
9486
TokenTree::Token(Token::new(kind, span), Spacing::Alone)
@@ -461,19 +453,6 @@ impl TokenStream {
461453
t1.next().is_none() && t2.next().is_none()
462454
}
463455

464-
/// Applies the supplied function to each `TokenTree` and its index in `self`, returning a new `TokenStream`
465-
///
466-
/// It is equivalent to `TokenStream::new(self.trees().cloned().enumerate().map(|(i, tt)| f(i, tt)).collect())`.
467-
pub fn map_enumerated_owned(
468-
mut self,
469-
mut f: impl FnMut(usize, TokenTree) -> TokenTree,
470-
) -> TokenStream {
471-
let owned = Lrc::make_mut(&mut self.0); // clone if necessary
472-
// rely on vec's in-place optimizations to avoid another allocation
473-
*owned = mem::take(owned).into_iter().enumerate().map(|(i, tree)| f(i, tree)).collect();
474-
self
475-
}
476-
477456
/// Create a token stream containing a single token with alone spacing. The
478457
/// spacing used for the final token in a constructed stream doesn't matter
479458
/// because it's never used. In practice we arbitrarily use

compiler/rustc_ast_lowering/src/lib.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -1434,19 +1434,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14341434
let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
14351435
let bounds =
14361436
this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1437-
GenericBound::Trait(
1438-
ty,
1439-
TraitBoundModifiers {
1440-
polarity: BoundPolarity::Positive | BoundPolarity::Negative(_),
1441-
constness,
1442-
},
1443-
) => Some(this.lower_poly_trait_ref(ty, itctx, *constness)),
1444-
// We can safely ignore constness here, since AST validation
1445-
// will take care of invalid modifier combinations.
1446-
GenericBound::Trait(
1447-
_,
1448-
TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. },
1449-
) => None,
1437+
// We can safely ignore constness here since AST validation
1438+
// takes care of rejecting invalid modifier combinations and
1439+
// const trait bounds in trait object types.
1440+
GenericBound::Trait(ty, modifiers) => match modifiers.polarity {
1441+
BoundPolarity::Positive | BoundPolarity::Negative(_) => {
1442+
Some(this.lower_poly_trait_ref(
1443+
ty,
1444+
itctx,
1445+
// Still, don't pass along the constness here; we don't want to
1446+
// synthesize any host effect args, it'd only cause problems.
1447+
ast::BoundConstness::Never,
1448+
))
1449+
}
1450+
BoundPolarity::Maybe(_) => None,
1451+
},
14501452
GenericBound::Outlives(lifetime) => {
14511453
if lifetime_bound.is_none() {
14521454
lifetime_bound = Some(this.lower_lifetime(lifetime));

compiler/rustc_codegen_ssa/src/back/link.rs

+30-14
Original file line numberDiff line numberDiff line change
@@ -1186,15 +1186,22 @@ mod win {
11861186
}
11871187
}
11881188

1189-
fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) {
1190-
// On macOS the runtimes are distributed as dylibs which should be linked to
1191-
// both executables and dynamic shared objects. Everywhere else the runtimes
1192-
// are currently distributed as static libraries which should be linked to
1193-
// executables only.
1189+
fn add_sanitizer_libraries(
1190+
sess: &Session,
1191+
flavor: LinkerFlavor,
1192+
crate_type: CrateType,
1193+
linker: &mut dyn Linker,
1194+
) {
1195+
// On macOS and Windows using MSVC the runtimes are distributed as dylibs
1196+
// which should be linked to both executables and dynamic libraries.
1197+
// Everywhere else the runtimes are currently distributed as static
1198+
// libraries which should be linked to executables only.
11941199
let needs_runtime = !sess.target.is_like_android
11951200
&& match crate_type {
11961201
CrateType::Executable => true,
1197-
CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => sess.target.is_like_osx,
1202+
CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => {
1203+
sess.target.is_like_osx || sess.target.is_like_msvc
1204+
}
11981205
CrateType::Rlib | CrateType::Staticlib => false,
11991206
};
12001207

@@ -1204,26 +1211,31 @@ fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut d
12041211

12051212
let sanitizer = sess.opts.unstable_opts.sanitizer;
12061213
if sanitizer.contains(SanitizerSet::ADDRESS) {
1207-
link_sanitizer_runtime(sess, linker, "asan");
1214+
link_sanitizer_runtime(sess, flavor, linker, "asan");
12081215
}
12091216
if sanitizer.contains(SanitizerSet::LEAK) {
1210-
link_sanitizer_runtime(sess, linker, "lsan");
1217+
link_sanitizer_runtime(sess, flavor, linker, "lsan");
12111218
}
12121219
if sanitizer.contains(SanitizerSet::MEMORY) {
1213-
link_sanitizer_runtime(sess, linker, "msan");
1220+
link_sanitizer_runtime(sess, flavor, linker, "msan");
12141221
}
12151222
if sanitizer.contains(SanitizerSet::THREAD) {
1216-
link_sanitizer_runtime(sess, linker, "tsan");
1223+
link_sanitizer_runtime(sess, flavor, linker, "tsan");
12171224
}
12181225
if sanitizer.contains(SanitizerSet::HWADDRESS) {
1219-
link_sanitizer_runtime(sess, linker, "hwasan");
1226+
link_sanitizer_runtime(sess, flavor, linker, "hwasan");
12201227
}
12211228
if sanitizer.contains(SanitizerSet::SAFESTACK) {
1222-
link_sanitizer_runtime(sess, linker, "safestack");
1229+
link_sanitizer_runtime(sess, flavor, linker, "safestack");
12231230
}
12241231
}
12251232

1226-
fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
1233+
fn link_sanitizer_runtime(
1234+
sess: &Session,
1235+
flavor: LinkerFlavor,
1236+
linker: &mut dyn Linker,
1237+
name: &str,
1238+
) {
12271239
fn find_sanitizer_runtime(sess: &Session, filename: &str) -> PathBuf {
12281240
let session_tlib =
12291241
filesearch::make_target_lib_path(&sess.sysroot, sess.opts.target_triple.triple());
@@ -1254,6 +1266,10 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
12541266
let rpath = path.to_str().expect("non-utf8 component in path");
12551267
linker.args(&["-Wl,-rpath", "-Xlinker", rpath]);
12561268
linker.link_dylib(&filename, false, true);
1269+
} else if sess.target.is_like_msvc && flavor == LinkerFlavor::Msvc(Lld::No) && name == "asan" {
1270+
// MSVC provides the `/INFERASANLIBS` argument to automatically find the
1271+
// compatible ASAN library.
1272+
linker.arg("/INFERASANLIBS");
12571273
} else {
12581274
let filename = format!("librustc{channel}_rt.{name}.a");
12591275
let path = find_sanitizer_runtime(sess, &filename).join(&filename);
@@ -2076,7 +2092,7 @@ fn linker_with_args<'a>(
20762092
);
20772093

20782094
// Sanitizer libraries.
2079-
add_sanitizer_libraries(sess, crate_type, cmd);
2095+
add_sanitizer_libraries(sess, flavor, crate_type, cmd);
20802096

20812097
// Object code from the current crate.
20822098
// Take careful note of the ordering of the arguments we pass to the linker

compiler/rustc_expand/src/mbe/macro_rules.rs

+2-33
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::mbe::transcribe::transcribe;
1010

1111
use rustc_ast as ast;
1212
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*};
13-
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
13+
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
1414
use rustc_ast::{NodeId, DUMMY_NODE_ID};
1515
use rustc_ast_pretty::pprust;
1616
use rustc_attr::{self as attr, TransparencyError};
@@ -213,45 +213,14 @@ fn expand_macro<'cx>(
213213
let arm_span = rhses[i].span();
214214

215215
// rhs has holes ( `$id` and `$(...)` that need filled)
216-
let mut tts = match transcribe(cx, &named_matches, rhs, rhs_span, transparency) {
216+
let tts = match transcribe(cx, &named_matches, rhs, rhs_span, transparency) {
217217
Ok(tts) => tts,
218218
Err(mut err) => {
219219
err.emit();
220220
return DummyResult::any(arm_span);
221221
}
222222
};
223223

224-
// Replace all the tokens for the corresponding positions in the macro, to maintain
225-
// proper positions in error reporting, while maintaining the macro_backtrace.
226-
if tts.len() == rhs.tts.len() {
227-
tts = tts.map_enumerated_owned(|i, mut tt| {
228-
let rhs_tt = &rhs.tts[i];
229-
let ctxt = tt.span().ctxt();
230-
match (&mut tt, rhs_tt) {
231-
// preserve the delim spans if able
232-
(
233-
TokenTree::Delimited(target_sp, ..),
234-
mbe::TokenTree::Delimited(source_sp, ..),
235-
) => {
236-
target_sp.open = source_sp.open.with_ctxt(ctxt);
237-
target_sp.close = source_sp.close.with_ctxt(ctxt);
238-
}
239-
(
240-
TokenTree::Delimited(target_sp, ..),
241-
mbe::TokenTree::MetaVar(source_sp, ..),
242-
) => {
243-
target_sp.open = source_sp.with_ctxt(ctxt);
244-
target_sp.close = source_sp.with_ctxt(ctxt).shrink_to_hi();
245-
}
246-
_ => {
247-
let sp = rhs_tt.span().with_ctxt(ctxt);
248-
tt.set_span(sp);
249-
}
250-
}
251-
tt
252-
});
253-
}
254-
255224
if cx.trace_macros() {
256225
let msg = format!("to `{}`", pprust::tts_to_string(&tts));
257226
trace_macros_note(&mut cx.expansions, sp, msg);

compiler/rustc_expand/src/mbe/transcribe.rs

+61-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::errors::{
44
NoSyntaxVarsExprRepeat, VarStillRepeating,
55
};
66
use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, MatchedTokenTree, NamedMatch};
7-
use crate::mbe::{self, MetaVarExpr};
7+
use crate::mbe::{self, KleeneOp, MetaVarExpr};
88
use rustc_ast::mut_visit::{self, MutVisitor};
99
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
1010
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
@@ -42,6 +42,7 @@ enum Frame<'a> {
4242
tts: &'a [mbe::TokenTree],
4343
idx: usize,
4444
sep: Option<Token>,
45+
kleene_op: KleeneOp,
4546
},
4647
}
4748

@@ -207,7 +208,7 @@ pub(super) fn transcribe<'a>(
207208

208209
// Is the repetition empty?
209210
if len == 0 {
210-
if seq.kleene.op == mbe::KleeneOp::OneOrMore {
211+
if seq.kleene.op == KleeneOp::OneOrMore {
211212
// FIXME: this really ought to be caught at macro definition
212213
// time... It happens when the Kleene operator in the matcher and
213214
// the body for the same meta-variable do not match.
@@ -227,6 +228,7 @@ pub(super) fn transcribe<'a>(
227228
idx: 0,
228229
sep: seq.separator.clone(),
229230
tts: &delimited.tts,
231+
kleene_op: seq.kleene.op,
230232
});
231233
}
232234
}
@@ -243,7 +245,7 @@ pub(super) fn transcribe<'a>(
243245
MatchedTokenTree(tt) => {
244246
// `tt`s are emitted into the output stream directly as "raw tokens",
245247
// without wrapping them into groups.
246-
result.push(tt.clone());
248+
result.push(maybe_use_metavar_location(cx, &stack, sp, tt));
247249
}
248250
MatchedNonterminal(nt) => {
249251
// Other variables are emitted into the output stream as groups with
@@ -308,6 +310,62 @@ pub(super) fn transcribe<'a>(
308310
}
309311
}
310312

313+
/// Usually metavariables `$var` produce interpolated tokens, which have an additional place for
314+
/// keeping both the original span and the metavariable span. For `tt` metavariables that's not the
315+
/// case however, and there's no place for keeping a second span. So we try to give the single
316+
/// produced span a location that would be most useful in practice (the hygiene part of the span
317+
/// must not be changed).
318+
///
319+
/// Different locations are useful for different purposes:
320+
/// - The original location is useful when we need to report a diagnostic for the original token in
321+
/// isolation, without combining it with any surrounding tokens. This case occurs, but it is not
322+
/// very common in practice.
323+
/// - The metavariable location is useful when we need to somehow combine the token span with spans
324+
/// of its surrounding tokens. This is the most common way to use token spans.
325+
///
326+
/// So this function replaces the original location with the metavariable location in all cases
327+
/// except these two:
328+
/// - The metavariable is an element of undelimited sequence `$($tt)*`.
329+
/// These are typically used for passing larger amounts of code, and tokens in that code usually
330+
/// combine with each other and not with tokens outside of the sequence.
331+
/// - The metavariable span comes from a different crate, then we prefer the more local span.
332+
///
333+
/// FIXME: Find a way to keep both original and metavariable spans for all tokens without
334+
/// regressing compilation time too much. Several experiments for adding such spans were made in
335+
/// the past (PR #95580, #118517, #118671) and all showed some regressions.
336+
fn maybe_use_metavar_location(
337+
cx: &ExtCtxt<'_>,
338+
stack: &[Frame<'_>],
339+
metavar_span: Span,
340+
orig_tt: &TokenTree,
341+
) -> TokenTree {
342+
let undelimited_seq = matches!(
343+
stack.last(),
344+
Some(Frame::Sequence {
345+
tts: [_],
346+
sep: None,
347+
kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore,
348+
..
349+
})
350+
);
351+
if undelimited_seq || cx.source_map().is_imported(metavar_span) {
352+
return orig_tt.clone();
353+
}
354+
355+
match orig_tt {
356+
TokenTree::Token(Token { kind, span }, spacing) => {
357+
let span = metavar_span.with_ctxt(span.ctxt());
358+
TokenTree::Token(Token { kind: kind.clone(), span }, *spacing)
359+
}
360+
TokenTree::Delimited(dspan, dspacing, delimiter, tts) => {
361+
let open = metavar_span.shrink_to_lo().with_ctxt(dspan.open.ctxt());
362+
let close = metavar_span.shrink_to_hi().with_ctxt(dspan.close.ctxt());
363+
let dspan = DelimSpan::from_pair(open, close);
364+
TokenTree::Delimited(dspan, *dspacing, *delimiter, tts.clone())
365+
}
366+
}
367+
}
368+
311369
/// Lookup the meta-var named `ident` and return the matched token tree from the invocation using
312370
/// the set of matches `interpolations`.
313371
///

0 commit comments

Comments
 (0)