Auto merge of #149013 - Zalathar:rollup-io1ddhc, r=Zalathar
Rollup of 11 pull requests Successful merges: - rust-lang/rust#148505 (add larger test for `proc_macro` `FromStr` implementations) - rust-lang/rust#148752 (Constify `ManuallyDrop::take`) - rust-lang/rust#148757 (Constify `mem::take`) - rust-lang/rust#148855 (Error if an autodiff user does not set lto=fat) - rust-lang/rust#148912 (add note to `lines` docs about empty str behavior) - rust-lang/rust#148958 (Run codegen tests on a 32-bit target in PR CI) - rust-lang/rust#148994 (Abi compatibility test cleanup) - rust-lang/rust#148999 (Tweak Motor OS linker preset, fix `remote-test-server` for Motor OS) - rust-lang/rust#149004 (compiletest: Avoid race condition in file deletion) - rust-lang/rust#149008 (triagebot: remove jsha from notifications for rustdoc HTML) - rust-lang/rust#149010 (compiletest: Remove the "wasm32-bare" alias for `wasm32-unknown-unknown`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
cc328c1238
29 changed files with 540 additions and 73 deletions
|
|
@ -1,4 +1,5 @@
|
|||
codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable
|
||||
codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml
|
||||
|
||||
codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ParseTargetMachineConfig<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_llvm_autodiff_without_lto)]
|
||||
pub(crate) struct AutoDiffWithoutLto;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_llvm_autodiff_without_enable)]
|
||||
pub(crate) struct AutoDiffWithoutEnable;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use crate::abi::FnAbiLlvmExt;
|
|||
use crate::builder::Builder;
|
||||
use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call};
|
||||
use crate::context::CodegenCx;
|
||||
use crate::errors::AutoDiffWithoutEnable;
|
||||
use crate::errors::{AutoDiffWithoutEnable, AutoDiffWithoutLto};
|
||||
use crate::llvm::{self, Metadata, Type, Value};
|
||||
use crate::type_of::LayoutLlvmExt;
|
||||
use crate::va_arg::emit_va_arg;
|
||||
|
|
@ -1136,6 +1136,9 @@ fn codegen_autodiff<'ll, 'tcx>(
|
|||
if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) {
|
||||
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutEnable);
|
||||
}
|
||||
if tcx.sess.lto() != rustc_session::config::Lto::Fat {
|
||||
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto);
|
||||
}
|
||||
|
||||
let fn_args = instance.args;
|
||||
let callee_ty = instance.ty(tcx, bx.typing_env());
|
||||
|
|
|
|||
|
|
@ -594,14 +594,6 @@ impl Session {
|
|||
|
||||
/// Calculates the flavor of LTO to use for this compilation.
|
||||
pub fn lto(&self) -> config::Lto {
|
||||
// Autodiff currently requires fat-lto to have access to the llvm-ir of all (indirectly) used functions and types.
|
||||
// fat-lto is the easiest solution to this requirement, but quite expensive.
|
||||
// FIXME(autodiff): Make autodiff also work with embed-bc instead of fat-lto.
|
||||
// Don't apply fat-lto to proc-macro crates as they cannot use fat-lto without -Zdylib-lto
|
||||
if self.opts.autodiff_enabled() && !self.opts.crate_types.contains(&CrateType::ProcMacro) {
|
||||
return config::Lto::Fat;
|
||||
}
|
||||
|
||||
// If our target has codegen requirements ignore the command line
|
||||
if self.target.requires_lto {
|
||||
return config::Lto::Fat;
|
||||
|
|
|
|||
|
|
@ -4,16 +4,8 @@ use crate::spec::{
|
|||
|
||||
pub(crate) fn opts() -> TargetOptions {
|
||||
let pre_link_args = TargetOptions::link_args(
|
||||
LinkerFlavor::Gnu(Cc::No, Lld::No),
|
||||
&[
|
||||
"-e",
|
||||
"motor_start",
|
||||
"--no-undefined",
|
||||
"--error-unresolved-symbols",
|
||||
"--no-undefined-version",
|
||||
"-u",
|
||||
"__rust_abort",
|
||||
],
|
||||
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
|
||||
&["-e", "motor_start", "-u", "__rust_abort"],
|
||||
);
|
||||
TargetOptions {
|
||||
os: Os::Motor,
|
||||
|
|
@ -23,7 +15,7 @@ pub(crate) fn opts() -> TargetOptions {
|
|||
// We use "OS level" TLS (see thread/local.rs in stdlib).
|
||||
has_thread_local: false,
|
||||
frame_pointer: FramePointer::NonLeaf,
|
||||
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No),
|
||||
linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No),
|
||||
main_needs_argc_argv: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
pre_link_args,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::spec::{
|
||||
Arch, CodeModel, LinkSelfContainedDefault, LldFlavor, RelocModel, RelroLevel, Target, base,
|
||||
Arch, CodeModel, LinkSelfContainedDefault, RelocModel, RelroLevel, Target, base,
|
||||
};
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
|
|
@ -15,7 +15,6 @@ pub(crate) fn target() -> Target {
|
|||
base.relro_level = RelroLevel::Full;
|
||||
base.static_position_independent_executables = true;
|
||||
base.relocation_model = RelocModel::Pic;
|
||||
base.lld_flavor_json = LldFlavor::Ld;
|
||||
base.link_self_contained = LinkSelfContainedDefault::True;
|
||||
base.dynamic_linking = false;
|
||||
base.crt_static_default = true;
|
||||
|
|
|
|||
|
|
@ -217,8 +217,9 @@ impl<T> ManuallyDrop<T> {
|
|||
///
|
||||
#[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
|
||||
#[stable(feature = "manually_drop_take", since = "1.42.0")]
|
||||
#[rustc_const_unstable(feature = "const_manually_drop_take", issue = "148773")]
|
||||
#[inline]
|
||||
pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
|
||||
pub const unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
|
||||
// SAFETY: we are reading from a reference, which is guaranteed
|
||||
// to be valid for reads.
|
||||
unsafe { ptr::read(&slot.value) }
|
||||
|
|
|
|||
|
|
@ -808,7 +808,8 @@ pub const fn swap<T>(x: &mut T, y: &mut T) {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "mem_take", since = "1.40.0")]
|
||||
pub fn take<T: Default>(dest: &mut T) -> T {
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
pub const fn take<T: [const] Default>(dest: &mut T) -> T {
|
||||
replace(dest, T::default())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1251,6 +1251,8 @@ impl str {
|
|||
/// ending will return the same lines as an otherwise identical string
|
||||
/// without a final line ending.
|
||||
///
|
||||
/// An empty string returns an empty iterator.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
|
|
@ -1281,6 +1283,15 @@ impl str {
|
|||
///
|
||||
/// assert_eq!(None, lines.next());
|
||||
/// ```
|
||||
///
|
||||
/// An empty string returns an empty iterator:
|
||||
///
|
||||
/// ```
|
||||
/// let text = "";
|
||||
/// let mut lines = text.lines();
|
||||
///
|
||||
/// assert_eq!(lines.next(), None);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn lines(&self) -> Lines<'_> {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
mingw-w64 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-27/wasi-sdk-27.0-x86_64-linux.tar.gz | \
|
||||
tar -xz
|
||||
ENV WASI_SDK_PATH=/wasi-sdk-27.0-x86_64-linux
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS="--set rust.validate-mir-opts=3"
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
|
|
@ -30,6 +34,10 @@ ENV SCRIPT \
|
|||
python3 ../x.py check && \
|
||||
python3 ../x.py clippy ci --stage 2 && \
|
||||
python3 ../x.py test --stage 1 core alloc std test proc_macro && \
|
||||
# Elsewhere, we run all tests for the host. A number of codegen tests are sensitive to the target pointer
|
||||
# width, for example because they mention a usize. wasm32-wasip1 in test-various, so using it here can't make
|
||||
# PR CI more strict than full CI.
|
||||
python3 ../x.py test --stage 1 tests/codegen-llvm --target wasm32-wasip1 && \
|
||||
python3 ../x.py test --stage 1 src/tools/compiletest && \
|
||||
python3 ../x.py doc bootstrap --stage 1 && \
|
||||
# Build both public and internal documentation.
|
||||
|
|
|
|||
|
|
@ -141,7 +141,6 @@ Some examples of `X` in `ignore-X` or `only-X`:
|
|||
- OS: `android`, `emscripten`, `freebsd`, `ios`, `linux`, `macos`, `windows`,
|
||||
...
|
||||
- Environment (fourth word of the target triple): `gnu`, `msvc`, `musl`
|
||||
- WASM: `wasm32-bare` matches `wasm32-unknown-unknown`.
|
||||
- Pointer width: `32bit`, `64bit`
|
||||
- Endianness: `endian-big`
|
||||
- Stage: `stage1`, `stage2`
|
||||
|
|
|
|||
|
|
@ -147,14 +147,6 @@ fn parse_cfg_name_directive<'a>(
|
|||
message: "when the target family is {name}"
|
||||
}
|
||||
|
||||
// `wasm32-bare` is an alias to refer to just wasm32-unknown-unknown
|
||||
// (in contrast to `wasm32` which also matches non-bare targets)
|
||||
condition! {
|
||||
name: "wasm32-bare",
|
||||
condition: config.target == "wasm32-unknown-unknown",
|
||||
message: "when the target is WASM"
|
||||
}
|
||||
|
||||
condition! {
|
||||
name: "thumb",
|
||||
condition: config.target.starts_with("thumb"),
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
|||
"ignore-wasi",
|
||||
"ignore-wasm",
|
||||
"ignore-wasm32",
|
||||
"ignore-wasm32-bare",
|
||||
"ignore-wasm32-unknown-unknown",
|
||||
"ignore-wasm64",
|
||||
"ignore-watchos",
|
||||
"ignore-windows",
|
||||
|
|
@ -240,7 +240,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
|||
"only-unix",
|
||||
"only-visionos",
|
||||
"only-wasm32",
|
||||
"only-wasm32-bare",
|
||||
"only-wasm32-unknown-unknown",
|
||||
"only-wasm32-wasip1",
|
||||
"only-watchos",
|
||||
"only-windows",
|
||||
|
|
|
|||
|
|
@ -710,18 +710,14 @@ fn wasm_special() {
|
|||
let ignores = [
|
||||
("wasm32-unknown-unknown", "emscripten", false),
|
||||
("wasm32-unknown-unknown", "wasm32", true),
|
||||
("wasm32-unknown-unknown", "wasm32-bare", true),
|
||||
("wasm32-unknown-unknown", "wasm64", false),
|
||||
("wasm32-unknown-emscripten", "emscripten", true),
|
||||
("wasm32-unknown-emscripten", "wasm32", true),
|
||||
("wasm32-unknown-emscripten", "wasm32-bare", false),
|
||||
("wasm32-wasip1", "emscripten", false),
|
||||
("wasm32-wasip1", "wasm32", true),
|
||||
("wasm32-wasip1", "wasm32-bare", false),
|
||||
("wasm32-wasip1", "wasi", true),
|
||||
("wasm64-unknown-unknown", "emscripten", false),
|
||||
("wasm64-unknown-unknown", "wasm32", false),
|
||||
("wasm64-unknown-unknown", "wasm32-bare", false),
|
||||
("wasm64-unknown-unknown", "wasm64", true),
|
||||
];
|
||||
for (target, pattern, ignore) in ignores {
|
||||
|
|
|
|||
|
|
@ -2766,12 +2766,11 @@ impl<'test> TestCx<'test> {
|
|||
.map_err(|err| format!("failed to load expected output from `{}`: {}", path, err))
|
||||
}
|
||||
|
||||
/// Attempts to delete a file, succeeding if the file does not exist.
|
||||
fn delete_file(&self, file: &Utf8Path) {
|
||||
if !file.exists() {
|
||||
// Deleting a nonexistent file would error.
|
||||
return;
|
||||
}
|
||||
if let Err(e) = fs::remove_file(file.as_std_path()) {
|
||||
if let Err(e) = fs::remove_file(file.as_std_path())
|
||||
&& e.kind() != io::ErrorKind::NotFound
|
||||
{
|
||||
self.fatal(&format!("failed to delete `{}`: {}", file, e,));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@
|
|||
//! themselves having support libraries. All data over the TCP sockets is in a
|
||||
//! basically custom format suiting our needs.
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(all(not(windows), not(target_os = "motor")))]
|
||||
use std::fs::Permissions;
|
||||
use std::fs::{self, File};
|
||||
use std::io::prelude::*;
|
||||
use std::io::{self, BufReader};
|
||||
use std::net::{SocketAddr, TcpListener, TcpStream};
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(all(not(windows), not(target_os = "motor")))]
|
||||
use std::os::unix::prelude::*;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, ExitStatus, Stdio};
|
||||
|
|
@ -325,7 +325,7 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf
|
|||
]));
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(all(not(windows), not(target_os = "motor")))]
|
||||
fn get_status_code(status: &ExitStatus) -> (u8, i32) {
|
||||
match status.code() {
|
||||
Some(n) => (0, n),
|
||||
|
|
@ -333,7 +333,7 @@ fn get_status_code(status: &ExitStatus) -> (u8, i32) {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[cfg(any(windows, target_os = "motor"))]
|
||||
fn get_status_code(status: &ExitStatus) -> (u8, i32) {
|
||||
(0, status.code().unwrap())
|
||||
}
|
||||
|
|
@ -359,11 +359,11 @@ fn recv<B: BufRead>(dir: &Path, io: &mut B) -> PathBuf {
|
|||
dst
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(all(not(windows), not(target_os = "motor")))]
|
||||
fn set_permissions(path: &Path) {
|
||||
t!(fs::set_permissions(&path, Permissions::from_mode(0o755)));
|
||||
}
|
||||
#[cfg(windows)]
|
||||
#[cfg(any(windows, target_os = "motor"))]
|
||||
fn set_permissions(_path: &Path) {}
|
||||
|
||||
fn my_copy(src: &mut dyn Read, which: u8, dst: &Mutex<dyn Write>) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
//@ ignore-apple slightly different policy on stack protection of arrays
|
||||
//@ ignore-msvc stack check code uses different function names
|
||||
//@ ignore-nvptx64 stack protector is not supported
|
||||
//@ ignore-wasm32-bare
|
||||
//@ ignore-wasm32-unknown-unknown
|
||||
//@ [all] compile-flags: -Z stack-protector=all
|
||||
//@ [strong] compile-flags: -Z stack-protector=strong
|
||||
//@ [basic] compile-flags: -Z stack-protector=basic
|
||||
|
|
|
|||
|
|
@ -119,6 +119,24 @@ pub struct ManuallyDrop<T: PointeeSized> {
|
|||
}
|
||||
impl<T: Copy + PointeeSized> Copy for ManuallyDrop<T> {}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[rustc_layout_scalar_valid_range_start(1)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
pub struct NonNull<T: ?Sized> {
|
||||
pointer: *const T,
|
||||
}
|
||||
impl<T: ?Sized> Copy for NonNull<T> {}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[rustc_layout_scalar_valid_range_start(1)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
pub struct NonZero<T>(T);
|
||||
|
||||
pub struct Unique<T: ?Sized> {
|
||||
pub pointer: NonNull<T>,
|
||||
pub _marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
#[lang = "unsafe_cell"]
|
||||
#[repr(transparent)]
|
||||
pub struct UnsafeCell<T: PointeeSized> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//@ only-wasm32-bare
|
||||
//@ only-wasm32-unknown-unknown
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@
|
|||
//@ revisions: arm
|
||||
//@[arm] compile-flags: --target arm-unknown-linux-gnueabi
|
||||
//@[arm] needs-llvm-components: arm
|
||||
//@ revisions: thumb
|
||||
//@[thumb] compile-flags: --target thumbv8m.main-none-eabi
|
||||
//@[thumb] needs-llvm-components: arm
|
||||
//@ revisions: aarch64
|
||||
//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
|
||||
//@[aarch64] needs-llvm-components: aarch64
|
||||
|
|
@ -31,12 +34,21 @@
|
|||
//@ revisions: sparc64
|
||||
//@[sparc64] compile-flags: --target sparc64-unknown-linux-gnu
|
||||
//@[sparc64] needs-llvm-components: sparc
|
||||
//@ revisions: powerpc
|
||||
//@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu
|
||||
//@[powerpc] needs-llvm-components: powerpc
|
||||
//@ revisions: powerpc64
|
||||
//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
|
||||
//@[powerpc64] needs-llvm-components: powerpc
|
||||
//@ revisions: aix
|
||||
//@[aix] compile-flags: --target powerpc64-ibm-aix
|
||||
//@[aix] needs-llvm-components: powerpc
|
||||
//@ revisions: riscv
|
||||
//@[riscv] compile-flags: --target riscv64gc-unknown-linux-gnu
|
||||
//@[riscv] needs-llvm-components: riscv
|
||||
//@ revisions: loongarch32
|
||||
//@[loongarch32] compile-flags: --target loongarch32-unknown-none
|
||||
//@[loongarch32] needs-llvm-components: loongarch
|
||||
//@ revisions: loongarch64
|
||||
//@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
|
||||
//@[loongarch64] needs-llvm-components: loongarch
|
||||
|
|
@ -87,19 +99,6 @@ mod prelude {
|
|||
fn clone(&self) -> Self;
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[rustc_layout_scalar_valid_range_start(1)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
pub struct NonNull<T: ?Sized> {
|
||||
pointer: *const T,
|
||||
}
|
||||
impl<T: ?Sized> Copy for NonNull<T> {}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[rustc_layout_scalar_valid_range_start(1)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
pub struct NonZero<T>(T);
|
||||
|
||||
// This just stands in for a non-trivial type.
|
||||
pub struct Vec<T> {
|
||||
ptr: NonNull<T>,
|
||||
|
|
@ -107,11 +106,6 @@ mod prelude {
|
|||
len: usize,
|
||||
}
|
||||
|
||||
pub struct Unique<T: ?Sized> {
|
||||
pub pointer: NonNull<T>,
|
||||
pub _marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
#[lang = "global_alloc_ty"]
|
||||
pub struct Global;
|
||||
|
||||
|
|
|
|||
4
tests/ui/autodiff/no_lto_flag.no_lto.stderr
Normal file
4
tests/ui/autodiff/no_lto_flag.no_lto.stderr
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
error: using the autodiff feature requires setting `lto="fat"` in your Cargo.toml
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
31
tests/ui/autodiff/no_lto_flag.rs
Normal file
31
tests/ui/autodiff/no_lto_flag.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//@ needs-enzyme
|
||||
//@ no-prefer-dynamic
|
||||
//@ revisions: with_lto no_lto
|
||||
//@[with_lto] compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat
|
||||
//@[no_lto] compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=thin
|
||||
|
||||
#![feature(autodiff)]
|
||||
//@[no_lto] build-fail
|
||||
//@[with_lto] build-pass
|
||||
|
||||
// Autodiff requires users to enable lto=fat (for now).
|
||||
// In the past, autodiff did not run if users forget to enable fat-lto, which caused functions to
|
||||
// returning zero-derivatives. That's obviously wrong and confusing to users. We now added a check
|
||||
// which will abort compilation instead.
|
||||
|
||||
use std::autodiff::autodiff_reverse;
|
||||
//[no_lto]~? ERROR using the autodiff feature requires setting `lto="fat"` in your Cargo.toml
|
||||
|
||||
#[autodiff_reverse(d_square, Duplicated, Active)]
|
||||
fn square(x: &f64) -> f64 {
|
||||
*x * *x
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let xf64: f64 = std::hint::black_box(3.0);
|
||||
|
||||
let mut df_dxf64: f64 = std::hint::black_box(0.0);
|
||||
|
||||
let _output_f64 = d_square(&xf64, &mut df_dxf64, 1.0);
|
||||
assert_eq!(6.0, df_dxf64);
|
||||
}
|
||||
|
|
@ -31,9 +31,8 @@ async unsafe extern "cmse-nonsecure-entry" fn async_is_not_allowed() {
|
|||
// this file, but they may be moved into `minicore` if/when other `#[no_core]` tests want to use
|
||||
// them.
|
||||
|
||||
// NOTE: in `core` this type uses `NonNull`.
|
||||
#[lang = "ResumeTy"]
|
||||
pub struct ResumeTy(*mut Context<'static>);
|
||||
pub struct ResumeTy(NonNull<Context<'static>>);
|
||||
|
||||
#[lang = "future_trait"]
|
||||
pub trait Future {
|
||||
|
|
|
|||
143
tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs
Normal file
143
tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
use std::fmt::Debug;
|
||||
use std::panic::catch_unwind;
|
||||
use std::str::FromStr;
|
||||
|
||||
use proc_macro::*;
|
||||
|
||||
use self::Mode::*;
|
||||
|
||||
// FIXME: all cases should become `NormalOk` or `NormalErr`
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
enum Mode {
|
||||
NormalOk,
|
||||
NormalErr,
|
||||
OtherError,
|
||||
OtherWithPanic,
|
||||
}
|
||||
|
||||
fn parse<T>(s: &str, mode: Mode)
|
||||
where
|
||||
T: FromStr<Err = LexError> + Debug,
|
||||
{
|
||||
match mode {
|
||||
NormalOk => {
|
||||
let t = T::from_str(s);
|
||||
println!("{:?}", t);
|
||||
assert!(t.is_ok());
|
||||
}
|
||||
NormalErr => {
|
||||
let t = T::from_str(s);
|
||||
println!("{:?}", t);
|
||||
assert!(t.is_err());
|
||||
}
|
||||
OtherError => {
|
||||
println!("{:?}", T::from_str(s));
|
||||
}
|
||||
OtherWithPanic => {
|
||||
if catch_unwind(|| println!("{:?}", T::from_str(s))).is_ok() {
|
||||
eprintln!("{s} did not panic");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn stream(s: &str, mode: Mode) {
|
||||
parse::<TokenStream>(s, mode);
|
||||
}
|
||||
|
||||
fn lit(s: &str, mode: Mode) {
|
||||
parse::<Literal>(s, mode);
|
||||
if mode == NormalOk {
|
||||
let Ok(lit) = Literal::from_str(s) else {
|
||||
panic!("literal was not ok");
|
||||
};
|
||||
let Ok(stream) = TokenStream::from_str(s) else {
|
||||
panic!("tokenstream was not ok, but literal was");
|
||||
};
|
||||
let Some(tree) = stream.into_iter().next() else {
|
||||
panic!("tokenstream should have a tokentree");
|
||||
};
|
||||
if let TokenTree::Literal(tokenstream_lit) = tree {
|
||||
assert_eq!(lit.to_string(), tokenstream_lit.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run() {
|
||||
// returns Ok(valid instance)
|
||||
lit("123", NormalOk);
|
||||
lit("\"ab\"", NormalOk);
|
||||
lit("\'b\'", NormalOk);
|
||||
lit("'b'", NormalOk);
|
||||
lit("b\"b\"", NormalOk);
|
||||
lit("c\"b\"", NormalOk);
|
||||
lit("cr\"b\"", NormalOk);
|
||||
lit("b'b'", NormalOk);
|
||||
lit("256u8", NormalOk);
|
||||
lit("-256u8", NormalOk);
|
||||
stream("-256u8", NormalOk);
|
||||
lit("0b11111000000001111i16", NormalOk);
|
||||
lit("0xf32", NormalOk);
|
||||
lit("0b0f32", NormalOk);
|
||||
lit("2E4", NormalOk);
|
||||
lit("2.2E-4f64", NormalOk);
|
||||
lit("18u8E", NormalOk);
|
||||
lit("18.0u8E", NormalOk);
|
||||
lit("cr#\"// /* // \n */\"#", NormalOk);
|
||||
lit("'\\''", NormalOk);
|
||||
lit("'\\\''", NormalOk);
|
||||
lit(&format!("r{0}\"a\"{0}", "#".repeat(255)), NormalOk);
|
||||
stream("fn main() { println!(\"Hello, world!\") }", NormalOk);
|
||||
stream("18.u8E", NormalOk);
|
||||
stream("18.0f32", NormalOk);
|
||||
stream("18.0f34", NormalOk);
|
||||
stream("18.bu8", NormalOk);
|
||||
stream("3//\n4", NormalOk);
|
||||
stream(
|
||||
"\'c\'/*\n
|
||||
*/",
|
||||
NormalOk,
|
||||
);
|
||||
stream("/*a*/ //", NormalOk);
|
||||
|
||||
println!("### ERRORS");
|
||||
|
||||
// returns Err(LexError)
|
||||
lit("\'c\'/**/", NormalErr);
|
||||
lit(" 0", NormalErr);
|
||||
lit("0 ", NormalErr);
|
||||
lit("0//", NormalErr);
|
||||
lit("3//\n4", NormalErr);
|
||||
lit("18.u8E", NormalErr);
|
||||
lit("/*a*/ //", NormalErr);
|
||||
// FIXME: all of the cases below should return an Err and emit no diagnostics, but don't yet.
|
||||
|
||||
// emits diagnostics and returns LexError
|
||||
lit("r'r'", OtherError);
|
||||
lit("c'r'", OtherError);
|
||||
|
||||
// emits diagnostic and returns a seemingly valid tokenstream
|
||||
stream("r'r'", OtherError);
|
||||
stream("c'r'", OtherError);
|
||||
|
||||
for parse in [stream as fn(&str, Mode), lit] {
|
||||
// emits diagnostic(s), then panics
|
||||
parse("1 ) 2", OtherWithPanic);
|
||||
parse("( x [ ) ]", OtherWithPanic);
|
||||
parse("r#", OtherWithPanic);
|
||||
|
||||
// emits diagnostic(s), then returns Ok(Literal { kind: ErrWithGuar, .. })
|
||||
parse("0b2", OtherError);
|
||||
parse("0bf32", OtherError);
|
||||
parse("0b0.0f32", OtherError);
|
||||
parse("'\''", OtherError);
|
||||
parse(
|
||||
"'
|
||||
'", OtherError,
|
||||
);
|
||||
parse(&format!("r{0}\"a\"{0}", "#".repeat(256)), OtherWithPanic);
|
||||
|
||||
// emits diagnostic, then, when parsing as a lit, returns LexError, otherwise ErrWithGuar
|
||||
parse("/*a*/ 0b2 //", OtherError);
|
||||
}
|
||||
}
|
||||
11
tests/ui/proc-macro/auxiliary/nonfatal-parsing.rs
Normal file
11
tests/ui/proc-macro/auxiliary/nonfatal-parsing.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
extern crate proc_macro;
|
||||
use proc_macro::*;
|
||||
|
||||
#[path = "nonfatal-parsing-body.rs"]
|
||||
mod body;
|
||||
|
||||
#[proc_macro]
|
||||
pub fn run(_: TokenStream) -> TokenStream {
|
||||
body::run();
|
||||
TokenStream::new()
|
||||
}
|
||||
19
tests/ui/proc-macro/nonfatal-parsing.rs
Normal file
19
tests/ui/proc-macro/nonfatal-parsing.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//@ proc-macro: nonfatal-parsing.rs
|
||||
//@ needs-unwind
|
||||
//@ edition: 2024
|
||||
//@ dont-require-annotations: ERROR
|
||||
//@ ignore-backends: gcc
|
||||
// FIXME: should be a run-pass test once invalidly parsed tokens no longer result in diagnostics
|
||||
|
||||
extern crate proc_macro;
|
||||
extern crate nonfatal_parsing;
|
||||
|
||||
#[path = "auxiliary/nonfatal-parsing-body.rs"]
|
||||
mod body;
|
||||
|
||||
fn main() {
|
||||
nonfatal_parsing::run!();
|
||||
// FIXME: enable this once the standalone backend exists
|
||||
// https://github.com/rust-lang/rust/issues/130856
|
||||
// body::run();
|
||||
}
|
||||
197
tests/ui/proc-macro/nonfatal-parsing.stderr
Normal file
197
tests/ui/proc-macro/nonfatal-parsing.stderr
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
error: prefix `r` is unknown
|
||||
--> <proc-macro source code>:1:1
|
||||
|
|
||||
LL | r'r'
|
||||
| ^ unknown prefix
|
||||
|
|
||||
= note: prefixed identifiers and literals are reserved since Rust 2021
|
||||
help: consider inserting whitespace here
|
||||
|
|
||||
LL | r 'r'
|
||||
| +
|
||||
|
||||
error: prefix `c` is unknown
|
||||
--> <proc-macro source code>:1:1
|
||||
|
|
||||
LL | c'r'
|
||||
| ^ unknown prefix
|
||||
|
|
||||
= note: prefixed identifiers and literals are reserved since Rust 2021
|
||||
help: consider inserting whitespace here
|
||||
|
|
||||
LL | c 'r'
|
||||
| +
|
||||
|
||||
error: unexpected closing delimiter: `)`
|
||||
--> $DIR/nonfatal-parsing.rs:15:5
|
||||
|
|
||||
LL | nonfatal_parsing::run!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ unexpected closing delimiter
|
||||
|
|
||||
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: unexpected closing delimiter: `]`
|
||||
--> $DIR/nonfatal-parsing.rs:15:5
|
||||
|
|
||||
LL | nonfatal_parsing::run!();
|
||||
| -^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| the nearest open delimiter
|
||||
| missing open `(` for this delimiter
|
||||
| unexpected closing delimiter
|
||||
|
|
||||
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: found invalid character; only `#` is allowed in raw string delimitation: \u{0}
|
||||
--> $DIR/nonfatal-parsing.rs:15:5
|
||||
|
|
||||
LL | nonfatal_parsing::run!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: invalid digit for a base 2 literal
|
||||
--> $DIR/nonfatal-parsing.rs:15:5
|
||||
|
|
||||
LL | nonfatal_parsing::run!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0768]: no valid digits found for number
|
||||
--> $DIR/nonfatal-parsing.rs:15:5
|
||||
|
|
||||
LL | nonfatal_parsing::run!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: binary float literal is not supported
|
||||
--> $DIR/nonfatal-parsing.rs:15:5
|
||||
|
|
||||
LL | nonfatal_parsing::run!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: character constant must be escaped: `'`
|
||||
--> $DIR/nonfatal-parsing.rs:15:5
|
||||
|
|
||||
LL | nonfatal_parsing::run!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: escape the character
|
||||
|
|
||||
LL - nonfatal_parsing::run!();
|
||||
LL + nonfatal_parsing::run!(\';
|
||||
|
|
||||
|
||||
error: character constant must be escaped: `\n`
|
||||
--> $DIR/nonfatal-parsing.rs:15:5
|
||||
|
|
||||
LL | nonfatal_parsing::run!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: escape the character
|
||||
|
|
||||
LL - nonfatal_parsing::run!();
|
||||
LL + nonfatal_parsing::run!(\n;
|
||||
|
|
||||
|
||||
error: too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found 256
|
||||
--> $DIR/nonfatal-parsing.rs:15:5
|
||||
|
|
||||
LL | nonfatal_parsing::run!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: invalid digit for a base 2 literal
|
||||
--> $DIR/nonfatal-parsing.rs:15:5
|
||||
|
|
||||
LL | nonfatal_parsing::run!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
= note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: unexpected closing delimiter: `)`
|
||||
--> <proc-macro source code>:1:3
|
||||
|
|
||||
LL | 1 ) 2
|
||||
| ^ unexpected closing delimiter
|
||||
|
||||
error: unexpected closing delimiter: `]`
|
||||
--> <proc-macro source code>:1:10
|
||||
|
|
||||
LL | ( x [ ) ]
|
||||
| - - ^ unexpected closing delimiter
|
||||
| | |
|
||||
| | missing open `(` for this delimiter
|
||||
| the nearest open delimiter
|
||||
|
||||
error: found invalid character; only `#` is allowed in raw string delimitation: \u{0}
|
||||
--> <proc-macro source code>:1:1
|
||||
|
|
||||
LL | r#
|
||||
| ^^
|
||||
|
||||
error: invalid digit for a base 2 literal
|
||||
--> <proc-macro source code>:1:3
|
||||
|
|
||||
LL | 0b2
|
||||
| ^
|
||||
|
||||
error[E0768]: no valid digits found for number
|
||||
--> <proc-macro source code>:1:1
|
||||
|
|
||||
LL | 0bf32
|
||||
| ^^
|
||||
|
||||
error: binary float literal is not supported
|
||||
--> <proc-macro source code>:1:1
|
||||
|
|
||||
LL | 0b0.0f32
|
||||
| ^^^^^
|
||||
|
||||
error: character constant must be escaped: `'`
|
||||
--> <proc-macro source code>:1:2
|
||||
|
|
||||
LL | '''
|
||||
| ^
|
||||
|
|
||||
help: escape the character
|
||||
|
|
||||
LL | '\''
|
||||
| +
|
||||
|
||||
error: character constant must be escaped: `\n`
|
||||
--> <proc-macro source code>:1:2
|
||||
|
|
||||
LL | '
|
||||
| __^
|
||||
LL | | '
|
||||
| |_^
|
||||
|
|
||||
help: escape the character
|
||||
|
|
||||
LL | '\n'
|
||||
| ++
|
||||
|
||||
error: too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found 256
|
||||
--> <proc-macro source code>:1:1
|
||||
|
|
||||
LL | r#######################################...##################################################
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: invalid digit for a base 2 literal
|
||||
--> <proc-macro source code>:1:9
|
||||
|
|
||||
LL | /*a*/ 0b2 //
|
||||
| ^
|
||||
|
||||
error: aborting due to 22 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0768`.
|
||||
54
tests/ui/proc-macro/nonfatal-parsing.stdout
Normal file
54
tests/ui/proc-macro/nonfatal-parsing.stdout
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
Ok(Literal { kind: Integer, symbol: "123", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Str, symbol: "ab", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Char, symbol: "b", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Char, symbol: "b", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: ByteStr, symbol: "b", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: CStr, symbol: "b", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: CStrRaw(0), symbol: "b", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Byte, symbol: "b", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Integer, symbol: "-256", suffix: Some("u8"), span: #44 bytes(361..385) })
|
||||
Ok(TokenStream [Punct { ch: '-', spacing: Alone, span: #44 bytes(361..385) }, Literal { kind: Integer, symbol: "256", suffix: Some("u8"), span: #44 bytes(361..385) }])
|
||||
Ok(Literal { kind: Integer, symbol: "0b11111000000001111", suffix: Some("i16"), span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Integer, symbol: "0xf32", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Integer, symbol: "0b0", suffix: Some("f32"), span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Float, symbol: "2E4", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Float, symbol: "2.2E-4", suffix: Some("f64"), span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Integer, symbol: "18", suffix: Some("u8E"), span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Float, symbol: "18.0", suffix: Some("u8E"), span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: CStrRaw(1), symbol: "// /* // \n */", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: Char, symbol: "\'", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: StrRaw(255), symbol: "a", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(TokenStream [Ident { ident: "fn", span: #44 bytes(361..385) }, Ident { ident: "main", span: #44 bytes(361..385) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #44 bytes(361..385) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "println", span: #44 bytes(361..385) }, Punct { ch: '!', spacing: Alone, span: #44 bytes(361..385) }, Group { delimiter: Parenthesis, stream: TokenStream [Literal { kind: Str, symbol: "Hello, world!", suffix: None, span: #44 bytes(361..385) }], span: #44 bytes(361..385) }], span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: #44 bytes(361..385) }, Punct { ch: '.', spacing: Alone, span: #44 bytes(361..385) }, Ident { ident: "u8E", span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f32"), span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: Float, symbol: "18.0", suffix: Some("f34"), span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: Integer, symbol: "18", suffix: None, span: #44 bytes(361..385) }, Punct { ch: '.', spacing: Alone, span: #44 bytes(361..385) }, Ident { ident: "bu8", span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: Integer, symbol: "3", suffix: None, span: #44 bytes(361..385) }, Literal { kind: Integer, symbol: "4", suffix: None, span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: Char, symbol: "c", suffix: None, span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [])
|
||||
### ERRORS
|
||||
Err(LexError)
|
||||
Err(LexError)
|
||||
Err(LexError)
|
||||
Err(LexError)
|
||||
Err(LexError)
|
||||
Err(LexError)
|
||||
Err(LexError)
|
||||
Err(LexError)
|
||||
Err(LexError)
|
||||
Ok(TokenStream [Ident { ident: "r", span: #44 bytes(361..385) }, Literal { kind: Char, symbol: "r", suffix: None, span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Ident { ident: "c", span: #44 bytes(361..385) }, Literal { kind: Char, symbol: "r", suffix: None, span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #44 bytes(361..385) }])
|
||||
Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }])
|
||||
Ok(Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #44 bytes(361..385) })
|
||||
Ok(Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #44 bytes(361..385) })
|
||||
Err(LexError)
|
||||
|
|
@ -1070,7 +1070,6 @@ source file via `./x run src/tools/unicode-table-generator` instead of editing \
|
|||
message = "Some changes occurred in HTML/CSS/JS."
|
||||
cc = [
|
||||
"@GuillaumeGomez",
|
||||
"@jsha",
|
||||
"@lolbinarycat",
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue