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 0a0f816

Browse files
committedJun 11, 2021
Auto merge of rust-lang#86225 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum
[beta] backports * Disable the machine outliner by default rust-lang#86020 * Fix incorrect gating of nonterminals in key-value attributes rust-lang#85445 * Build crtbegin.o/crtend.o from source code rust-lang#85395 * Bring back x86_64-sun-solaris target to rustup rust-lang#85252 * Preserve SyntaxContext for invalid/dummy spans in crate metadata rust-lang#85211 * [beta] backport: Remove unsound TrustedRandomAccess implementations rust-lang#86222 r? `@Mark-Simulacrum`
2 parents 05f39bf + 28ea358 commit 0a0f816

File tree

20 files changed

+279
-117
lines changed

20 files changed

+279
-117
lines changed
 

‎compiler/rustc_codegen_llvm/src/llvm_util.rs‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::back::write::create_informational_target_machine;
2-
use crate::llvm;
2+
use crate::{llvm, llvm_util};
33
use libc::c_int;
44
use rustc_codegen_ssa::target_features::supported_target_features;
55
use rustc_data_structures::fx::FxHashSet;
@@ -84,6 +84,17 @@ unsafe fn configure_llvm(sess: &Session) {
8484
if !sess.opts.debugging_opts.no_generate_arange_section {
8585
add("-generate-arange-section", false);
8686
}
87+
88+
// FIXME(nagisa): disable the machine outliner by default in LLVM versions 11, where it was
89+
// introduced and up.
90+
//
91+
// This should remain in place until https://reviews.llvm.org/D103167 is fixed. If LLVM
92+
// has been upgraded since, consider adjusting the version check below to contain an upper
93+
// bound.
94+
if llvm_util::get_version() >= (11, 0, 0) {
95+
add("-enable-machine-outliner=never", false);
96+
}
97+
8798
match sess.opts.debugging_opts.merge_functions.unwrap_or(sess.target.merge_functions) {
8899
MergeFunctions::Disabled | MergeFunctions::Trampolines => {}
89100
MergeFunctions::Aliases => {

‎compiler/rustc_metadata/src/rmeta/decoder.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,17 +406,17 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
406406

407407
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
408408
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Span, String> {
409+
let ctxt = SyntaxContext::decode(decoder)?;
409410
let tag = u8::decode(decoder)?;
410411

411-
if tag == TAG_INVALID_SPAN {
412-
return Ok(DUMMY_SP);
412+
if tag == TAG_PARTIAL_SPAN {
413+
return Ok(DUMMY_SP.with_ctxt(ctxt));
413414
}
414415

415416
debug_assert!(tag == TAG_VALID_SPAN_LOCAL || tag == TAG_VALID_SPAN_FOREIGN);
416417

417418
let lo = BytePos::decode(decoder)?;
418419
let len = BytePos::decode(decoder)?;
419-
let ctxt = SyntaxContext::decode(decoder)?;
420420
let hi = lo + len;
421421

422422
let sess = if let Some(sess) = decoder.sess {

‎compiler/rustc_metadata/src/rmeta/encoder.rs‎

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,48 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
184184

185185
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
186186
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
187-
if *self == rustc_span::DUMMY_SP {
188-
return TAG_INVALID_SPAN.encode(s);
187+
let span = self.data();
188+
189+
// Don't serialize any `SyntaxContext`s from a proc-macro crate,
190+
// since we don't load proc-macro dependencies during serialization.
191+
// This means that any hygiene information from macros used *within*
192+
// a proc-macro crate (e.g. invoking a macro that expands to a proc-macro
193+
// definition) will be lost.
194+
//
195+
// This can show up in two ways:
196+
//
197+
// 1. Any hygiene information associated with identifier of
198+
// a proc macro (e.g. `#[proc_macro] pub fn $name`) will be lost.
199+
// Since proc-macros can only be invoked from a different crate,
200+
// real code should never need to care about this.
201+
//
202+
// 2. Using `Span::def_site` or `Span::mixed_site` will not
203+
// include any hygiene information associated with the definition
204+
// site. This means that a proc-macro cannot emit a `$crate`
205+
// identifier which resolves to one of its dependencies,
206+
// which also should never come up in practice.
207+
//
208+
// Additionally, this affects `Span::parent`, and any other
209+
// span inspection APIs that would otherwise allow traversing
210+
// the `SyntaxContexts` associated with a span.
211+
//
212+
// None of these user-visible effects should result in any
213+
// cross-crate inconsistencies (getting one behavior in the same
214+
// crate, and a different behavior in another crate) due to the
215+
// limited surface that proc-macros can expose.
216+
//
217+
// IMPORTANT: If this is ever changed, be sure to update
218+
// `rustc_span::hygiene::raw_encode_expn_id` to handle
219+
// encoding `ExpnData` for proc-macro crates.
220+
if s.is_proc_macro {
221+
SyntaxContext::root().encode(s)?;
222+
} else {
223+
span.ctxt.encode(s)?;
189224
}
190225

191-
let span = self.data();
226+
if self.is_dummy() {
227+
return TAG_PARTIAL_SPAN.encode(s);
228+
}
192229

193230
// The Span infrastructure should make sure that this invariant holds:
194231
debug_assert!(span.lo <= span.hi);
@@ -203,7 +240,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
203240
if !s.source_file_cache.0.contains(span.hi) {
204241
// Unfortunately, macro expansion still sometimes generates Spans
205242
// that malformed in this way.
206-
return TAG_INVALID_SPAN.encode(s);
243+
return TAG_PARTIAL_SPAN.encode(s);
207244
}
208245

209246
let source_files = s.required_source_files.as_mut().expect("Already encoded SourceMap!");
@@ -259,43 +296,6 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
259296
let len = hi - lo;
260297
len.encode(s)?;
261298

262-
// Don't serialize any `SyntaxContext`s from a proc-macro crate,
263-
// since we don't load proc-macro dependencies during serialization.
264-
// This means that any hygiene information from macros used *within*
265-
// a proc-macro crate (e.g. invoking a macro that expands to a proc-macro
266-
// definition) will be lost.
267-
//
268-
// This can show up in two ways:
269-
//
270-
// 1. Any hygiene information associated with identifier of
271-
// a proc macro (e.g. `#[proc_macro] pub fn $name`) will be lost.
272-
// Since proc-macros can only be invoked from a different crate,
273-
// real code should never need to care about this.
274-
//
275-
// 2. Using `Span::def_site` or `Span::mixed_site` will not
276-
// include any hygiene information associated with the definition
277-
// site. This means that a proc-macro cannot emit a `$crate`
278-
// identifier which resolves to one of its dependencies,
279-
// which also should never come up in practice.
280-
//
281-
// Additionally, this affects `Span::parent`, and any other
282-
// span inspection APIs that would otherwise allow traversing
283-
// the `SyntaxContexts` associated with a span.
284-
//
285-
// None of these user-visible effects should result in any
286-
// cross-crate inconsistencies (getting one behavior in the same
287-
// crate, and a different behavior in another crate) due to the
288-
// limited surface that proc-macros can expose.
289-
//
290-
// IMPORTANT: If this is ever changed, be sure to update
291-
// `rustc_span::hygiene::raw_encode_expn_id` to handle
292-
// encoding `ExpnData` for proc-macro crates.
293-
if s.is_proc_macro {
294-
SyntaxContext::root().encode(s)?;
295-
} else {
296-
span.ctxt.encode(s)?;
297-
}
298-
299299
if tag == TAG_VALID_SPAN_FOREIGN {
300300
// This needs to be two lines to avoid holding the `s.source_file_cache`
301301
// while calling `cnum.encode(s)`

‎compiler/rustc_metadata/src/rmeta/mod.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,4 +450,4 @@ struct GeneratorData<'tcx> {
450450
// Tags used for encoding Spans:
451451
const TAG_VALID_SPAN_LOCAL: u8 = 0;
452452
const TAG_VALID_SPAN_FOREIGN: u8 = 1;
453-
const TAG_INVALID_SPAN: u8 = 2;
453+
const TAG_PARTIAL_SPAN: u8 = 2;

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,8 +1077,11 @@ impl<'a> Parser<'a> {
10771077
let span = expr.span;
10781078

10791079
match &expr.kind {
1080-
// Not gated to supporte things like `doc = $expr` that work on stable.
1081-
_ if is_interpolated_expr => {}
1080+
// Not gated to support things like `doc = $expr` that work on stable.
1081+
// Do not gate in `capture_cfg` mode, since we flatten all nontemrinals
1082+
// before parsing. `capture_cfg` mode is only used to reparse existing
1083+
// tokens, so the gating will be performed by the initial parse
1084+
_ if is_interpolated_expr || self.capture_cfg => {}
10821085
ExprKind::Lit(lit) if lit.kind.is_unsuffixed() => {}
10831086
_ => self.sess.gated_spans.gate(sym::extended_key_value_attributes, span),
10841087
}

‎library/alloc/src/collections/vec_deque/into_iter.rs‎

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::fmt;
2-
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
2+
use core::iter::{FusedIterator, TrustedLen};
33

44
use super::VecDeque;
55

@@ -36,22 +36,6 @@ impl<T> Iterator for IntoIter<T> {
3636
let len = self.inner.len();
3737
(len, Some(len))
3838
}
39-
40-
#[inline]
41-
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
42-
where
43-
Self: TrustedRandomAccess,
44-
{
45-
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
46-
// that is in bounds.
47-
// Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
48-
// multiple repeated reads of the same index would be safe and the
49-
// values are !Drop, thus won't suffer from double drops.
50-
unsafe {
51-
let idx = self.inner.wrap_add(self.inner.tail, idx);
52-
self.inner.buffer_read(idx)
53-
}
54-
}
5539
}
5640

5741
#[stable(feature = "rust1", since = "1.0.0")]
@@ -74,14 +58,3 @@ impl<T> FusedIterator for IntoIter<T> {}
7458

7559
#[unstable(feature = "trusted_len", issue = "37572")]
7660
unsafe impl<T> TrustedLen for IntoIter<T> {}
77-
78-
#[doc(hidden)]
79-
#[unstable(feature = "trusted_random_access", issue = "none")]
80-
// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
81-
// and thus we can't implement drop-handling
82-
unsafe impl<T> TrustedRandomAccess for IntoIter<T>
83-
where
84-
T: Copy,
85-
{
86-
const MAY_HAVE_SIDE_EFFECT: bool = false;
87-
}

‎library/core/src/array/iter.rs‎

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::{
44
fmt,
5-
iter::{self, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess},
5+
iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
66
mem::{self, MaybeUninit},
77
ops::Range,
88
ptr,
@@ -130,18 +130,6 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
130130
fn last(mut self) -> Option<Self::Item> {
131131
self.next_back()
132132
}
133-
134-
#[inline]
135-
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
136-
where
137-
Self: TrustedRandomAccess,
138-
{
139-
// SAFETY: Callers are only allowed to pass an index that is in bounds
140-
// Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
141-
// multiple repeated reads of the same index would be safe and the
142-
// values aree !Drop, thus won't suffer from double drops.
143-
unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() }
144-
}
145133
}
146134

147135
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
@@ -196,17 +184,6 @@ impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}
196184
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
197185
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}
198186

199-
#[doc(hidden)]
200-
#[unstable(feature = "trusted_random_access", issue = "none")]
201-
// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
202-
// and thus we can't implement drop-handling
203-
unsafe impl<T, const N: usize> TrustedRandomAccess for IntoIter<T, N>
204-
where
205-
T: Copy,
206-
{
207-
const MAY_HAVE_SIDE_EFFECT: bool = false;
208-
}
209-
210187
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
211188
impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
212189
fn clone(&self) -> Self {

‎src/bootstrap/builder.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ impl<'a> Builder<'a> {
369369
tool::Rustfmt,
370370
tool::Miri,
371371
tool::CargoMiri,
372-
native::Lld
372+
native::Lld,
373+
native::CrtBeginEnd
373374
),
374375
Kind::Check | Kind::Clippy { .. } | Kind::Fix | Kind::Format => describe!(
375376
check::Std,

‎src/bootstrap/compile.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,9 @@ fn copy_self_contained_objects(
199199
DependencyType::TargetSelfContained,
200200
);
201201
}
202+
let crt_path = builder.ensure(native::CrtBeginEnd { target });
202203
for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] {
203-
let src = compiler_file(builder, builder.cc(target), target, obj);
204+
let src = crt_path.join(obj);
204205
let target = libdir_self_contained.join(obj);
205206
builder.copy(&src, &target);
206207
target_deps.push((target, DependencyType::TargetSelfContained));

‎src/bootstrap/native.rs‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,3 +858,69 @@ impl HashStamp {
858858
fs::write(&self.path, self.hash.as_deref().unwrap_or(b""))
859859
}
860860
}
861+
862+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
863+
pub struct CrtBeginEnd {
864+
pub target: TargetSelection,
865+
}
866+
867+
impl Step for CrtBeginEnd {
868+
type Output = PathBuf;
869+
870+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
871+
run.path("src/llvm-project/compiler-rt/lib/crt")
872+
}
873+
874+
fn make_run(run: RunConfig<'_>) {
875+
run.builder.ensure(CrtBeginEnd { target: run.target });
876+
}
877+
878+
/// Build crtbegin.o/crtend.o for musl target.
879+
fn run(self, builder: &Builder<'_>) -> Self::Output {
880+
let out_dir = builder.native_dir(self.target).join("crt");
881+
882+
if builder.config.dry_run {
883+
return out_dir;
884+
}
885+
886+
let crtbegin_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtbegin.c");
887+
let crtend_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtend.c");
888+
if up_to_date(&crtbegin_src, &out_dir.join("crtbegin.o"))
889+
&& up_to_date(&crtend_src, &out_dir.join("crtendS.o"))
890+
{
891+
return out_dir;
892+
}
893+
894+
builder.info("Building crtbegin.o and crtend.o");
895+
t!(fs::create_dir_all(&out_dir));
896+
897+
let mut cfg = cc::Build::new();
898+
899+
if let Some(ar) = builder.ar(self.target) {
900+
cfg.archiver(ar);
901+
}
902+
cfg.compiler(builder.cc(self.target));
903+
cfg.cargo_metadata(false)
904+
.out_dir(&out_dir)
905+
.target(&self.target.triple)
906+
.host(&builder.config.build.triple)
907+
.warnings(false)
908+
.debug(false)
909+
.opt_level(3)
910+
.file(crtbegin_src)
911+
.file(crtend_src);
912+
913+
// Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt
914+
// Currently only consumer of those objects is musl, which use .init_array/.fini_array
915+
// instead of .ctors/.dtors
916+
cfg.flag("-std=c11")
917+
.define("CRT_HAS_INITFINI_ARRAY", None)
918+
.define("EH_USE_FRAME_REGISTRY", None);
919+
920+
cfg.compile("crt");
921+
922+
t!(fs::copy(out_dir.join("crtbegin.o"), out_dir.join("crtbeginS.o")));
923+
t!(fs::copy(out_dir.join("crtend.o"), out_dir.join("crtendS.o")));
924+
out_dir
925+
}
926+
}

‎src/ci/docker/host-x86_64/dist-various-1/Dockerfile‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,11 @@ ENV TARGETS=$TARGETS,armv7a-none-eabi
144144
# riscv targets currently do not need a C compiler, as compiler_builtins
145145
# doesn't currently have it enabled, and the riscv gcc compiler is not
146146
# installed.
147-
ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
147+
ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft" \
148+
CFLAGS_arm_unknown_linux_musleabi="-march=armv6 -marm" \
149+
CFLAGS_arm_unknown_linux_musleabihf="-march=armv6 -marm -mfpu=vfp" \
150+
CFLAGS_armv7_unknown_linux_musleabihf="-march=armv7-a" \
151+
CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
148152
CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc \
149153
CC_mips64el_unknown_linux_muslabi64=mips64el-linux-gnuabi64-gcc \
150154
CC_mips64_unknown_linux_muslabi64=mips64-linux-gnuabi64-gcc \

‎src/ci/docker/host-x86_64/dist-various-2/Dockerfile‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ ENV \
4242
AR_x86_64_pc_solaris=x86_64-pc-solaris2.10-ar \
4343
CC_x86_64_pc_solaris=x86_64-pc-solaris2.10-gcc \
4444
CXX_x86_64_pc_solaris=x86_64-pc-solaris2.10-g++ \
45+
AR_x86_64_sun_solaris=x86_64-sun-solaris2.10-ar \
46+
CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \
47+
CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++ \
4548
CC_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-gcc-8 \
4649
CXX_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-g++-8 \
4750
AR_x86_64_fortanix_unknown_sgx=ar \
@@ -68,8 +71,10 @@ COPY host-x86_64/dist-various-2/shared.sh /tmp/
6871
COPY host-x86_64/dist-various-2/build-fuchsia-toolchain.sh /tmp/
6972
RUN /tmp/build-fuchsia-toolchain.sh
7073
COPY host-x86_64/dist-various-2/build-solaris-toolchain.sh /tmp/
71-
RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386
72-
RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc
74+
RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 pc
75+
# Build deprecated target 'x86_64-sun-solaris2.10' until removed
76+
RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 sun
77+
RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc sun
7378
COPY host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/
7479
RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh
7580

@@ -99,6 +104,7 @@ ENV TARGETS=$TARGETS,wasm32-unknown-unknown
99104
ENV TARGETS=$TARGETS,wasm32-wasi
100105
ENV TARGETS=$TARGETS,sparcv9-sun-solaris
101106
ENV TARGETS=$TARGETS,x86_64-pc-solaris
107+
ENV TARGETS=$TARGETS,x86_64-sun-solaris
102108
ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
103109
ENV TARGETS=$TARGETS,x86_64-fortanix-unknown-sgx
104110
ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda

‎src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh‎

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,11 @@ source shared.sh
66
ARCH=$1
77
LIB_ARCH=$2
88
APT_ARCH=$3
9+
MANUFACTURER=$4
910
BINUTILS=2.28.1
1011
GCC=6.5.0
1112

12-
# Choose correct target based on the $ARCH
13-
case "$ARCH" in
14-
x86_64)
15-
TARGET=x86_64-pc-solaris2.10
16-
;;
17-
sparcv9)
18-
TARGET=sparcv9-sun-solaris2.10
19-
;;
20-
*)
21-
printf 'ERROR: unknown architecture: %s\n' "$ARCH"
22-
exit 1
23-
esac
13+
TARGET=${ARCH}-${MANUFACTURER}-solaris2.10
2414

2515
# First up, build binutils
2616
mkdir binutils
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// revisions: rpass1 rpass2
2+
3+
extern crate respan;
4+
5+
#[macro_use]
6+
#[path = "invalid-span-helper-mod.rs"]
7+
mod invalid_span_helper_mod;
8+
9+
// Invoke a macro from a different file - this
10+
// allows us to get tokens with spans from different files
11+
helper!(1);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#[macro_export]
2+
macro_rules! helper {
3+
// Use `:tt` instead of `:ident` so that we don't get a `None`-delimited group
4+
($first:tt) => {
5+
pub fn foo<T>() {
6+
// The span of `$first` comes from another file,
7+
// so the expression `1 + $first` ends up with an
8+
// 'invalid' span that starts and ends in different files.
9+
// We use the `respan!` macro to give all tokens the same
10+
// `SyntaxContext`, so that the parser will try to merge the spans.
11+
respan::respan!(let a = 1 + $first;);
12+
}
13+
}
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
4+
#![crate_type = "proc-macro"]
5+
6+
extern crate proc_macro;
7+
use proc_macro::TokenStream;
8+
9+
10+
/// Copies the resolution information (the `SyntaxContext`) of the first
11+
/// token to all other tokens in the stream. Does not recurse into groups.
12+
#[proc_macro]
13+
pub fn respan(input: TokenStream) -> TokenStream {
14+
let first_span = input.clone().into_iter().next().unwrap().span();
15+
input.into_iter().map(|mut tree| {
16+
tree.set_span(tree.span().resolved_at(first_span));
17+
tree
18+
}).collect()
19+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// revisions: rpass1 rpass2
2+
// aux-build:respan.rs
3+
// aux-build:invalid-span-helper-lib.rs
4+
5+
// This issue has several different parts. The high level idea is:
6+
// 1. We create an 'invalid' span with the help of the `respan` proc-macro,
7+
// The compiler attempts to prevent the creation of invalid spans by
8+
// refusing to join spans with different `SyntaxContext`s. We work around
9+
// this by applying the same `SyntaxContext` to the span of every token,
10+
// using `Span::resolved_at`
11+
// 2. We using this invalid span in the body of a function, causing it to get
12+
// encoded into the `optimized_mir`
13+
// 3. We call the function from a different crate - since the function is generic,
14+
// monomorphization runs, causing `optimized_mir` to get called.
15+
// 4. We re-run compilation using our populated incremental cache, but without
16+
// making any changes. When we recompile the crate containing our generic function
17+
// (`invalid_span_helper_lib`), we load the span from the incremental cache, and
18+
// write it into the crate metadata.
19+
20+
extern crate invalid_span_helper_lib;
21+
22+
fn main() {
23+
invalid_span_helper_lib::foo::<u8>();
24+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# only-linux
2+
# ignore-32bit
3+
4+
-include ../tools.mk
5+
6+
all:
7+
$(RUSTC) eh_frame-terminator.rs
8+
$(call RUN,eh_frame-terminator) | $(CGREP) '1122334455667788'
9+
objdump --dwarf=frames $(TMPDIR)/eh_frame-terminator | $(CGREP) 'ZERO terminator'
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// run-pass
2+
3+
#![feature(backtrace)]
4+
#[derive(Clone, Copy)]
5+
struct Foo {
6+
array: [u64; 10240],
7+
}
8+
9+
impl Foo {
10+
const fn new() -> Self {
11+
Self {
12+
array: [0x1122_3344_5566_7788; 10240]
13+
}
14+
}
15+
}
16+
17+
static BAR: [Foo; 10240] = [Foo::new(); 10240];
18+
19+
fn main() {
20+
let bt = std::backtrace::Backtrace::force_capture();
21+
println!("Hello, world! {:?}", bt);
22+
println!("{:x}", BAR[0].array[0]);
23+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// check-pass
2+
// Regression test for issue #85432
3+
// Ensures that we don't incorrectly gate nonterminals
4+
// in key-value macros when we need to reparse due to
5+
// the presence of `#[derive]`
6+
7+
macro_rules! with_doc_comment {
8+
($comment:expr, $item:item) => {
9+
#[doc = $comment]
10+
$item
11+
};
12+
}
13+
14+
macro_rules! database_table_doc {
15+
() => {
16+
""
17+
};
18+
}
19+
20+
with_doc_comment! {
21+
database_table_doc!(),
22+
#[derive(Debug)]
23+
struct Image {
24+
#[cfg(FALSE)]
25+
_f: (),
26+
}
27+
28+
}
29+
30+
fn main() {}

0 commit comments

Comments
 (0)
This repository has been archived.