From e9191ec57ee5bdd0961a22fd9852f361a5c97ea0 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 1 Jul 2025 21:42:20 +0500 Subject: [PATCH 01/15] moved tests --- .../auto-traits-type-parameter} | 0 .../const-eval-array-len-in-impl.rs} | 0 .../const-eval-array-len-in-impl.stderr} | 0 .../let-binding-tuple-destructuring.rs} | 0 .../any-lifetime-escape-higher-rank.rs} | 0 .../type-length-limit-enforcement.rs} | 0 .../type-length-limit-enforcement.stderr} | 0 .../macro-fragment-ident-underscore-error.rs} | 0 .../macro-fragment-ident-underscore-error.stderr} | 0 .../struct-type-and-function-name-coexistence.rs} | 0 .../integer-literal-method-call-underscore.rs} | 0 .../ptr-write-bool-representation.rs} | 0 tests/ui/{type-ptr.rs => ptr_ops/raw-pointer-type-basic.rs} | 0 .../try-operator-expansion-hygiene.rs} | 0 .../try-operator-various-contexts.rs} | 0 .../type-inference-none-in-generic-ref.rs} | 0 .../type-inference-none-in-generic-ref.stderr} | 0 .../type-inference-unconstrained-none.rs} | 0 .../type-inference-unconstrained-none.stderr} | 0 tests/ui/{tydesc-name.rs => type/type-name-basic.rs} | 0 .../typeid-consistency-comprehensive.rs} | 0 .../basic-underscore-lifetime-elision.rs} | 0 22 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{type-param-constraints.rs => auto-traits/auto-traits-type-parameter} (100%) rename tests/ui/{unevaluated_fixed_size_array_len.rs => consts/const-eval-array-len-in-impl.rs} (100%) rename tests/ui/{unevaluated_fixed_size_array_len.stderr => consts/const-eval-array-len-in-impl.stderr} (100%) rename tests/ui/{typestate-multi-decl.rs => destructuring-assignment/let-binding-tuple-destructuring.rs} (100%) rename tests/ui/{type-id-higher-rank-2.rs => lifetimes/any-lifetime-escape-higher-rank.rs} (100%) rename tests/ui/{type_length_limit.rs => limits/type-length-limit-enforcement.rs} (100%) rename tests/ui/{type_length_limit.stderr => limits/type-length-limit-enforcement.stderr} (100%) rename tests/ui/{underscore-ident-matcher.rs => macros/macro-fragment-ident-underscore-error.rs} (100%) rename tests/ui/{underscore-ident-matcher.stderr => macros/macro-fragment-ident-underscore-error.stderr} (100%) rename tests/ui/{type-namespace.rs => namespace/struct-type-and-function-name-coexistence.rs} (100%) rename tests/ui/{underscore-method-after-integer.rs => parser/integer-literal-method-call-underscore.rs} (100%) rename tests/ui/{type-use-i1-versus-i8.rs => ptr_ops/ptr-write-bool-representation.rs} (100%) rename tests/ui/{type-ptr.rs => ptr_ops/raw-pointer-type-basic.rs} (100%) rename tests/ui/{try-operator-hygiene.rs => try-trait/try-operator-expansion-hygiene.rs} (100%) rename tests/ui/{try-operator.rs => try-trait/try-operator-various-contexts.rs} (100%) rename tests/ui/{unconstrained-ref.rs => type-inference/type-inference-none-in-generic-ref.rs} (100%) rename tests/ui/{unconstrained-ref.stderr => type-inference/type-inference-none-in-generic-ref.stderr} (100%) rename tests/ui/{unconstrained-none.rs => type-inference/type-inference-unconstrained-none.rs} (100%) rename tests/ui/{unconstrained-none.stderr => type-inference/type-inference-unconstrained-none.stderr} (100%) rename tests/ui/{tydesc-name.rs => type/type-name-basic.rs} (100%) rename tests/ui/{typeid-intrinsic.rs => type/typeid-consistency-comprehensive.rs} (100%) rename tests/ui/{underscore-lifetimes.rs => underscore-lifetime/basic-underscore-lifetime-elision.rs} (100%) diff --git a/tests/ui/type-param-constraints.rs b/tests/ui/auto-traits/auto-traits-type-parameter similarity index 100% rename from tests/ui/type-param-constraints.rs rename to tests/ui/auto-traits/auto-traits-type-parameter diff --git a/tests/ui/unevaluated_fixed_size_array_len.rs b/tests/ui/consts/const-eval-array-len-in-impl.rs similarity index 100% rename from tests/ui/unevaluated_fixed_size_array_len.rs rename to tests/ui/consts/const-eval-array-len-in-impl.rs diff --git a/tests/ui/unevaluated_fixed_size_array_len.stderr b/tests/ui/consts/const-eval-array-len-in-impl.stderr similarity index 100% rename from tests/ui/unevaluated_fixed_size_array_len.stderr rename to tests/ui/consts/const-eval-array-len-in-impl.stderr diff --git a/tests/ui/typestate-multi-decl.rs b/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs similarity index 100% rename from tests/ui/typestate-multi-decl.rs rename to tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs diff --git a/tests/ui/type-id-higher-rank-2.rs b/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs similarity index 100% rename from tests/ui/type-id-higher-rank-2.rs rename to tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs diff --git a/tests/ui/type_length_limit.rs b/tests/ui/limits/type-length-limit-enforcement.rs similarity index 100% rename from tests/ui/type_length_limit.rs rename to tests/ui/limits/type-length-limit-enforcement.rs diff --git a/tests/ui/type_length_limit.stderr b/tests/ui/limits/type-length-limit-enforcement.stderr similarity index 100% rename from tests/ui/type_length_limit.stderr rename to tests/ui/limits/type-length-limit-enforcement.stderr diff --git a/tests/ui/underscore-ident-matcher.rs b/tests/ui/macros/macro-fragment-ident-underscore-error.rs similarity index 100% rename from tests/ui/underscore-ident-matcher.rs rename to tests/ui/macros/macro-fragment-ident-underscore-error.rs diff --git a/tests/ui/underscore-ident-matcher.stderr b/tests/ui/macros/macro-fragment-ident-underscore-error.stderr similarity index 100% rename from tests/ui/underscore-ident-matcher.stderr rename to tests/ui/macros/macro-fragment-ident-underscore-error.stderr diff --git a/tests/ui/type-namespace.rs b/tests/ui/namespace/struct-type-and-function-name-coexistence.rs similarity index 100% rename from tests/ui/type-namespace.rs rename to tests/ui/namespace/struct-type-and-function-name-coexistence.rs diff --git a/tests/ui/underscore-method-after-integer.rs b/tests/ui/parser/integer-literal-method-call-underscore.rs similarity index 100% rename from tests/ui/underscore-method-after-integer.rs rename to tests/ui/parser/integer-literal-method-call-underscore.rs diff --git a/tests/ui/type-use-i1-versus-i8.rs b/tests/ui/ptr_ops/ptr-write-bool-representation.rs similarity index 100% rename from tests/ui/type-use-i1-versus-i8.rs rename to tests/ui/ptr_ops/ptr-write-bool-representation.rs diff --git a/tests/ui/type-ptr.rs b/tests/ui/ptr_ops/raw-pointer-type-basic.rs similarity index 100% rename from tests/ui/type-ptr.rs rename to tests/ui/ptr_ops/raw-pointer-type-basic.rs diff --git a/tests/ui/try-operator-hygiene.rs b/tests/ui/try-trait/try-operator-expansion-hygiene.rs similarity index 100% rename from tests/ui/try-operator-hygiene.rs rename to tests/ui/try-trait/try-operator-expansion-hygiene.rs diff --git a/tests/ui/try-operator.rs b/tests/ui/try-trait/try-operator-various-contexts.rs similarity index 100% rename from tests/ui/try-operator.rs rename to tests/ui/try-trait/try-operator-various-contexts.rs diff --git a/tests/ui/unconstrained-ref.rs b/tests/ui/type-inference/type-inference-none-in-generic-ref.rs similarity index 100% rename from tests/ui/unconstrained-ref.rs rename to tests/ui/type-inference/type-inference-none-in-generic-ref.rs diff --git a/tests/ui/unconstrained-ref.stderr b/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr similarity index 100% rename from tests/ui/unconstrained-ref.stderr rename to tests/ui/type-inference/type-inference-none-in-generic-ref.stderr diff --git a/tests/ui/unconstrained-none.rs b/tests/ui/type-inference/type-inference-unconstrained-none.rs similarity index 100% rename from tests/ui/unconstrained-none.rs rename to tests/ui/type-inference/type-inference-unconstrained-none.rs diff --git a/tests/ui/unconstrained-none.stderr b/tests/ui/type-inference/type-inference-unconstrained-none.stderr similarity index 100% rename from tests/ui/unconstrained-none.stderr rename to tests/ui/type-inference/type-inference-unconstrained-none.stderr diff --git a/tests/ui/tydesc-name.rs b/tests/ui/type/type-name-basic.rs similarity index 100% rename from tests/ui/tydesc-name.rs rename to tests/ui/type/type-name-basic.rs diff --git a/tests/ui/typeid-intrinsic.rs b/tests/ui/type/typeid-consistency-comprehensive.rs similarity index 100% rename from tests/ui/typeid-intrinsic.rs rename to tests/ui/type/typeid-consistency-comprehensive.rs diff --git a/tests/ui/underscore-lifetimes.rs b/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs similarity index 100% rename from tests/ui/underscore-lifetimes.rs rename to tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs From 1fb5e0149fb85af0e49fa40329cbc352b4cba861 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 1 Jul 2025 23:33:59 +0500 Subject: [PATCH 02/15] moved tests --- .../weak-uninhabited-type.rs} | 0 .../underscore-prefixed-function-argument.rs} | 0 .../ownership-struct-update-moved-error.rs} | 0 .../ownership-struct-update-moved-error.stderr} | 0 .../no-capture-closure-call.rs} | 0 .../ui/{unknown-llvm-arg.rs => codegen/llvm-args-invalid-flag.rs} | 0 .../llvm-args-invalid-flag.stderr} | 0 .../box-drop-unused-value-statement-regression.rs} | 0 tests/ui/{weird-exprs.rs => expr/syntax-edge-cases-lint-clean.rs} | 0 .../hashset-enum-variant.rs} | 0 tests/ui/{write-fmt-errors.rs => io-checks/write-macro-error.rs} | 0 .../lang-item-unknown-definition-error.rs} | 0 .../lang-item-unknown-definition-error.stderr} | 0 .../module-qualified-paths-basic.rs} | 0 .../{use-nested-groups.rs => modules/module-use-nested-groups.rs} | 0 .../primitive-type-module-deprecated-paths.rs} | 0 .../use-keyword-reexport-type-alias.rs} | 0 .../unary-negation-unsigned-integer-error.rs} | 0 .../unary-negation-unsigned-integer-error.stderr} | 0 .../unwind-force-no-unwind-tables.rs} | 0 .../process-spawn-failure.rs} | 0 .../windows-exit-code-still-active.rs} | 0 .../diverging-expressions-unreachable-code.rs} | 0 .../unreachable-code-diverging-expressions.rs} | 0 .../virtual-call-parameter-handling.rs} | 0 tests/ui/{unit.rs => type/unit-type-basic-usages.rs} | 0 .../usize-no-generic-arguments.rs} | 0 .../usize-no-generic-arguments.stderr} | 0 .../maybe-uninit-zero-sized-types.rs} | 0 29 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{weak-new-uninhabited-issue-48493.rs => allocator/weak-uninhabited-type.rs} (100%) rename tests/ui/{unnamed_argument_mode.rs => binding/underscore-prefixed-function-argument.rs} (100%) rename tests/ui/{walk-struct-literal-with.rs => borrowck/ownership-struct-update-moved-error.rs} (100%) rename tests/ui/{walk-struct-literal-with.stderr => borrowck/ownership-struct-update-moved-error.stderr} (100%) rename tests/ui/{unused-move-capture.rs => closures/no-capture-closure-call.rs} (100%) rename tests/ui/{unknown-llvm-arg.rs => codegen/llvm-args-invalid-flag.rs} (100%) rename tests/ui/{unknown-llvm-arg.stderr => codegen/llvm-args-invalid-flag.stderr} (100%) rename tests/ui/{unused-move.rs => drop/box-drop-unused-value-statement-regression.rs} (100%) rename tests/ui/{weird-exprs.rs => expr/syntax-edge-cases-lint-clean.rs} (100%) rename tests/ui/{wrong-hashset-issue-42918.rs => hashmap/hashset-enum-variant.rs} (100%) rename tests/ui/{write-fmt-errors.rs => io-checks/write-macro-error.rs} (100%) rename tests/ui/{unknown-language-item.rs => lang-items/lang-item-unknown-definition-error.rs} (100%) rename tests/ui/{unknown-language-item.stderr => lang-items/lang-item-unknown-definition-error.stderr} (100%) rename tests/ui/{use-import-export.rs => modules/module-qualified-paths-basic.rs} (100%) rename tests/ui/{use-nested-groups.rs => modules/module-use-nested-groups.rs} (100%) rename tests/ui/{use-module-level-int-consts.rs => modules/primitive-type-module-deprecated-paths.rs} (100%) rename tests/ui/{use-keyword-2.rs => modules/use-keyword-reexport-type-alias.rs} (100%) rename tests/ui/{unsigned-literal-negation.rs => numbers-arithmetic/unary-negation-unsigned-integer-error.rs} (100%) rename tests/ui/{unsigned-literal-negation.stderr => numbers-arithmetic/unary-negation-unsigned-integer-error.stderr} (100%) rename tests/ui/{unwind-no-uwtable.rs => panics/unwind-force-no-unwind-tables.rs} (100%) rename tests/ui/{wait-forked-but-failed-child.rs => process/process-spawn-failure.rs} (100%) rename tests/ui/{weird-exit-code.rs => process/windows-exit-code-still-active.rs} (100%) rename tests/ui/{unreachable-code-1.rs => reachable/diverging-expressions-unreachable-code.rs} (100%) rename tests/ui/{unreachable-code.rs => reachable/unreachable-code-diverging-expressions.rs} (100%) rename tests/ui/{virtual-call-attrs-issue-137646.rs => traits/virtual-call-parameter-handling.rs} (100%) rename tests/ui/{unit.rs => type/unit-type-basic-usages.rs} (100%) rename tests/ui/{usize-generic-argument-parent.rs => type/usize-no-generic-arguments.rs} (100%) rename tests/ui/{usize-generic-argument-parent.stderr => type/usize-no-generic-arguments.stderr} (100%) rename tests/ui/{uninit-empty-types.rs => unsafe/maybe-uninit-zero-sized-types.rs} (100%) diff --git a/tests/ui/weak-new-uninhabited-issue-48493.rs b/tests/ui/allocator/weak-uninhabited-type.rs similarity index 100% rename from tests/ui/weak-new-uninhabited-issue-48493.rs rename to tests/ui/allocator/weak-uninhabited-type.rs diff --git a/tests/ui/unnamed_argument_mode.rs b/tests/ui/binding/underscore-prefixed-function-argument.rs similarity index 100% rename from tests/ui/unnamed_argument_mode.rs rename to tests/ui/binding/underscore-prefixed-function-argument.rs diff --git a/tests/ui/walk-struct-literal-with.rs b/tests/ui/borrowck/ownership-struct-update-moved-error.rs similarity index 100% rename from tests/ui/walk-struct-literal-with.rs rename to tests/ui/borrowck/ownership-struct-update-moved-error.rs diff --git a/tests/ui/walk-struct-literal-with.stderr b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr similarity index 100% rename from tests/ui/walk-struct-literal-with.stderr rename to tests/ui/borrowck/ownership-struct-update-moved-error.stderr diff --git a/tests/ui/unused-move-capture.rs b/tests/ui/closures/no-capture-closure-call.rs similarity index 100% rename from tests/ui/unused-move-capture.rs rename to tests/ui/closures/no-capture-closure-call.rs diff --git a/tests/ui/unknown-llvm-arg.rs b/tests/ui/codegen/llvm-args-invalid-flag.rs similarity index 100% rename from tests/ui/unknown-llvm-arg.rs rename to tests/ui/codegen/llvm-args-invalid-flag.rs diff --git a/tests/ui/unknown-llvm-arg.stderr b/tests/ui/codegen/llvm-args-invalid-flag.stderr similarity index 100% rename from tests/ui/unknown-llvm-arg.stderr rename to tests/ui/codegen/llvm-args-invalid-flag.stderr diff --git a/tests/ui/unused-move.rs b/tests/ui/drop/box-drop-unused-value-statement-regression.rs similarity index 100% rename from tests/ui/unused-move.rs rename to tests/ui/drop/box-drop-unused-value-statement-regression.rs diff --git a/tests/ui/weird-exprs.rs b/tests/ui/expr/syntax-edge-cases-lint-clean.rs similarity index 100% rename from tests/ui/weird-exprs.rs rename to tests/ui/expr/syntax-edge-cases-lint-clean.rs diff --git a/tests/ui/wrong-hashset-issue-42918.rs b/tests/ui/hashmap/hashset-enum-variant.rs similarity index 100% rename from tests/ui/wrong-hashset-issue-42918.rs rename to tests/ui/hashmap/hashset-enum-variant.rs diff --git a/tests/ui/write-fmt-errors.rs b/tests/ui/io-checks/write-macro-error.rs similarity index 100% rename from tests/ui/write-fmt-errors.rs rename to tests/ui/io-checks/write-macro-error.rs diff --git a/tests/ui/unknown-language-item.rs b/tests/ui/lang-items/lang-item-unknown-definition-error.rs similarity index 100% rename from tests/ui/unknown-language-item.rs rename to tests/ui/lang-items/lang-item-unknown-definition-error.rs diff --git a/tests/ui/unknown-language-item.stderr b/tests/ui/lang-items/lang-item-unknown-definition-error.stderr similarity index 100% rename from tests/ui/unknown-language-item.stderr rename to tests/ui/lang-items/lang-item-unknown-definition-error.stderr diff --git a/tests/ui/use-import-export.rs b/tests/ui/modules/module-qualified-paths-basic.rs similarity index 100% rename from tests/ui/use-import-export.rs rename to tests/ui/modules/module-qualified-paths-basic.rs diff --git a/tests/ui/use-nested-groups.rs b/tests/ui/modules/module-use-nested-groups.rs similarity index 100% rename from tests/ui/use-nested-groups.rs rename to tests/ui/modules/module-use-nested-groups.rs diff --git a/tests/ui/use-module-level-int-consts.rs b/tests/ui/modules/primitive-type-module-deprecated-paths.rs similarity index 100% rename from tests/ui/use-module-level-int-consts.rs rename to tests/ui/modules/primitive-type-module-deprecated-paths.rs diff --git a/tests/ui/use-keyword-2.rs b/tests/ui/modules/use-keyword-reexport-type-alias.rs similarity index 100% rename from tests/ui/use-keyword-2.rs rename to tests/ui/modules/use-keyword-reexport-type-alias.rs diff --git a/tests/ui/unsigned-literal-negation.rs b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs similarity index 100% rename from tests/ui/unsigned-literal-negation.rs rename to tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs diff --git a/tests/ui/unsigned-literal-negation.stderr b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr similarity index 100% rename from tests/ui/unsigned-literal-negation.stderr rename to tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr diff --git a/tests/ui/unwind-no-uwtable.rs b/tests/ui/panics/unwind-force-no-unwind-tables.rs similarity index 100% rename from tests/ui/unwind-no-uwtable.rs rename to tests/ui/panics/unwind-force-no-unwind-tables.rs diff --git a/tests/ui/wait-forked-but-failed-child.rs b/tests/ui/process/process-spawn-failure.rs similarity index 100% rename from tests/ui/wait-forked-but-failed-child.rs rename to tests/ui/process/process-spawn-failure.rs diff --git a/tests/ui/weird-exit-code.rs b/tests/ui/process/windows-exit-code-still-active.rs similarity index 100% rename from tests/ui/weird-exit-code.rs rename to tests/ui/process/windows-exit-code-still-active.rs diff --git a/tests/ui/unreachable-code-1.rs b/tests/ui/reachable/diverging-expressions-unreachable-code.rs similarity index 100% rename from tests/ui/unreachable-code-1.rs rename to tests/ui/reachable/diverging-expressions-unreachable-code.rs diff --git a/tests/ui/unreachable-code.rs b/tests/ui/reachable/unreachable-code-diverging-expressions.rs similarity index 100% rename from tests/ui/unreachable-code.rs rename to tests/ui/reachable/unreachable-code-diverging-expressions.rs diff --git a/tests/ui/virtual-call-attrs-issue-137646.rs b/tests/ui/traits/virtual-call-parameter-handling.rs similarity index 100% rename from tests/ui/virtual-call-attrs-issue-137646.rs rename to tests/ui/traits/virtual-call-parameter-handling.rs diff --git a/tests/ui/unit.rs b/tests/ui/type/unit-type-basic-usages.rs similarity index 100% rename from tests/ui/unit.rs rename to tests/ui/type/unit-type-basic-usages.rs diff --git a/tests/ui/usize-generic-argument-parent.rs b/tests/ui/type/usize-no-generic-arguments.rs similarity index 100% rename from tests/ui/usize-generic-argument-parent.rs rename to tests/ui/type/usize-no-generic-arguments.rs diff --git a/tests/ui/usize-generic-argument-parent.stderr b/tests/ui/type/usize-no-generic-arguments.stderr similarity index 100% rename from tests/ui/usize-generic-argument-parent.stderr rename to tests/ui/type/usize-no-generic-arguments.stderr diff --git a/tests/ui/uninit-empty-types.rs b/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs similarity index 100% rename from tests/ui/uninit-empty-types.rs rename to tests/ui/unsafe/maybe-uninit-zero-sized-types.rs From ae5cb5f66d88f75d88eb9d37fc1bf73c169f47c5 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 7 Jul 2025 22:43:59 +0300 Subject: [PATCH 03/15] Mention more APIs in `ParseIntError` docs --- library/core/src/num/error.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index a5242d60bf14d..f9c4cdd0ebe63 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -45,8 +45,11 @@ impl From for TryFromIntError { /// An error which can be returned when parsing an integer. /// -/// This error is used as the error type for the `from_str_radix()` functions -/// on the primitive integer types, such as [`i8::from_str_radix`]. +/// For example, this error is returned by the `from_str_radix()` functions +/// on the primitive integer types (such as [`i8::from_str_radix`]) +/// and is used as the error type in their [`FromStr`] implementations. +/// +/// [`FromStr`]: crate::str::FromStr /// /// # Potential causes /// From d8273d39978ed16528c9792f9c4a81cc596bf7f8 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Mon, 7 Jul 2025 14:16:41 +0530 Subject: [PATCH 04/15] std: sys: net: uefi: tcp4: Add timeout support - Implement timeout support for read, write and connect. - A software implementation using Instant. Signed-off-by: Ayush Singh --- .../std/src/sys/net/connection/uefi/mod.rs | 41 +++++++---- .../std/src/sys/net/connection/uefi/tcp.rs | 13 ++-- .../std/src/sys/net/connection/uefi/tcp4.rs | 68 +++++++++++++++++-- 3 files changed, 97 insertions(+), 25 deletions(-) diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs index 6835ba44ee242..884cbd4ac1dc7 100644 --- a/library/std/src/sys/net/connection/uefi/mod.rs +++ b/library/std/src/sys/net/connection/uefi/mod.rs @@ -1,37 +1,54 @@ use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; +use crate::sync::{Arc, Mutex}; use crate::sys::unsupported; use crate::time::Duration; mod tcp; pub(crate) mod tcp4; -pub struct TcpStream(tcp::Tcp); +pub struct TcpStream { + inner: tcp::Tcp, + read_timeout: Arc>>, + write_timeout: Arc>>, +} impl TcpStream { pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result { - tcp::Tcp::connect(addr?).map(Self) + let inner = tcp::Tcp::connect(addr?, None)?; + Ok(Self { + inner, + read_timeout: Arc::new(Mutex::new(None)), + write_timeout: Arc::new(Mutex::new(None)), + }) } - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result { - unsupported() + pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result { + let inner = tcp::Tcp::connect(addr, Some(timeout))?; + Ok(Self { + inner, + read_timeout: Arc::new(Mutex::new(None)), + write_timeout: Arc::new(Mutex::new(None)), + }) } - pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { - unsupported() + pub fn set_read_timeout(&self, t: Option) -> io::Result<()> { + self.read_timeout.set(t).unwrap(); + Ok(()) } - pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { - unsupported() + pub fn set_write_timeout(&self, t: Option) -> io::Result<()> { + self.write_timeout.set(t).unwrap(); + Ok(()) } pub fn read_timeout(&self) -> io::Result> { - unsupported() + Ok(self.read_timeout.get_cloned().unwrap()) } pub fn write_timeout(&self) -> io::Result> { - unsupported() + Ok(self.write_timeout.get_cloned().unwrap()) } pub fn peek(&self, _: &mut [u8]) -> io::Result { @@ -39,7 +56,7 @@ impl TcpStream { } pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) + self.inner.read(buf, self.read_timeout()?) } pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> { @@ -56,7 +73,7 @@ impl TcpStream { } pub fn write(&self, buf: &[u8]) -> io::Result { - self.0.write(buf) + self.inner.write(buf, self.write_timeout()?) } pub fn write_vectored(&self, buf: &[IoSlice<'_>]) -> io::Result { diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index 55b6dbf2490bd..1152f69446e42 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs @@ -1,33 +1,34 @@ use super::tcp4; use crate::io; use crate::net::SocketAddr; +use crate::time::Duration; pub(crate) enum Tcp { V4(tcp4::Tcp4), } impl Tcp { - pub(crate) fn connect(addr: &SocketAddr) -> io::Result { + pub(crate) fn connect(addr: &SocketAddr, timeout: Option) -> io::Result { match addr { SocketAddr::V4(x) => { let temp = tcp4::Tcp4::new()?; temp.configure(true, Some(x), None)?; - temp.connect()?; + temp.connect(timeout)?; Ok(Tcp::V4(temp)) } SocketAddr::V6(_) => todo!(), } } - pub(crate) fn write(&self, buf: &[u8]) -> io::Result { + pub(crate) fn write(&self, buf: &[u8], timeout: Option) -> io::Result { match self { - Self::V4(client) => client.write(buf), + Self::V4(client) => client.write(buf, timeout), } } - pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result { + pub(crate) fn read(&self, buf: &mut [u8], timeout: Option) -> io::Result { match self { - Self::V4(client) => client.read(buf), + Self::V4(client) => client.read(buf, timeout), } } } diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs index af1ba2be47adb..6342718929a7d 100644 --- a/library/std/src/sys/net/connection/uefi/tcp4.rs +++ b/library/std/src/sys/net/connection/uefi/tcp4.rs @@ -6,6 +6,7 @@ use crate::net::SocketAddrV4; use crate::ptr::NonNull; use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::pal::helpers; +use crate::time::{Duration, Instant}; const TYPE_OF_SERVICE: u8 = 8; const TIME_TO_LIVE: u8 = 255; @@ -66,7 +67,7 @@ impl Tcp4 { if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } - pub(crate) fn connect(&self) -> io::Result<()> { + pub(crate) fn connect(&self, timeout: Option) -> io::Result<()> { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -79,7 +80,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut conn_token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -88,7 +89,7 @@ impl Tcp4 { } } - pub(crate) fn write(&self, buf: &[u8]) -> io::Result { + pub(crate) fn write(&self, buf: &[u8], timeout: Option) -> io::Result { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -119,7 +120,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -128,7 +129,7 @@ impl Tcp4 { } } - pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result { + pub(crate) fn read(&self, buf: &mut [u8], timeout: Option) -> io::Result { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -158,7 +159,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -167,6 +168,50 @@ impl Tcp4 { } } + /// Wait for an event to finish. This is checked by an atomic boolean that is supposed to be set + /// to true in the event callback. + /// + /// Optionally, allow specifying a timeout. + /// + /// If a timeout is provided, the operation (specified by its `EFI_TCP4_COMPLETION_TOKEN`) is + /// canceled and Error of kind TimedOut is returned. + /// + /// # SAFETY + /// + /// Pointer to a valid `EFI_TCP4_COMPLETION_TOKEN` + unsafe fn wait_or_cancel( + &self, + timeout: Option, + token: *mut tcp4::CompletionToken, + ) -> io::Result<()> { + if !self.wait_for_flag(timeout) { + let _ = unsafe { self.cancel(token) }; + return Err(io::Error::new(io::ErrorKind::TimedOut, "Operation Timed out")); + } + + Ok(()) + } + + /// Abort an asynchronous connection, listen, transmission or receive request. + /// + /// If token is NULL, then all pending tokens issued by EFI_TCP4_PROTOCOL.Connect(), + /// EFI_TCP4_PROTOCOL.Accept(), EFI_TCP4_PROTOCOL.Transmit() or EFI_TCP4_PROTOCOL.Receive() are + /// aborted. + /// + /// # SAFETY + /// + /// Pointer to a valid `EFI_TCP4_COMPLETION_TOKEN` or NULL + unsafe fn cancel(&self, token: *mut tcp4::CompletionToken) -> io::Result<()> { + let protocol = self.protocol.as_ptr(); + + let r = unsafe { ((*protocol).cancel)(protocol, token) }; + if r.is_error() { + return Err(io::Error::from_raw_os_error(r.as_usize())); + } else { + Ok(()) + } + } + unsafe fn create_evt(&self) -> io::Result { self.flag.store(false, Ordering::Relaxed); helpers::OwnedEvent::new( @@ -177,10 +222,19 @@ impl Tcp4 { ) } - fn wait_for_flag(&self) { + fn wait_for_flag(&self, timeout: Option) -> bool { + let start = Instant::now(); + while !self.flag.load(Ordering::Relaxed) { let _ = self.poll(); + if let Some(t) = timeout { + if Instant::now().duration_since(start) >= t { + return false; + } + } } + + true } fn poll(&self) -> io::Result<()> { From 425cd0f571b3888be81ebad295af8e3c903fb244 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 9 Jul 2025 14:55:53 -0500 Subject: [PATCH 05/15] test: Verify frontmatter unpretty behavior --- tests/ui/unpretty/frontmatter.rs | 10 ++++++++++ tests/ui/unpretty/frontmatter.stdout | 7 +++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/unpretty/frontmatter.rs create mode 100644 tests/ui/unpretty/frontmatter.stdout diff --git a/tests/ui/unpretty/frontmatter.rs b/tests/ui/unpretty/frontmatter.rs new file mode 100644 index 0000000000000..1971808e2a866 --- /dev/null +++ b/tests/ui/unpretty/frontmatter.rs @@ -0,0 +1,10 @@ +--- +--- + +//@ compile-flags: -Zunpretty=normal +//@ check-pass + +#![feature(frontmatter)] + +fn main() { +} diff --git a/tests/ui/unpretty/frontmatter.stdout b/tests/ui/unpretty/frontmatter.stdout new file mode 100644 index 0000000000000..9ad6bbbe5774b --- /dev/null +++ b/tests/ui/unpretty/frontmatter.stdout @@ -0,0 +1,7 @@ + +//@ compile-flags: -Zunpretty=normal +//@ check-pass + +#![feature(frontmatter)] + +fn main() {} From 45a1e492b1adfc6f7664d1da736dff147e5c3168 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 9 Jul 2025 16:40:22 -0500 Subject: [PATCH 06/15] feat(lexer): Allow including frontmatter with 'tokenize' --- compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- compiler/rustc_lexer/src/lib.rs | 29 ++++++++++++------- compiler/rustc_lexer/src/tests.rs | 3 +- .../src/undocumented_unsafe_blocks.rs | 4 +-- .../src/utils/format_args_collector.rs | 4 +-- src/tools/clippy/clippy_utils/src/consts.rs | 12 +++----- .../clippy/clippy_utils/src/hir_utils.rs | 4 +-- src/tools/clippy/clippy_utils/src/lib.rs | 6 ++-- src/tools/clippy/clippy_utils/src/source.rs | 7 +++-- .../crates/parser/src/lexed_str.rs | 10 ++++--- .../crates/proc-macro-srv/src/server_impl.rs | 2 +- src/tools/rust-analyzer/crates/tt/src/lib.rs | 2 +- 12 files changed, 47 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index aff98c63bcb41..9d656253f720d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -120,7 +120,7 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec pos += shebang_len; } - for token in rustc_lexer::tokenize(&text[pos..]) { + for token in rustc_lexer::tokenize(&text[pos..], rustc_lexer::FrontmatterAllowed::No) { let token_text = &text[pos..pos + token.len as usize]; match token.kind { rustc_lexer::TokenKind::Whitespace => { diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index e30dbe80248d4..e80196ed5679d 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -273,14 +273,15 @@ pub fn strip_shebang(input: &str) -> Option { if let Some(input_tail) = input.strip_prefix("#!") { // Ok, this is a shebang but if the next non-whitespace token is `[`, // then it may be valid Rust code, so consider it Rust code. - let next_non_whitespace_token = tokenize(input_tail).map(|tok| tok.kind).find(|tok| { - !matches!( - tok, - TokenKind::Whitespace - | TokenKind::LineComment { doc_style: None } - | TokenKind::BlockComment { doc_style: None, .. } - ) - }); + let next_non_whitespace_token = + tokenize(input_tail, FrontmatterAllowed::No).map(|tok| tok.kind).find(|tok| { + !matches!( + tok, + TokenKind::Whitespace + | TokenKind::LineComment { doc_style: None } + | TokenKind::BlockComment { doc_style: None, .. } + ) + }); if next_non_whitespace_token != Some(TokenKind::OpenBracket) { // No other choice than to consider this a shebang. return Some(2 + input_tail.lines().next().unwrap_or_default().len()); @@ -303,8 +304,16 @@ pub fn validate_raw_str(input: &str, prefix_len: u32) -> Result<(), RawStrError> } /// Creates an iterator that produces tokens from the input string. -pub fn tokenize(input: &str) -> impl Iterator { - let mut cursor = Cursor::new(input, FrontmatterAllowed::No); +/// +/// When parsing a full Rust document, +/// first [`strip_shebang`] and then allow frontmatters with [`FrontmatterAllowed::Yes`]. +/// +/// When tokenizing a slice of a document, be sure to disallow frontmatters with [`FrontmatterAllowed::No`] +pub fn tokenize( + input: &str, + frontmatter_allowed: FrontmatterAllowed, +) -> impl Iterator { + let mut cursor = Cursor::new(input, frontmatter_allowed); std::iter::from_fn(move || { let token = cursor.advance_token(); if token.kind != TokenKind::Eof { Some(token) } else { None } diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index fc8d9b9d57bc4..a9fcb4817599f 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -125,7 +125,8 @@ fn test_valid_shebang() { } fn check_lexing(src: &str, expect: Expect) { - let actual: String = tokenize(src).map(|token| format!("{:?}\n", token)).collect(); + let actual: String = + tokenize(src, FrontmatterAllowed::No).map(|token| format!("{:?}\n", token)).collect(); expect.assert_eq(&actual) } diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index 6cc4b589a7207..8906e654c972a 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -9,7 +9,7 @@ use clippy_utils::visitors::{Descend, for_each_expr}; use hir::HirId; use rustc_hir as hir; use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource}; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; use rustc_span::{BytePos, Pos, RelativeBytePos, Span, SyntaxContext}; @@ -746,7 +746,7 @@ fn text_has_safety_comment(src: &str, line_starts: &[RelativeBytePos], start_pos loop { if line.starts_with("/*") { let src = &src[line_start..line_starts.last().unwrap().to_usize()]; - let mut tokens = tokenize(src); + let mut tokens = tokenize(src, FrontmatterAllowed::No); return (src[..tokens.next().unwrap().len as usize] .to_ascii_uppercase() .contains("SAFETY:") diff --git a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs index 8f314ce7a60ce..6629a67f78bd4 100644 --- a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs @@ -3,7 +3,7 @@ use clippy_utils::source::SpanRangeExt; use itertools::Itertools; use rustc_ast::{Crate, Expr, ExprKind, FormatArgs}; use rustc_data_structures::fx::FxHashMap; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::impl_lint_pass; use rustc_span::{Span, hygiene}; @@ -82,7 +82,7 @@ fn has_span_from_proc_macro(cx: &EarlyContext<'_>, args: &FormatArgs) -> bool { .all(|sp| { sp.check_source_text(cx, |src| { // text should be either `, name` or `, name =` - let mut iter = tokenize(src).filter(|t| { + let mut iter = tokenize(src, FrontmatterAllowed::No).filter(|t| { !matches!( t.kind, TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index ba0376e4d4066..25afa12e95d63 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::{ BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp, }; -use rustc_lexer::tokenize; +use rustc_lexer::{FrontmatterAllowed, tokenize}; use rustc_lint::LateContext; use rustc_middle::mir::ConstValue; use rustc_middle::mir::interpret::{Scalar, alloc_range}; @@ -304,9 +304,7 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option>) -> Constan match *lit { LitKind::Str(ref is, _) => Constant::Str(is.to_string()), LitKind::Byte(b) => Constant::Int(u128::from(b)), - LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => { - Constant::Binary(s.as_byte_str().to_vec()) - } + LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(s.as_byte_str().to_vec()), LitKind::Char(c) => Constant::Char(c), LitKind::Int(n, _) => Constant::Int(n.get()), LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { @@ -568,9 +566,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { } else { match &lit.node { LitKind::Str(is, _) => Some(is.is_empty()), - LitKind::ByteStr(s, _) | LitKind::CStr(s, _) => { - Some(s.as_byte_str().is_empty()) - } + LitKind::ByteStr(s, _) | LitKind::CStr(s, _) => Some(s.as_byte_str().is_empty()), _ => None, } } @@ -715,7 +711,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { && let Some(src) = src.as_str() { use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace}; - if !tokenize(src) + if !tokenize(src, FrontmatterAllowed::No) .map(|t| t.kind) .filter(|t| !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)) .eq([OpenBrace]) diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 0ca494f16e31d..6e8dccbccd515 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -12,7 +12,7 @@ use rustc_hir::{ Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr, TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind, }; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::LateContext; use rustc_middle::ty::TypeckResults; use rustc_span::{BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext, sym}; @@ -686,7 +686,7 @@ fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &' // `{}` => `()` ([], None) if block.span.check_source_text(cx, |src| { - tokenize(src) + tokenize(src, FrontmatterAllowed::No) .map(|t| t.kind) .filter(|t| { !matches!( diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index c01f0ffaac9a0..98b4c183b1206 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -106,7 +106,7 @@ use rustc_hir::{ Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, TraitFn, TraitItem, TraitItemKind, TraitRef, TyKind, UnOp, def, }; -use rustc_lexer::{TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_middle::hir::nested_filter; use rustc_middle::hir::place::PlaceBase; @@ -2764,7 +2764,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'tcx>) -> ExprUseCtx /// Tokenizes the input while keeping the text associated with each token. pub fn tokenize_with_text(s: &str) -> impl Iterator { let mut pos = 0; - tokenize(s).map(move |t| { + tokenize(s, FrontmatterAllowed::No).map(move |t| { let end = pos + t.len; let range = pos as usize..end as usize; let inner = InnerSpan::new(range.start, range.end); @@ -2779,7 +2779,7 @@ pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool { let Ok(snippet) = sm.span_to_snippet(span) else { return false; }; - return tokenize(&snippet).any(|token| { + return tokenize(&snippet, FrontmatterAllowed::No).any(|token| { matches!( token.kind, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. } diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs index 7f2bf99daff20..7d21336be1cd8 100644 --- a/src/tools/clippy/clippy_utils/src/source.rs +++ b/src/tools/clippy/clippy_utils/src/source.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use rustc_ast::{LitKind, StrStyle}; use rustc_errors::Applicability; use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource}; -use rustc_lexer::{LiteralKind, TokenKind, tokenize}; +use rustc_lexer::{FrontmatterAllowed, LiteralKind, TokenKind, tokenize}; use rustc_lint::{EarlyContext, LateContext}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; @@ -277,7 +277,7 @@ fn map_range( } fn ends_with_line_comment_or_broken(text: &str) -> bool { - let Some(last) = tokenize(text).last() else { + let Some(last) = tokenize(text, FrontmatterAllowed::No).last() else { return false; }; match last.kind { @@ -310,7 +310,8 @@ fn with_leading_whitespace_inner(lines: &[RelativeBytePos], src: &str, range: Ra && ends_with_line_comment_or_broken(&start[prev_start..]) && let next_line = lines.partition_point(|&pos| pos.to_usize() < range.end) && let next_start = lines.get(next_line).map_or(src.len(), |&x| x.to_usize()) - && tokenize(src.get(range.end..next_start)?).any(|t| !matches!(t.kind, TokenKind::Whitespace)) + && tokenize(src.get(range.end..next_start)?, FrontmatterAllowed::No) + .any(|t| !matches!(t.kind, TokenKind::Whitespace)) { Some(range.start) } else { diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs index e6c92dec68107..bff9acd78fa0f 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -11,8 +11,8 @@ use std::ops; use rustc_literal_escaper::{ - EscapeError, Mode, unescape_byte, unescape_byte_str, unescape_c_str, unescape_char, - unescape_str, + unescape_byte, unescape_byte_str, unescape_c_str, unescape_char, unescape_str, EscapeError, + Mode, }; use crate::{ @@ -44,7 +44,9 @@ impl<'a> LexedStr<'a> { // Re-create the tokenizer from scratch every token because `GuardedStrPrefix` is one token in the lexer // but we want to split it to two in edition <2024. - while let Some(token) = rustc_lexer::tokenize(&text[conv.offset..]).next() { + while let Some(token) = + rustc_lexer::tokenize(&text[conv.offset..], rustc_lexer::FrontmatterAllowed::No).next() + { let token_text = &text[conv.offset..][..token.len as usize]; conv.extend_token(&token.kind, token_text); @@ -58,7 +60,7 @@ impl<'a> LexedStr<'a> { return None; } - let token = rustc_lexer::tokenize(text).next()?; + let token = rustc_lexer::tokenize(text, rustc_lexer::FrontmatterAllowed::No).next()?; if token.len as usize != text.len() { return None; } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs index dd576f23ae9fd..662f6257642f0 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs @@ -121,7 +121,7 @@ pub(super) fn literal_from_str( use proc_macro::bridge::LitKind; use rustc_lexer::{LiteralKind, Token, TokenKind}; - let mut tokens = rustc_lexer::tokenize(s); + let mut tokens = rustc_lexer::tokenize(s, rustc_lexer::FrontmatterAllowed::No); let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 }); let lit = if minus_or_lit.kind == TokenKind::Minus { diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 14574a6456bda..44123385c8cc3 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -579,7 +579,7 @@ where { use rustc_lexer::LiteralKind; - let token = rustc_lexer::tokenize(text).next_tuple(); + let token = rustc_lexer::tokenize(text, rustc_lexer::FrontmatterAllowed::No).next_tuple(); let Some((rustc_lexer::Token { kind: rustc_lexer::TokenKind::Literal { kind, suffix_start }, .. From e0f76871eddd0f1345eba7d09e5ab4812f8aa91d Mon Sep 17 00:00:00 2001 From: "LevitatingBusinessMan (Rein Fernhout)" Date: Thu, 12 Jun 2025 02:34:15 +0200 Subject: [PATCH 07/15] rust: library: Add setsid method to CommandExt trait Add a setsid method to the CommandExt trait so that callers can create a process in a new session and process group whilst still using the POSIX spawn fast path. Co-Authored-By: Harvey Hunt --- library/std/src/os/unix/process.rs | 8 +++ library/std/src/sys/process/unix/common.rs | 9 +++ .../std/src/sys/process/unix/common/tests.rs | 58 +++++++++++++++++++ library/std/src/sys/process/unix/unix.rs | 14 +++++ 4 files changed, 89 insertions(+) diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 57ce3c5a4bf4a..baa922f75bccd 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -210,6 +210,9 @@ pub trait CommandExt: Sealed { /// intentional difference from the underlying `chroot` system call.) #[unstable(feature = "process_chroot", issue = "141298")] fn chroot>(&mut self, dir: P) -> &mut process::Command; + + #[unstable(feature = "process_setsid", issue = "105376")] + fn setsid(&mut self, setsid: bool) -> &mut process::Command; } #[stable(feature = "rust1", since = "1.0.0")] @@ -260,6 +263,11 @@ impl CommandExt for process::Command { self.as_inner_mut().chroot(dir.as_ref()); self } + + fn setsid(&mut self, setsid: bool) -> &mut process::Command { + self.as_inner_mut().setsid(setsid); + self + } } /// Unix-specific extensions to [`process::ExitStatus`] and diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs index b6777b76668d5..6219be60caf2c 100644 --- a/library/std/src/sys/process/unix/common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -98,6 +98,7 @@ pub struct Command { #[cfg(target_os = "linux")] create_pidfd: bool, pgroup: Option, + setsid: bool, } // passed back to std::process with the pipes connected to the child, if any @@ -185,6 +186,7 @@ impl Command { #[cfg(target_os = "linux")] create_pidfd: false, pgroup: None, + setsid: false, } } @@ -220,6 +222,9 @@ impl Command { self.cwd(&OsStr::new("/")); } } + pub fn setsid(&mut self, setsid: bool) { + self.setsid = setsid; + } #[cfg(target_os = "linux")] pub fn create_pidfd(&mut self, val: bool) { @@ -298,6 +303,10 @@ impl Command { pub fn get_chroot(&self) -> Option<&CStr> { self.chroot.as_deref() } + #[allow(dead_code)] + pub fn get_setsid(&self) -> bool { + self.setsid + } pub fn get_closures(&mut self) -> &mut Vec io::Result<()> + Send + Sync>> { &mut self.closures diff --git a/library/std/src/sys/process/unix/common/tests.rs b/library/std/src/sys/process/unix/common/tests.rs index e5c8dd6e341e1..5f71bf051f8a8 100644 --- a/library/std/src/sys/process/unix/common/tests.rs +++ b/library/std/src/sys/process/unix/common/tests.rs @@ -134,6 +134,64 @@ fn test_process_group_no_posix_spawn() { } } +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_setsid_posix_spawn() { + // Spawn a cat subprocess that's just going to hang since there is no I/O. + let mut cmd = Command::new(OsStr::new("cat")); + cmd.setsid(true); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + unsafe { + // Setsid will create a new session and process group, so check that + // we can kill the process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_setsid_no_posix_spawn() { + let mut cmd = Command::new(OsStr::new("cat")); + cmd.setsid(true); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + + unsafe { + // Same as above, create hang-y cat. This time, force using the non-posix_spawn path. + cmd.pre_exec(Box::new(|| Ok(()))); // pre_exec forces fork + exec rather than posix spawn. + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + // Setsid will create a new session and process group, so check that + // we can kill the process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + #[test] fn test_program_kind() { let vectors = &[ diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 4f595ac9a1c5f..9162573ba09b3 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -340,6 +340,10 @@ impl Command { cvt(libc::setpgid(0, pgroup))?; } + if self.get_setsid() { + cvt(libc::setsid())?; + } + // emscripten has no signal support. #[cfg(not(target_os = "emscripten"))] { @@ -741,6 +745,16 @@ impl Command { flags |= libc::POSIX_SPAWN_SETSIGDEF; } + if self.get_setsid() { + cfg_if::cfg_if! { + if #[cfg(all(target_os = "linux", target_env = "gnu"))] { + flags |= libc::POSIX_SPAWN_SETSID; + } else { + return Ok(None); + } + } + } + cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; // Make sure we synchronize access to the global `environ` resource From 58d7c2d5a760c1adfa4c3984eeb12787f5ad5b1d Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 9 Jul 2025 22:30:15 -0700 Subject: [PATCH 08/15] Make UB transmutes really UB in LLVM Ralf suggested in that UB transmutes shouldn't be trapping, which happened for the one path that PR was changing, but there's another path as well, so this PR changes that other path to match. --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 12 +++++------ tests/codegen/intrinsics/transmute.rs | 22 ++++++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index cbbb0196890fd..1e3b76e5f933d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -236,14 +236,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { || operand.layout.is_uninhabited() || cast.is_uninhabited() { - if !operand.layout.is_uninhabited() { - // Since this is known statically and the input could have existed - // without already having hit UB, might as well trap for it. - bx.abort(); - } + // We can't use unreachable because that's a terminator, and we + // need something that can be in the middle of a basic block. + bx.assume(bx.cx().const_bool(false)); - // Because this transmute is UB, return something easy to generate, - // since it's fine that later uses of the value are probably UB. + // We still need to return a value of the appropriate type, but + // it's already UB so do the easiest thing available. return OperandValue::poison(bx, cast); } diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index e375724bc1bbd..36d6a2f722f23 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -58,9 +58,9 @@ pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] { - // CHECK-NOT: trap - // CHECK: call void @llvm.trap - // CHECK-NOT: trap + // CHECK-NOT: call + // CHECK: call void @llvm.assume(i1 false) + // CHECK-NOT: call mir! { { RET = CastTransmute(x); @@ -88,9 +88,9 @@ pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_uninhabited(x: u16) { - // CHECK-NOT: trap - // CHECK: call void @llvm.trap - // CHECK-NOT: trap + // CHECK-NOT: call + // CHECK: call void @llvm.assume(i1 false) + // CHECK-NOT: call mir! { let temp: BigNever; { @@ -104,6 +104,9 @@ pub unsafe fn check_to_uninhabited(x: u16) { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 { + // CHECK-NOT: call + // CHECK: call void @llvm.assume(i1 false) + // CHECK-NOT: call // CHECK: ret i16 poison mir! { { @@ -401,9 +404,9 @@ pub unsafe fn check_issue_109992(x: ()) -> [(); 1] { pub unsafe fn check_unit_to_never(x: ()) { // This uses custom MIR to avoid MIR optimizations having removed ZST ops. - // CHECK-NOT: trap - // CHECK: call void @llvm.trap - // CHECK-NOT: trap + // CHECK-NOT: call + // CHECK: call void @llvm.assume(i1 false) + // CHECK-NOT: call mir! { let temp: ZstNever; { @@ -420,6 +423,7 @@ pub unsafe fn check_unit_from_never(x: ZstNever) -> () { // This uses custom MIR to avoid MIR optimizations having removed ZST ops. // CHECK: start + // CHECK-NEXT: call void @llvm.assume(i1 false) // CHECK-NEXT: ret void mir! { { From 3ad95cccf9b3af7e527869a1eb130217971b7a57 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 1 Jul 2025 21:46:28 +0500 Subject: [PATCH 09/15] cleaned up some tests --- ...arameter => auto-traits-type-parameter.rs} | 17 ++++----- .../ui/consts/const-eval-array-len-in-impl.rs | 4 ++- .../const-eval-array-len-in-impl.stderr | 2 +- .../let-binding-tuple-destructuring.rs | 2 ++ .../any-lifetime-escape-higher-rank.rs | 12 +++++-- .../limits/type-length-limit-enforcement.rs | 16 +++++---- .../type-length-limit-enforcement.stderr | 4 +-- .../macro-fragment-ident-underscore-error.rs | 7 ++-- ...cro-fragment-ident-underscore-error.stderr | 6 ++-- ...ruct-type-and-function-name-coexistence.rs | 13 +++++-- .../integer-literal-method-call-underscore.rs | 6 +++- .../ptr_ops/ptr-write-bool-representation.rs | 7 ++++ tests/ui/ptr_ops/raw-pointer-type-basic.rs | 15 ++++++-- .../try-operator-expansion-hygiene.rs | 16 ++++----- .../try-operator-various-contexts.rs | 35 ++++++++++--------- .../type-inference-none-in-generic-ref.rs | 6 ++-- .../type-inference-none-in-generic-ref.stderr | 2 +- .../type-inference-unconstrained-none.rs | 2 +- .../type-inference-unconstrained-none.stderr | 2 +- .../auxiliary/typeid-consistency-aux1.rs} | 0 .../auxiliary/typeid-consistency-aux2.rs} | 0 tests/ui/type/type-name-basic.rs | 7 ++-- ...comprehensive.rs => typeid-consistency.rs} | 27 +++++++------- .../basic-underscore-lifetime-elision.rs | 8 ++--- 24 files changed, 131 insertions(+), 85 deletions(-) rename tests/ui/auto-traits/{auto-traits-type-parameter => auto-traits-type-parameter.rs} (59%) rename tests/ui/{auxiliary/typeid-intrinsic-aux1.rs => type/auxiliary/typeid-consistency-aux1.rs} (100%) rename tests/ui/{auxiliary/typeid-intrinsic-aux2.rs => type/auxiliary/typeid-consistency-aux2.rs} (100%) rename tests/ui/type/{typeid-consistency-comprehensive.rs => typeid-consistency.rs} (85%) diff --git a/tests/ui/auto-traits/auto-traits-type-parameter b/tests/ui/auto-traits/auto-traits-type-parameter.rs similarity index 59% rename from tests/ui/auto-traits/auto-traits-type-parameter rename to tests/ui/auto-traits/auto-traits-type-parameter.rs index 83d81c0d833f1..0c448f5899672 100644 --- a/tests/ui/auto-traits/auto-traits-type-parameter +++ b/tests/ui/auto-traits/auto-traits-type-parameter.rs @@ -1,24 +1,25 @@ +//! Checks how type parameters interact with auto-traits like `Send` and `Sync` with implicit +//! bounds + //@ run-pass #![allow(non_camel_case_types)] #![allow(dead_code)] -fn p_foo(_pinned: T) { } -fn s_foo(_shared: T) { } -fn u_foo(_unique: T) { } +fn p_foo(_pinned: T) {} +fn s_foo(_shared: T) {} +fn u_foo(_unique: T) {} struct r { - i: isize, + i: isize, } impl Drop for r { fn drop(&mut self) {} } -fn r(i:isize) -> r { - r { - i: i - } +fn r(i: isize) -> r { + r { i } } pub fn main() { diff --git a/tests/ui/consts/const-eval-array-len-in-impl.rs b/tests/ui/consts/const-eval-array-len-in-impl.rs index 6c545913dd9dc..0373274770de5 100644 --- a/tests/ui/consts/const-eval-array-len-in-impl.rs +++ b/tests/ui/consts/const-eval-array-len-in-impl.rs @@ -1,4 +1,6 @@ -// https://github.com/rust-lang/rust/issues/49208 +//! This checks that compiler correctly evaluate constant array lengths within trait `impl` headers. +//! +//! Regression test for . trait Foo { fn foo(); diff --git a/tests/ui/consts/const-eval-array-len-in-impl.stderr b/tests/ui/consts/const-eval-array-len-in-impl.stderr index 43cc377006e0e..faff7aa3ff7a7 100644 --- a/tests/ui/consts/const-eval-array-len-in-impl.stderr +++ b/tests/ui/consts/const-eval-array-len-in-impl.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied - --> $DIR/unevaluated_fixed_size_array_len.rs:12:6 + --> $DIR/const-eval-array-len-in-impl.rs:14:6 | LL | <[(); 0] as Foo>::foo() | ^^^^^^^ the trait `Foo` is not implemented for `[(); 0]` diff --git a/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs b/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs index 3d0e79632bb33..f62fae8621934 100644 --- a/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs +++ b/tests/ui/destructuring-assignment/let-binding-tuple-destructuring.rs @@ -1,3 +1,5 @@ +//! Checks basic multiple variable declaration using tuple destructuring in a `let` binding. + //@ run-pass pub fn main() { diff --git a/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs b/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs index 7b0c7b5394084..f9f38ee532d9d 100644 --- a/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs +++ b/tests/ui/lifetimes/any-lifetime-escape-higher-rank.rs @@ -1,11 +1,15 @@ +//! Checks that `std::any::Any` cannot be used to circumvent lifetime rules +//! with higher-rank types. + //@ run-pass -// Test that we can't ignore lifetimes by going through Any. use std::any::Any; struct Foo<'a>(&'a str); -fn good(s: &String) -> Foo<'_> { Foo(s) } +fn good(s: &String) -> Foo<'_> { + Foo(s) +} fn bad1(s: String) -> Option<&'static str> { let a: Box = Box::new(good as fn(&String) -> Foo); @@ -17,7 +21,9 @@ trait AsStr<'a, 'b> { } impl<'a> AsStr<'a, 'a> for String { - fn get(&'a self) -> &'a str { self } + fn get(&'a self) -> &'a str { + self + } } fn bad2(s: String) -> Option<&'static str> { diff --git a/tests/ui/limits/type-length-limit-enforcement.rs b/tests/ui/limits/type-length-limit-enforcement.rs index 87f5ffd76d7a6..3b34d6eb5c855 100644 --- a/tests/ui/limits/type-length-limit-enforcement.rs +++ b/tests/ui/limits/type-length-limit-enforcement.rs @@ -1,17 +1,19 @@ -//@ build-fail +//~ ERROR reached the type-length limit + +//! Checks the enforcement of the type-length limit +//! and its configurability via `#![type_length_limit]`. + //@ compile-flags: -Copt-level=0 -Zenforce-type-length-limit -//~^^ ERROR reached the type-length limit -// Test that the type length limit can be changed. -// The exact type depends on optimizations, so disable them. +//@ build-fail #![allow(dead_code)] -#![type_length_limit="8"] +#![type_length_limit = "8"] macro_rules! link { ($id:ident, $t:ty) => { pub type $id = ($t, $t, $t); - } + }; } link! { A1, B1 } @@ -26,7 +28,7 @@ link! { D, E } link! { E, F } link! { F, G, Option> } -pub struct G(std::marker::PhantomData::<(T, K)>); +pub struct G(std::marker::PhantomData<(T, K)>); fn main() { drop::>(None); diff --git a/tests/ui/limits/type-length-limit-enforcement.stderr b/tests/ui/limits/type-length-limit-enforcement.stderr index 198d133c08c88..516230ae832dc 100644 --- a/tests/ui/limits/type-length-limit-enforcement.stderr +++ b/tests/ui/limits/type-length-limit-enforcement.stderr @@ -1,11 +1,11 @@ error: reached the type-length limit while instantiating `std::mem::drop::>` - --> $DIR/type_length_limit.rs:32:5 + --> $DIR/type-length-limit-enforcement.rs:34:5 | LL | drop::>(None); | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate - = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/type-length-limit-enforcement.long-type.txt' error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` | diff --git a/tests/ui/macros/macro-fragment-ident-underscore-error.rs b/tests/ui/macros/macro-fragment-ident-underscore-error.rs index 77ec70d43d54e..882dd167adc7d 100644 --- a/tests/ui/macros/macro-fragment-ident-underscore-error.rs +++ b/tests/ui/macros/macro-fragment-ident-underscore-error.rs @@ -1,7 +1,10 @@ +//! Verifies that the reserved underscore `_` cannot be used as an `ident` fragment specifier +//! within a macro pattern, as it leads to a compilation error. + macro_rules! identity { - ($i: ident) => ( + ($i: ident) => { $i - ) + }; } fn main() { diff --git a/tests/ui/macros/macro-fragment-ident-underscore-error.stderr b/tests/ui/macros/macro-fragment-ident-underscore-error.stderr index 0c3f980cf6c71..929e4624e4b2e 100644 --- a/tests/ui/macros/macro-fragment-ident-underscore-error.stderr +++ b/tests/ui/macros/macro-fragment-ident-underscore-error.stderr @@ -1,5 +1,5 @@ error: no rules expected reserved identifier `_` - --> $DIR/underscore-ident-matcher.rs:8:19 + --> $DIR/macro-fragment-ident-underscore-error.rs:11:19 | LL | macro_rules! identity { | --------------------- when calling this macro @@ -8,9 +8,9 @@ LL | let identity!(_) = 10; | ^ no rules expected this token in macro call | note: while trying to match meta-variable `$i:ident` - --> $DIR/underscore-ident-matcher.rs:2:6 + --> $DIR/macro-fragment-ident-underscore-error.rs:5:6 | -LL | ($i: ident) => ( +LL | ($i: ident) => { | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/namespace/struct-type-and-function-name-coexistence.rs b/tests/ui/namespace/struct-type-and-function-name-coexistence.rs index 31dc684a214a7..8d5ab3781b5c3 100644 --- a/tests/ui/namespace/struct-type-and-function-name-coexistence.rs +++ b/tests/ui/namespace/struct-type-and-function-name-coexistence.rs @@ -1,7 +1,14 @@ //@ run-pass -struct A { a: isize } +struct A { + a: isize, +} -fn a(a: A) -> isize { return a.a; } +fn a(a: A) -> isize { + return a.a; +} -pub fn main() { let x: A = A {a: 1}; assert_eq!(a(x), 1); } +pub fn main() { + let x: A = A { a: 1 }; + assert_eq!(a(x), 1); +} diff --git a/tests/ui/parser/integer-literal-method-call-underscore.rs b/tests/ui/parser/integer-literal-method-call-underscore.rs index d9eb21894e8ca..9e4abf28cbaa6 100644 --- a/tests/ui/parser/integer-literal-method-call-underscore.rs +++ b/tests/ui/parser/integer-literal-method-call-underscore.rs @@ -1,6 +1,10 @@ +//! Checks that methods with names starting with an underscore (`_`) can be +//! successfully called directly on integer literals, confirming the correct +//! parsing of such expressions where the underscore is part of the method identifier. + //@ run-pass -trait Tr : Sized { +trait Tr: Sized { fn _method_on_numbers(self) {} } diff --git a/tests/ui/ptr_ops/ptr-write-bool-representation.rs b/tests/ui/ptr_ops/ptr-write-bool-representation.rs index 4eb25329223cf..3dfc3e51ab298 100644 --- a/tests/ui/ptr_ops/ptr-write-bool-representation.rs +++ b/tests/ui/ptr_ops/ptr-write-bool-representation.rs @@ -1,3 +1,10 @@ +//! Validates the correct behavior of writing a `bool` value using `std::ptr::write`. +//! +//! This test addresses historical concerns regarding the internal representation of `bool` +//! (e.g., as `i1` in LLVM versus its byte-aligned memory layout) and checks that +//! `ptr::write` correctly handles this type without issues, confirming its memory +//! behavior is as expected. + //@ run-pass use std::ptr; diff --git a/tests/ui/ptr_ops/raw-pointer-type-basic.rs b/tests/ui/ptr_ops/raw-pointer-type-basic.rs index 5c8ed344ab33a..349e8e67909fd 100644 --- a/tests/ui/ptr_ops/raw-pointer-type-basic.rs +++ b/tests/ui/ptr_ops/raw-pointer-type-basic.rs @@ -1,9 +1,18 @@ +//! Checks the basic usage of raw pointers (`*const isize`) as function argument and return types. + //@ run-pass #![allow(dead_code)] -fn f(a: *const isize) -> *const isize { return a; } +fn f(a: *const isize) -> *const isize { + return a; +} -fn g(a: *const isize) -> *const isize { let b = f(a); return b; } +fn g(a: *const isize) -> *const isize { + let b = f(a); + return b; +} -pub fn main() { return; } +pub fn main() { + return; +} diff --git a/tests/ui/try-trait/try-operator-expansion-hygiene.rs b/tests/ui/try-trait/try-operator-expansion-hygiene.rs index 20538e094c6d6..b6f4e533d8d4e 100644 --- a/tests/ui/try-trait/try-operator-expansion-hygiene.rs +++ b/tests/ui/try-trait/try-operator-expansion-hygiene.rs @@ -1,16 +1,14 @@ +//! This test verifies that the `?` operator expansion is hygienic, +//! i.e., it's not affected by other `val` and `err` bindings that may be in scope. +//! +//! Note: Prior to the Try trait stabilization, `expr?` expanded to a match +//! with `val` and `err` bindings. The current implementation uses Try::branch() +//! but this test remains relevant for hygiene verification. + //@ run-pass #![allow(non_upper_case_globals)] #![allow(dead_code)] -// `expr?` expands to: -// -// match expr { -// Ok(val) => val, -// Err(err) => return Err(From::from(err)), -// } -// -// This test verifies that the expansion is hygienic, i.e., it's not affected by other `val` and -// `err` bindings that may be in scope. use std::num::ParseIntError; diff --git a/tests/ui/try-trait/try-operator-various-contexts.rs b/tests/ui/try-trait/try-operator-various-contexts.rs index b99782045575f..41c3679c96f6a 100644 --- a/tests/ui/try-trait/try-operator-various-contexts.rs +++ b/tests/ui/try-trait/try-operator-various-contexts.rs @@ -1,9 +1,11 @@ +//! Checks the functionality of the `?` operator in various syntactic contexts. + //@ run-pass #![allow(dead_code)] use std::fs::File; -use std::io::{Read, self}; +use std::io::{self, Read}; use std::num::ParseIntError; use std::str::FromStr; @@ -35,7 +37,9 @@ fn on_path() -> Result { fn on_macro() -> Result { macro_rules! id { - ($e:expr) => { $e } + ($e:expr) => { + $e + }; } Ok(id!("7".parse::())?) @@ -50,11 +54,14 @@ fn on_parens() -> Result { fn on_block() -> Result { let x = "9".parse::(); - Ok({x}?) + Ok({ x }?) } fn on_field() -> Result { - struct Pair { a: A, b: B } + struct Pair { + a: A, + b: B, + } let x = Pair { a: "10".parse::(), b: 0 }; @@ -89,7 +96,9 @@ fn on_index() -> Result { } fn on_args() -> Result { - fn sub(x: i32, y: i32) -> i32 { x - y } + fn sub(x: i32, y: i32) -> i32 { + x - y + } let x = "20".parse(); let y = "21".parse(); @@ -98,19 +107,11 @@ fn on_args() -> Result { } fn on_if() -> Result { - Ok(if true { - "22".parse::() - } else { - "23".parse::() - }?) + Ok(if true { "22".parse::() } else { "23".parse::() }?) } fn on_if_let() -> Result { - Ok(if let Ok(..) = "24".parse::() { - "25".parse::() - } else { - "26".parse::() - }?) + Ok(if let Ok(..) = "24".parse::() { "25".parse::() } else { "26".parse::() }?) } fn on_match() -> Result { @@ -121,7 +122,9 @@ fn on_match() -> Result { } fn tight_binding() -> Result { - fn ok(x: T) -> Result { Ok(x) } + fn ok(x: T) -> Result { + Ok(x) + } let x = ok(true); Ok(!x?) diff --git a/tests/ui/type-inference/type-inference-none-in-generic-ref.rs b/tests/ui/type-inference/type-inference-none-in-generic-ref.rs index 473ca954b232d..9c1b7c19e3da3 100644 --- a/tests/ui/type-inference/type-inference-none-in-generic-ref.rs +++ b/tests/ui/type-inference/type-inference-none-in-generic-ref.rs @@ -1,5 +1,7 @@ -struct S<'a, T:'a> { - o: &'a Option +//! Checks that unconstrained `None` is rejected through references and generics + +struct S<'a, T: 'a> { + o: &'a Option, } fn main() { diff --git a/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr b/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr index 72fd0202f4e53..d671c189b3730 100644 --- a/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr +++ b/tests/ui/type-inference/type-inference-none-in-generic-ref.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/unconstrained-ref.rs:6:5 + --> $DIR/type-inference-none-in-generic-ref.rs:8:5 | LL | S { o: &None }; | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `S` diff --git a/tests/ui/type-inference/type-inference-unconstrained-none.rs b/tests/ui/type-inference/type-inference-unconstrained-none.rs index e180b3163d412..38a506763c761 100644 --- a/tests/ui/type-inference/type-inference-unconstrained-none.rs +++ b/tests/ui/type-inference/type-inference-unconstrained-none.rs @@ -1,4 +1,4 @@ -// Issue #5062 +//! Regression test for . fn main() { None; //~ ERROR type annotations needed [E0282] diff --git a/tests/ui/type-inference/type-inference-unconstrained-none.stderr b/tests/ui/type-inference/type-inference-unconstrained-none.stderr index 4af6f412e5b22..80572b845e84f 100644 --- a/tests/ui/type-inference/type-inference-unconstrained-none.stderr +++ b/tests/ui/type-inference/type-inference-unconstrained-none.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/unconstrained-none.rs:4:5 + --> $DIR/type-inference-unconstrained-none.rs:4:5 | LL | None; | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` diff --git a/tests/ui/auxiliary/typeid-intrinsic-aux1.rs b/tests/ui/type/auxiliary/typeid-consistency-aux1.rs similarity index 100% rename from tests/ui/auxiliary/typeid-intrinsic-aux1.rs rename to tests/ui/type/auxiliary/typeid-consistency-aux1.rs diff --git a/tests/ui/auxiliary/typeid-intrinsic-aux2.rs b/tests/ui/type/auxiliary/typeid-consistency-aux2.rs similarity index 100% rename from tests/ui/auxiliary/typeid-intrinsic-aux2.rs rename to tests/ui/type/auxiliary/typeid-consistency-aux2.rs diff --git a/tests/ui/type/type-name-basic.rs b/tests/ui/type/type-name-basic.rs index 068a42606c2f3..9381cb8257811 100644 --- a/tests/ui/type/type-name-basic.rs +++ b/tests/ui/type/type-name-basic.rs @@ -1,3 +1,6 @@ +//! Checks the basic functionality of `std::any::type_name` for primitive types +//! and simple generic structs. + //@ run-pass #![allow(dead_code)] @@ -5,10 +8,10 @@ use std::any::type_name; struct Foo { - x: T + x: T, } pub fn main() { assert_eq!(type_name::(), "isize"); - assert_eq!(type_name::>(), "tydesc_name::Foo"); + assert_eq!(type_name::>(), "type_name_basic::Foo"); } diff --git a/tests/ui/type/typeid-consistency-comprehensive.rs b/tests/ui/type/typeid-consistency.rs similarity index 85% rename from tests/ui/type/typeid-consistency-comprehensive.rs rename to tests/ui/type/typeid-consistency.rs index 7c4fb3f95a94e..67ee1b6d839ab 100644 --- a/tests/ui/type/typeid-consistency-comprehensive.rs +++ b/tests/ui/type/typeid-consistency.rs @@ -1,16 +1,18 @@ +//! Checks the correctness and consistency of `std::any::TypeId::of`. + //@ run-pass #![allow(deprecated)] -//@ aux-build:typeid-intrinsic-aux1.rs -//@ aux-build:typeid-intrinsic-aux2.rs - #![feature(core_intrinsics)] -extern crate typeid_intrinsic_aux1 as other1; -extern crate typeid_intrinsic_aux2 as other2; +//@ aux-build:typeid-consistency-aux1.rs +//@ aux-build:typeid-consistency-aux2.rs + +extern crate typeid_consistency_aux1 as other1; +extern crate typeid_consistency_aux2 as other2; -use std::hash::{SipHasher, Hasher, Hash}; use std::any::TypeId; +use std::hash::{Hash, Hasher, SipHasher}; struct A; struct Test; @@ -34,7 +36,7 @@ pub fn main() { assert_eq!(TypeId::of::(), other2::id_F()); assert_eq!(TypeId::of::(), other2::id_G()); assert_eq!(TypeId::of::(), other2::id_H()); - assert_eq!(TypeId::of::(), other2::id_I()); + assert_eq!(TypeId::of::(), other2::id_I()); assert_eq!(other1::id_F(), other2::id_F()); assert_eq!(other1::id_G(), other2::id_G()); @@ -49,10 +51,8 @@ pub fn main() { assert_eq!(other2::foo::(), other1::foo::()); // sanity test of TypeId - let (a, b, c) = (TypeId::of::(), TypeId::of::<&'static str>(), - TypeId::of::()); - let (d, e, f) = (TypeId::of::(), TypeId::of::<&'static str>(), - TypeId::of::()); + let (a, b, c) = (TypeId::of::(), TypeId::of::<&'static str>(), TypeId::of::()); + let (d, e, f) = (TypeId::of::(), TypeId::of::<&'static str>(), TypeId::of::()); assert!(a != b); assert!(a != c); @@ -82,10 +82,7 @@ pub fn main() { assert_ne!(TypeId::of::(), TypeId::of::()); // Check fn pointer against collisions - assert_ne!( - TypeId::of:: A) -> A>(), - TypeId::of:: A, A) -> A>() - ); + assert_ne!(TypeId::of:: A) -> A>(), TypeId::of:: A, A) -> A>()); assert_ne!( TypeId::of:: fn(&'a i32) -> &'a i32>(), TypeId::of:: fn(&'a i32) -> &'static i32>() diff --git a/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs b/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs index a372851f9cfff..a2e3c8e26d4be 100644 --- a/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs +++ b/tests/ui/underscore-lifetime/basic-underscore-lifetime-elision.rs @@ -1,6 +1,9 @@ +//! Checks the correct usage and behavior of the anonymous lifetime `'_` (underscore lifetime) + //@ run-pass #![allow(dead_code, mismatched_lifetime_syntaxes)] + struct Foo<'a>(&'a u8); fn foo(x: &u8) -> Foo<'_> { @@ -31,8 +34,5 @@ fn main() { let _ = foo2(x); let _ = foo3(x); foo4(Foo(x)); - let _ = foo5(Foo2 { - a: x, - b: &6, - }); + let _ = foo5(Foo2 { a: x, b: &6 }); } From 259512e3b6a920b1e1eb6034fbc738e7b9815337 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 1 Jul 2025 23:37:49 +0500 Subject: [PATCH 10/15] cleaned up some tests --- tests/ui/allocator/weak-uninhabited-type.rs | 8 +++- .../underscore-prefixed-function-argument.rs | 12 +++-- .../ownership-struct-update-moved-error.rs | 16 ++++--- ...ownership-struct-update-moved-error.stderr | 12 ++--- tests/ui/closures/no-capture-closure-call.rs | 2 + ...-drop-unused-value-statement-regression.rs | 14 +++--- tests/ui/hashmap/hashset-enum-variant.rs | 13 ++--- tests/ui/io-checks/write-macro-error.rs | 13 +++-- .../lang-item-unknown-definition-error.rs | 4 +- .../lang-item-unknown-definition-error.stderr | 2 +- .../modules/module-qualified-paths-basic.rs | 15 ++++-- tests/ui/modules/module-use-nested-groups.rs | 2 + .../primitive-type-module-deprecated-paths.rs | 7 +-- .../use-keyword-reexport-type-alias.rs | 10 ++-- .../unary-negation-unsigned-integer-error.rs | 2 + ...ary-negation-unsigned-integer-error.stderr | 6 +-- .../panics/unwind-force-no-unwind-tables.rs | 15 ++++-- tests/ui/process/process-spawn-failure.rs | 47 ++++++++++++------- .../process/windows-exit-code-still-active.rs | 24 +++++----- .../diverging-expressions-unreachable-code.rs | 20 ++++---- .../unreachable-code-diverging-expressions.rs | 10 ++-- .../traits/virtual-call-parameter-handling.rs | 6 ++- tests/ui/type/unit-type-basic-usages.rs | 18 ++++--- tests/ui/type/usize-no-generic-arguments.rs | 2 + .../ui/type/usize-no-generic-arguments.stderr | 2 +- .../unsafe/maybe-uninit-zero-sized-types.rs | 7 ++- 26 files changed, 177 insertions(+), 112 deletions(-) diff --git a/tests/ui/allocator/weak-uninhabited-type.rs b/tests/ui/allocator/weak-uninhabited-type.rs index ce7d5786b41bb..74258eedc6ac3 100644 --- a/tests/ui/allocator/weak-uninhabited-type.rs +++ b/tests/ui/allocator/weak-uninhabited-type.rs @@ -1,7 +1,13 @@ +//! Checks that `Weak` pointers can be created with an empty enum type parameter. +//! And generic `Weak` handles zero-variant enums without error. +//! +//! Regression test for + //@ run-pass +enum Void {} + fn main() { - enum Void {} let _ = std::rc::Weak::::new(); let _ = std::sync::Weak::::new(); } diff --git a/tests/ui/binding/underscore-prefixed-function-argument.rs b/tests/ui/binding/underscore-prefixed-function-argument.rs index 2014e0d23d849..e5b2ec1b5f005 100644 --- a/tests/ui/binding/underscore-prefixed-function-argument.rs +++ b/tests/ui/binding/underscore-prefixed-function-argument.rs @@ -1,11 +1,13 @@ -//@ run-pass +//! Test that argument names starting with `_` are usable. -fn good(_a: &isize) { -} +//@ run-pass -// unnamed argument &isize is now parse x: &isize +fn good(_a: &isize) {} -fn called(_f: F) where F: FnOnce(&isize) { +fn called(_f: F) +where + F: FnOnce(&isize), +{ } pub fn main() { diff --git a/tests/ui/borrowck/ownership-struct-update-moved-error.rs b/tests/ui/borrowck/ownership-struct-update-moved-error.rs index ee1a77eb9a48a..62fc1f42969f4 100644 --- a/tests/ui/borrowck/ownership-struct-update-moved-error.rs +++ b/tests/ui/borrowck/ownership-struct-update-moved-error.rs @@ -1,17 +1,19 @@ -struct Mine{ +//! Checks borrow after move error when using `self` consuming method with struct update syntax. + +struct Mine { test: String, - other_val: isize + other_val: isize, } -impl Mine{ - fn make_string_bar(mut self) -> Mine{ +impl Mine { + fn make_string_bar(mut self) -> Mine { self.test = "Bar".to_string(); self } } -fn main(){ - let start = Mine{test:"Foo".to_string(), other_val:0}; - let end = Mine{other_val:1, ..start.make_string_bar()}; +fn main() { + let start = Mine { test: "Foo".to_string(), other_val: 0 }; + let end = Mine { other_val: 1, ..start.make_string_bar() }; println!("{}", start.test); //~ ERROR borrow of moved value: `start` } diff --git a/tests/ui/borrowck/ownership-struct-update-moved-error.stderr b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr index 34b501f8ec881..83cfc7bb412cf 100644 --- a/tests/ui/borrowck/ownership-struct-update-moved-error.stderr +++ b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr @@ -1,17 +1,17 @@ error[E0382]: borrow of moved value: `start` - --> $DIR/walk-struct-literal-with.rs:16:20 + --> $DIR/ownership-struct-update-moved-error.rs:18:20 | -LL | let start = Mine{test:"Foo".to_string(), other_val:0}; +LL | let start = Mine { test: "Foo".to_string(), other_val: 0 }; | ----- move occurs because `start` has type `Mine`, which does not implement the `Copy` trait -LL | let end = Mine{other_val:1, ..start.make_string_bar()}; - | ----------------- `start` moved due to this method call +LL | let end = Mine { other_val: 1, ..start.make_string_bar() }; + | ----------------- `start` moved due to this method call LL | println!("{}", start.test); | ^^^^^^^^^^ value borrowed here after move | note: `Mine::make_string_bar` takes ownership of the receiver `self`, which moves `start` - --> $DIR/walk-struct-literal-with.rs:7:28 + --> $DIR/ownership-struct-update-moved-error.rs:9:28 | -LL | fn make_string_bar(mut self) -> Mine{ +LL | fn make_string_bar(mut self) -> Mine { | ^^^^ = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/closures/no-capture-closure-call.rs b/tests/ui/closures/no-capture-closure-call.rs index 5f42bcbe280e6..29e5ac635b421 100644 --- a/tests/ui/closures/no-capture-closure-call.rs +++ b/tests/ui/closures/no-capture-closure-call.rs @@ -1,3 +1,5 @@ +//! Sanity check for no capture closures + //@ run-pass pub fn main() { diff --git a/tests/ui/drop/box-drop-unused-value-statement-regression.rs b/tests/ui/drop/box-drop-unused-value-statement-regression.rs index 3d5eff2c48d50..43865e0844457 100644 --- a/tests/ui/drop/box-drop-unused-value-statement-regression.rs +++ b/tests/ui/drop/box-drop-unused-value-statement-regression.rs @@ -1,12 +1,12 @@ -//@ run-pass -// Issue #3878 -// Issue Name: Unused move causes a crash -// Abstract: zero-fill to block after drop - +//! Regression test for a crash caused by an "unsused move" +//! (specifically, a variable bound to a `Box` used as a statement) +//! leading to incorrect memory zero-filling after drop. +//! +//! Regression test for . -#![allow(path_statements)] +//@ run-pass pub fn main() { let y: Box<_> = Box::new(1); - y; + drop(y); } diff --git a/tests/ui/hashmap/hashset-enum-variant.rs b/tests/ui/hashmap/hashset-enum-variant.rs index 5795cc527cf27..39a59d3a39b63 100644 --- a/tests/ui/hashmap/hashset-enum-variant.rs +++ b/tests/ui/hashmap/hashset-enum-variant.rs @@ -1,26 +1,27 @@ +//! Check for correct initialization of `HashSet` with enums. This is a regression test for a +//! codegen bug that caused the `HashSet` to appear as if it contained one of each enum variant. +//! +//! Regression test for + //@ run-pass -// -#![allow(dead_code)] //@ compile-flags: -O +#![allow(dead_code)] + use std::collections::HashSet; #[derive(PartialEq, Debug, Hash, Eq, Clone, PartialOrd, Ord)] enum MyEnum { E0, - E1, - E2, E3, E4, - E5, E6, E7, } - fn main() { use MyEnum::*; let s: HashSet<_> = [E4, E1].iter().cloned().collect(); diff --git a/tests/ui/io-checks/write-macro-error.rs b/tests/ui/io-checks/write-macro-error.rs index b48fa3f11ccb1..857ea0024e16c 100644 --- a/tests/ui/io-checks/write-macro-error.rs +++ b/tests/ui/io-checks/write-macro-error.rs @@ -1,3 +1,6 @@ +//! Tests that errors from both the writer (`Write::write`) and formatter (`Display::fmt`) +//! are correctly propagated: writer errors return `Err`, formatter errors cause panics. + //@ run-pass //@ needs-unwind @@ -24,7 +27,9 @@ impl Write for ErrorWriter { Err(Error::new(WRITER_ERROR, "not connected")) } - fn flush(&mut self) -> io::Result<()> { Ok(()) } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } } fn main() { @@ -37,7 +42,8 @@ fn main() { let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); assert!( err.contains("formatting trait implementation returned an error"), - "unexpected panic: {}", err + "unexpected panic: {}", + err ); // Writer error when there's some string before the first `{}` @@ -50,6 +56,7 @@ fn main() { let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); assert!( err.contains("formatting trait implementation returned an error"), - "unexpected panic: {}", err + "unexpected panic: {}", + err ); } diff --git a/tests/ui/lang-items/lang-item-unknown-definition-error.rs b/tests/ui/lang-items/lang-item-unknown-definition-error.rs index ce206d20358a1..22812128c2d36 100644 --- a/tests/ui/lang-items/lang-item-unknown-definition-error.rs +++ b/tests/ui/lang-items/lang-item-unknown-definition-error.rs @@ -1,9 +1,11 @@ +//! Checks that compiler prevernt attempting to define an unrecognized or unknown lang item + #![allow(unused)] #![feature(lang_items)] #[lang = "foo"] fn bar() -> ! { -//~^^ ERROR definition of an unknown lang item: `foo` + //~^^ ERROR definition of an unknown lang item: `foo` loop {} } diff --git a/tests/ui/lang-items/lang-item-unknown-definition-error.stderr b/tests/ui/lang-items/lang-item-unknown-definition-error.stderr index 832f134241844..3b939757ac2b0 100644 --- a/tests/ui/lang-items/lang-item-unknown-definition-error.stderr +++ b/tests/ui/lang-items/lang-item-unknown-definition-error.stderr @@ -1,5 +1,5 @@ error[E0522]: definition of an unknown lang item: `foo` - --> $DIR/unknown-language-item.rs:4:1 + --> $DIR/lang-item-unknown-definition-error.rs:6:1 | LL | #[lang = "foo"] | ^^^^^^^^^^^^^^^ definition of unknown lang item `foo` diff --git a/tests/ui/modules/module-qualified-paths-basic.rs b/tests/ui/modules/module-qualified-paths-basic.rs index d948ffc1520b3..c02f6060caa71 100644 --- a/tests/ui/modules/module-qualified-paths-basic.rs +++ b/tests/ui/modules/module-qualified-paths-basic.rs @@ -1,11 +1,20 @@ +//! Checks that functions from different modules are accessible via their fully-qualified paths. + //@ run-pass mod foo { - pub fn x() -> isize { return 1; } + pub fn x() -> isize { + return 1; + } } mod bar { - pub fn y() -> isize { return 1; } + pub fn y() -> isize { + return 1; + } } -pub fn main() { foo::x(); bar::y(); } +pub fn main() { + foo::x(); + bar::y(); +} diff --git a/tests/ui/modules/module-use-nested-groups.rs b/tests/ui/modules/module-use-nested-groups.rs index c5d66a8693533..84d1f9141a899 100644 --- a/tests/ui/modules/module-use-nested-groups.rs +++ b/tests/ui/modules/module-use-nested-groups.rs @@ -1,3 +1,5 @@ +//! Checks complex `use` syntax and availability of types across nested modules. + //@ run-pass mod a { diff --git a/tests/ui/modules/primitive-type-module-deprecated-paths.rs b/tests/ui/modules/primitive-type-module-deprecated-paths.rs index 6e8c7053c5760..5c9d2a616b3f0 100644 --- a/tests/ui/modules/primitive-type-module-deprecated-paths.rs +++ b/tests/ui/modules/primitive-type-module-deprecated-paths.rs @@ -1,9 +1,10 @@ +//! Make sure the module level constants are still there and accessible even after +//! the corresponding associated constants have been added, and later stabilized. + //@ run-pass -// Make sure the module level constants are still there and accessible even after -// the corresponding associated constants have been added, and later stabilized. #![allow(deprecated, deprecated_in_future)] -use std::{u16, f32}; +use std::{f32, u16}; fn main() { let _ = u16::MAX; diff --git a/tests/ui/modules/use-keyword-reexport-type-alias.rs b/tests/ui/modules/use-keyword-reexport-type-alias.rs index 4f3d1ee500d80..c62bd9687ae62 100644 --- a/tests/ui/modules/use-keyword-reexport-type-alias.rs +++ b/tests/ui/modules/use-keyword-reexport-type-alias.rs @@ -1,18 +1,20 @@ +//! Checks module re-exports, aliasing with `pub use`, +//! and calling private methods via `Self` in an impl block. + //@ run-pass #![allow(unused_variables)] pub struct A; mod test { - pub use super :: A; - - pub use self :: A as B; + pub use self::A as B; + pub use super::A; } impl A { fn f() {} fn g() { - Self :: f() + Self::f() } } diff --git a/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs index 943c7f79742ab..4325c8b111bc5 100644 --- a/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs +++ b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.rs @@ -1,3 +1,5 @@ +//! This test ensures that the unary negation operator (`-`) cannot be applied to unsigned ints + fn main() { let x = -1 as usize; //~ ERROR: cannot apply unary operator `-` let x = (-1) as usize; //~ ERROR: cannot apply unary operator `-` diff --git a/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr index 0bedbc1accd3b..4ce870ded9f76 100644 --- a/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr +++ b/tests/ui/numbers-arithmetic/unary-negation-unsigned-integer-error.stderr @@ -1,5 +1,5 @@ error[E0600]: cannot apply unary operator `-` to type `usize` - --> $DIR/unsigned-literal-negation.rs:2:13 + --> $DIR/unary-negation-unsigned-integer-error.rs:4:13 | LL | let x = -1 as usize; | ^^ cannot apply unary operator `-` @@ -12,7 +12,7 @@ LL + let x = usize::MAX; | error[E0600]: cannot apply unary operator `-` to type `usize` - --> $DIR/unsigned-literal-negation.rs:3:13 + --> $DIR/unary-negation-unsigned-integer-error.rs:5:13 | LL | let x = (-1) as usize; | ^^^^ cannot apply unary operator `-` @@ -25,7 +25,7 @@ LL + let x = usize::MAX; | error[E0600]: cannot apply unary operator `-` to type `u32` - --> $DIR/unsigned-literal-negation.rs:4:18 + --> $DIR/unary-negation-unsigned-integer-error.rs:6:18 | LL | let x: u32 = -1; | ^^ cannot apply unary operator `-` diff --git a/tests/ui/panics/unwind-force-no-unwind-tables.rs b/tests/ui/panics/unwind-force-no-unwind-tables.rs index fb8082e31880a..2226e4dd03ebc 100644 --- a/tests/ui/panics/unwind-force-no-unwind-tables.rs +++ b/tests/ui/panics/unwind-force-no-unwind-tables.rs @@ -1,3 +1,7 @@ +//! This test checks that Rust's unwinding mechanism correctly executes `Drop` +//! implementations during stack unwinding, even when unwind tables (`uwtable`) +//! are explicitly disabled via `-C force-unwind-tables=n`. + //@ run-pass //@ needs-unwind //@ ignore-windows target requires uwtable @@ -26,9 +30,12 @@ fn increase(count: &mut u8) { fn main() { let mut count = 0; - assert!(panic::catch_unwind(AssertUnwindSafe( - #[inline(never)] - || increase(&mut count) - )).is_err()); + assert!( + panic::catch_unwind(AssertUnwindSafe( + #[inline(never)] + || increase(&mut count) + )) + .is_err() + ); assert_eq!(count, 1); } diff --git a/tests/ui/process/process-spawn-failure.rs b/tests/ui/process/process-spawn-failure.rs index 4a7f2bee9d954..0950b044c97ca 100644 --- a/tests/ui/process/process-spawn-failure.rs +++ b/tests/ui/process/process-spawn-failure.rs @@ -1,3 +1,9 @@ +//! Tests that repeatedly spawning a failing command does not create zombie processes. +//! Spawns a deliberately invalid command multiple times, verifies each spawn fails, +//! then uses `ps` (on Unix) to detect any leftover zombie (defunct) child processes. +//! Checks Rust's process spawning cleans up resources properly. +//! Skipped on platforms without `ps` utility. + //@ run-pass //@ needs-subprocess //@ ignore-vxworks no 'ps' @@ -36,35 +42,42 @@ fn find_zombies() { // the PPID column contains a "-" for the respective process. // Filter out any lines that have a "-" as the PPID as the PPID is // expected to be an integer. - let filtered_ps: Vec<_> = ps_output - .lines() - .filter(|line| line.split_whitespace().nth(1) != Some("-")) - .collect(); + let filtered_ps: Vec<_> = + ps_output.lines().filter(|line| line.split_whitespace().nth(1) != Some("-")).collect(); for (line_no, line) in filtered_ps.into_iter().enumerate() { - if 0 < line_no && 0 < line.len() && - my_pid == line.split(' ').filter(|w| 0 < w.len()).nth(1) - .expect("1st column should be PPID") - .parse().ok() - .expect("PPID string into integer") && - line.contains("defunct") { + if 0 < line_no + && 0 < line.len() + && my_pid + == line + .split(' ') + .filter(|w| 0 < w.len()) + .nth(1) + .expect("1st column should be PPID") + .parse() + .ok() + .expect("PPID string into integer") + && line.contains("defunct") + { panic!("Zombie child {}", line); } } } #[cfg(windows)] -fn find_zombies() { } +fn find_zombies() {} fn main() { let too_long = format!("/NoSuchCommand{:0300}", 0u8); - let _failures = (0..100).map(|_| { - let mut cmd = Command::new(&too_long); - let failed = cmd.spawn(); - assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd); - failed - }).collect::>(); + let _failures = (0..100) + .map(|_| { + let mut cmd = Command::new(&too_long); + let failed = cmd.spawn(); + assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd); + failed + }) + .collect::>(); find_zombies(); // then _failures goes out of scope diff --git a/tests/ui/process/windows-exit-code-still-active.rs b/tests/ui/process/windows-exit-code-still-active.rs index e016343f8ba2f..e661a4f6adc53 100644 --- a/tests/ui/process/windows-exit-code-still-active.rs +++ b/tests/ui/process/windows-exit-code-still-active.rs @@ -1,23 +1,21 @@ +//! On Windows the GetExitCodeProcess API is used to get the exit code of a +//! process, but it's easy to mistake a process exiting with the code 259 as +//! "still running" because this is the value of the STILL_ACTIVE constant. Make +//! sure we handle this case in the standard library and correctly report the +//! status. +//! +//! Note that this is disabled on unix as processes exiting with 259 will have +//! their exit status truncated to 3 (only the lower 8 bits are used). + //@ run-pass -// On Windows the GetExitCodeProcess API is used to get the exit code of a -// process, but it's easy to mistake a process exiting with the code 259 as -// "still running" because this is the value of the STILL_ACTIVE constant. Make -// sure we handle this case in the standard library and correctly report the -// status. -// -// Note that this is disabled on unix as processes exiting with 259 will have -// their exit status truncated to 3 (only the lower 8 bits are used). #[cfg(windows)] fn main() { - use std::process::{self, Command}; use std::env; + use std::process::{self, Command}; if env::args().len() == 1 { - let status = Command::new(env::current_exe().unwrap()) - .arg("foo") - .status() - .unwrap(); + let status = Command::new(env::current_exe().unwrap()).arg("foo").status().unwrap(); assert_eq!(status.code(), Some(259)); } else { process::exit(259); diff --git a/tests/ui/reachable/diverging-expressions-unreachable-code.rs b/tests/ui/reachable/diverging-expressions-unreachable-code.rs index 9c5f7c8f45190..bb56987775ff2 100644 --- a/tests/ui/reachable/diverging-expressions-unreachable-code.rs +++ b/tests/ui/reachable/diverging-expressions-unreachable-code.rs @@ -3,17 +3,17 @@ #![allow(unused_must_use)] #![allow(unreachable_code)] -#![allow(unused_variables)] -#![allow(dead_code)] - -fn id(x: bool) -> bool { x } - -fn call_id() { - let c = panic!(); - id(c); +fn _id(x: bool) -> bool { + x } -fn call_id_3() { id(return) && id(return); } +fn _call_id() { + let _c = panic!(); + _id(_c); +} -pub fn main() { +fn _call_id_3() { + _id(return) && _id(return); } + +pub fn main() {} diff --git a/tests/ui/reachable/unreachable-code-diverging-expressions.rs b/tests/ui/reachable/unreachable-code-diverging-expressions.rs index 0c46a38d73f35..00676418002c9 100644 --- a/tests/ui/reachable/unreachable-code-diverging-expressions.rs +++ b/tests/ui/reachable/unreachable-code-diverging-expressions.rs @@ -26,9 +26,13 @@ fn call_id_3() { fn ret_guard() { match 2 { - x if (return) => { x; } - x if let true = return => { x; } - _ => {} + x if (return) => { + x; + } + x if let true = return => { + x; + } + _ => {} } } diff --git a/tests/ui/traits/virtual-call-parameter-handling.rs b/tests/ui/traits/virtual-call-parameter-handling.rs index e80bd5768a429..71ed459d15aca 100644 --- a/tests/ui/traits/virtual-call-parameter-handling.rs +++ b/tests/ui/traits/virtual-call-parameter-handling.rs @@ -1,5 +1,7 @@ -//! Regression test for https://github.com/rust-lang/rust/issues/137646. -//! The parameter value at all calls to `check` should be `(1, 1, 1)`. +//! This test checks the correct parameter handling during virtual method calls +//! through a `dyn Trait` object. +//! +//! Regression test for: //@ run-pass diff --git a/tests/ui/type/unit-type-basic-usages.rs b/tests/ui/type/unit-type-basic-usages.rs index 04404fc3f5e66..c3ee8067f5918 100644 --- a/tests/ui/type/unit-type-basic-usages.rs +++ b/tests/ui/type/unit-type-basic-usages.rs @@ -1,16 +1,14 @@ -//@ run-pass - -#![allow(unused_assignments)] -#![allow(unknown_lints)] +//! Checks the basic usage of unit type -#![allow(unused_variables)] -#![allow(dead_assignment)] +//@ run-pass -fn f(u: ()) { return u; } +fn f(u: ()) { + u +} pub fn main() { let u1: () = (); - let mut u2: () = f(u1); - u2 = (); - return (); + let mut _u2: () = f(u1); + _u2 = (); + () } diff --git a/tests/ui/type/usize-no-generic-arguments.rs b/tests/ui/type/usize-no-generic-arguments.rs index 4ab80d944a56f..d4d1eea757cab 100644 --- a/tests/ui/type/usize-no-generic-arguments.rs +++ b/tests/ui/type/usize-no-generic-arguments.rs @@ -1,3 +1,5 @@ +//! Sanity test that primitives cannot have const generics. + fn foo() { let x: usize; //~ ERROR const arguments are not allowed on builtin type `usize` } diff --git a/tests/ui/type/usize-no-generic-arguments.stderr b/tests/ui/type/usize-no-generic-arguments.stderr index 9c081a287ed75..f1f3456461fc6 100644 --- a/tests/ui/type/usize-no-generic-arguments.stderr +++ b/tests/ui/type/usize-no-generic-arguments.stderr @@ -1,5 +1,5 @@ error[E0109]: const arguments are not allowed on builtin type `usize` - --> $DIR/usize-generic-argument-parent.rs:2:18 + --> $DIR/usize-no-generic-arguments.rs:4:18 | LL | let x: usize; | ----- ^^^ const argument not allowed diff --git a/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs b/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs index 82474d873b788..e587ca554fe4d 100644 --- a/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs +++ b/tests/ui/unsafe/maybe-uninit-zero-sized-types.rs @@ -1,6 +1,9 @@ -//@ build-pass -// Test the uninit() construct returning various empty types. +//! This test checks that ZSTs can be safely initialized from +//! `MaybeUninit::uninit().assume_init()` and `std::mem::uninitialized()` +//! (which is deprecated). This is safe because ZSTs inherently +//! require no actual memory initialization, as they occupy no memory. +//@ build-pass use std::mem::MaybeUninit; From 61b172a34c94108d013a2d352901b4a5a06ad9ee Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 8 Jul 2025 18:10:58 -0600 Subject: [PATCH 11/15] test: Make one multi suggestion test unicode --- .../suggestions/multi-suggestion.ascii.stderr | 130 ++++++++++++++++++ tests/ui/suggestions/multi-suggestion.rs | 22 +++ .../multi-suggestion.unicode.stderr | 130 ++++++++++++++++++ 3 files changed, 282 insertions(+) create mode 100644 tests/ui/suggestions/multi-suggestion.ascii.stderr create mode 100644 tests/ui/suggestions/multi-suggestion.rs create mode 100644 tests/ui/suggestions/multi-suggestion.unicode.stderr diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr new file mode 100644 index 0000000000000..b6c7b9ed6df23 --- /dev/null +++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr @@ -0,0 +1,130 @@ +error[E0423]: expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` + --> $DIR/multi-suggestion.rs:17:13 + | +LL | let _ = std::collections::HashMap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + | + = note: `std::collections::HashMap` defined here + | +help: you might have meant to use an associated function to build this type + | +LL | let _ = std::collections::HashMap::new(); + | +++++ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity(_); + | +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_hasher(_); + | +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + | +help: consider using the `Default` trait + | +LL | let _ = ::default(); + | + ++++++++++++++++++++++++++++++++++ + +error[E0423]: cannot initialize a tuple struct which contains private fields + --> $DIR/multi-suggestion.rs:11:19 + | +LL | wtf: Some(Box(U { + | ^^^ + | +note: constructor is not visible here due to private fields + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: private field + | + = note: private field +help: you might have meant to use an associated function to build this type + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new(_)), + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_uninit()), + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_zeroed()), + | +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_in(_, _)), + | + and 12 other candidates +help: consider using the `Default` trait + | +LL - wtf: Some(Box(U { +LL + wtf: Some(::default()), + | + +error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + --> $DIR/multi-suggestion.rs:19:13 + | +LL | let _ = std::collections::HashMap {}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: private field `base` that was not provided +help: you might have meant to use an associated function to build this type + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new(); + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity(_); + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_hasher(_); + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + | +help: consider using the `Default` trait + | +LL - let _ = std::collections::HashMap {}; +LL + let _ = ::default(); + | + +error: cannot construct `Box<_, _>` with struct literal syntax due to private fields + --> $DIR/multi-suggestion.rs:21:13 + | +LL | let _ = Box {}; + | ^^^ + | + = note: private fields `0` and `1` that were not provided +help: you might have meant to use an associated function to build this type + | +LL - let _ = Box {}; +LL + let _ = Box::new(_); + | +LL - let _ = Box {}; +LL + let _ = Box::new_uninit(); + | +LL - let _ = Box {}; +LL + let _ = Box::new_zeroed(); + | +LL - let _ = Box {}; +LL + let _ = Box::new_in(_, _); + | + and 12 other candidates +help: consider using the `Default` trait + | +LL - let _ = Box {}; +LL + let _ = ::default(); + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/suggestions/multi-suggestion.rs b/tests/ui/suggestions/multi-suggestion.rs new file mode 100644 index 0000000000000..99d2407aa212a --- /dev/null +++ b/tests/ui/suggestions/multi-suggestion.rs @@ -0,0 +1,22 @@ +//@ revisions: ascii unicode +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode + +#![allow(dead_code)] +struct U { + wtf: Option>>, + x: T, +} +fn main() { + U { + wtf: Some(Box(U { //[ascii]~ ERROR cannot initialize a tuple struct which contains private fields + wtf: None, + x: (), + })), + x: () + }; + let _ = std::collections::HashMap(); + //[ascii]~^ ERROR expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` + let _ = std::collections::HashMap {}; + //[ascii]~^ ERROR cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + let _ = Box {}; //[ascii]~ ERROR cannot construct `Box<_, _>` with struct literal syntax due to private fields +} diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr new file mode 100644 index 0000000000000..e0933606de0e7 --- /dev/null +++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr @@ -0,0 +1,130 @@ +error[E0423]: expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` + ╭▸ $DIR/multi-suggestion.rs:17:13 + │ +LL │ let _ = std::collections::HashMap(); + │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━ + ╭▸ $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + │ + ╰ note: `std::collections::HashMap` defined here + ╰╴ +help: you might have meant to use an associated function to build this type + ╭╴ +LL │ let _ = std::collections::HashMap::new(); + ├╴ +++++ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity(_); + ├╴ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_hasher(_); + ├╴ +LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + ╰╴ +help: consider using the `Default` trait + ╭╴ +LL │ let _ = ::default(); + ╰╴ + ++++++++++++++++++++++++++++++++++ + +error[E0423]: cannot initialize a tuple struct which contains private fields + ╭▸ $DIR/multi-suggestion.rs:11:19 + │ +LL │ wtf: Some(Box(U { + │ ━━━ + ╰╴ +note: constructor is not visible here due to private fields + ╭▸ $SRC_DIR/alloc/src/boxed.rs:LL:COL + │ + ╰ note: private field + │ + ╰ note: private field +help: you might have meant to use an associated function to build this type + ╭╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new(_)), + ├╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_uninit()), + ├╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_zeroed()), + ├╴ +LL - wtf: Some(Box(U { +LL - wtf: None, +LL - x: (), +LL - })), +LL + wtf: Some(Box::new_in(_, _)), + ╰╴ + and 12 other candidates +help: consider using the `Default` trait + ╭╴ +LL - wtf: Some(Box(U { +LL + wtf: Some(::default()), + ╰╴ + +error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + ╭▸ $DIR/multi-suggestion.rs:19:13 + │ +LL │ let _ = std::collections::HashMap {}; + │ ━━━━━━━━━━━━━━━━━━━━━━━━━ + │ + ╰ note: private field `base` that was not provided +help: you might have meant to use an associated function to build this type + ╭╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new(); + ├╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity(_); + ├╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_hasher(_); + ├╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); + ╰╴ +help: consider using the `Default` trait + ╭╴ +LL - let _ = std::collections::HashMap {}; +LL + let _ = ::default(); + ╰╴ + +error: cannot construct `Box<_, _>` with struct literal syntax due to private fields + ╭▸ $DIR/multi-suggestion.rs:21:13 + │ +LL │ let _ = Box {}; + │ ━━━ + │ + ╰ note: private fields `0` and `1` that were not provided +help: you might have meant to use an associated function to build this type + ╭╴ +LL - let _ = Box {}; +LL + let _ = Box::new(_); + ├╴ +LL - let _ = Box {}; +LL + let _ = Box::new_uninit(); + ├╴ +LL - let _ = Box {}; +LL + let _ = Box::new_zeroed(); + ├╴ +LL - let _ = Box {}; +LL + let _ = Box::new_in(_, _); + ╰╴ + and 12 other candidates +help: consider using the `Default` trait + ╭╴ +LL - let _ = Box {}; +LL + let _ = ::default(); + ╰╴ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0423`. From d67bf6095a9a3f278a223a20b316c235360c1c90 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 1 Jul 2025 19:09:45 -0600 Subject: [PATCH 12/15] chore: Improve how the other suggestions message gets rendered --- compiler/rustc_errors/src/emitter.rs | 9 +++++++-- .../associated-types-in-ambiguous-context.stderr | 2 +- tests/ui/const-generics/issues/issue-82956.stderr | 2 +- .../issue-56028-there-is-an-enum-variant.stderr | 4 ++-- .../call_method_without_import.no_import.stderr | 2 +- tests/ui/imports/issue-56125.stderr | 2 +- tests/ui/lint/use_suggestion_json.stderr | 2 +- tests/ui/privacy/suggest-box-new.stderr | 4 ++-- tests/ui/rust-2018/issue-52202-use-suggestions.stderr | 2 +- tests/ui/suggestions/multi-suggestion.ascii.stderr | 4 ++-- tests/ui/suggestions/multi-suggestion.unicode.stderr | 8 ++++---- tests/ui/suggestions/too-many-field-suggestions.stderr | 4 ++-- 12 files changed, 25 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 2f398cea926cd..1b581f9373686 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2446,17 +2446,22 @@ impl HumanEmitter { | DisplaySuggestion::Underline => row_num - 1, DisplaySuggestion::None => row_num, }; - self.draw_col_separator_end(&mut buffer, row, max_line_num_len + 1); + if other_suggestions > 0 { + self.draw_col_separator_no_space(&mut buffer, row, max_line_num_len + 1); + } else { + self.draw_col_separator_end(&mut buffer, row, max_line_num_len + 1); + } row_num = row + 1; } } if other_suggestions > 0 { + self.draw_note_separator(&mut buffer, row_num, max_line_num_len + 1, false); let msg = format!( "and {} other candidate{}", other_suggestions, pluralize!(other_suggestions) ); - buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle); + buffer.append(row_num, &msg, Style::NoStyle); } emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr index a7647cf26aadf..71a1360cb5a22 100644 --- a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr +++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr @@ -42,7 +42,7 @@ LL + type X = ::Target; LL - type X = std::ops::Deref::Target; LL + type X = as Deref>::Target; | - and N other candidates + = and N other candidates error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:13:23 diff --git a/tests/ui/const-generics/issues/issue-82956.stderr b/tests/ui/const-generics/issues/issue-82956.stderr index 5e380eea81cab..fd93e5122a5ef 100644 --- a/tests/ui/const-generics/issues/issue-82956.stderr +++ b/tests/ui/const-generics/issues/issue-82956.stderr @@ -14,7 +14,7 @@ LL + use std::collections::btree_map::IntoIter; | LL + use std::collections::btree_set::IntoIter; | - and 9 other candidates + = and 9 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr index 927f9e842e665..12965800a027f 100644 --- a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr +++ b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr @@ -18,7 +18,7 @@ LL + fn setup() -> Determine { Set } LL - fn setup() -> Set { Set } LL + fn setup() -> PutDown { Set } | - and 3 other candidates + = and 3 other candidates error[E0425]: cannot find value `Set` in this scope --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:21 @@ -36,7 +36,7 @@ LL + use Determine::Set; | LL + use PutDown::Set; | - and 3 other candidates + = and 3 other candidates error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/call_method_without_import.no_import.stderr b/tests/ui/impl-trait/call_method_without_import.no_import.stderr index 72982b695bbb0..e59409ea27e64 100644 --- a/tests/ui/impl-trait/call_method_without_import.no_import.stderr +++ b/tests/ui/impl-trait/call_method_without_import.no_import.stderr @@ -30,7 +30,7 @@ LL + use std::fmt::Display; | LL + use std::fmt::LowerExp; | - and 5 other candidates + = and 5 other candidates error: aborting due to 2 previous errors diff --git a/tests/ui/imports/issue-56125.stderr b/tests/ui/imports/issue-56125.stderr index 81336d51df4c6..371130facf9d3 100644 --- a/tests/ui/imports/issue-56125.stderr +++ b/tests/ui/imports/issue-56125.stderr @@ -18,7 +18,7 @@ LL + use ::issue_56125::issue_56125; LL - use empty::issue_56125; LL + use ::issue_56125::last_segment::issue_56125; | - and 1 other candidate + = and 1 other candidate error[E0659]: `issue_56125` is ambiguous --> $DIR/issue-56125.rs:6:9 diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr index 0d4304e2e2e40..558c2260fcede 100644 --- a/tests/ui/lint/use_suggestion_json.stderr +++ b/tests/ui/lint/use_suggestion_json.stderr @@ -419,7 +419,7 @@ mod foo { \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m \u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::hash_map::Iter;\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0m and 9 other candidates\u001b[0m +\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0mand 9 other candidates\u001b[0m " } diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index b651348de29ea..6c47b52c9de74 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -63,7 +63,7 @@ LL - x: (), LL - })), LL + wtf: Some(Box::new_in(_, _)), | - and 12 other candidates + = and 12 other candidates help: consider using the `Default` trait | LL - wtf: Some(Box(U { @@ -118,7 +118,7 @@ LL + let _ = Box::new_zeroed(); LL - let _ = Box {}; LL + let _ = Box::new_in(_, _); | - and 12 other candidates + = and 12 other candidates help: consider using the `Default` trait | LL - let _ = Box {}; diff --git a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr index ee1a336ea98f6..0eb1d46637bd5 100644 --- a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr +++ b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr @@ -14,7 +14,7 @@ LL + use std::collections::hash_map::Drain; | LL + use std::collections::hash_set::Drain; | - and 3 other candidates + = and 3 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr index b6c7b9ed6df23..f2a146fbd5257 100644 --- a/tests/ui/suggestions/multi-suggestion.ascii.stderr +++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr @@ -63,7 +63,7 @@ LL - x: (), LL - })), LL + wtf: Some(Box::new_in(_, _)), | - and 12 other candidates + = and 12 other candidates help: consider using the `Default` trait | LL - wtf: Some(Box(U { @@ -118,7 +118,7 @@ LL + let _ = Box::new_zeroed(); LL - let _ = Box {}; LL + let _ = Box::new_in(_, _); | - and 12 other candidates + = and 12 other candidates help: consider using the `Default` trait | LL - let _ = Box {}; diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr index e0933606de0e7..69df481579bc7 100644 --- a/tests/ui/suggestions/multi-suggestion.unicode.stderr +++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr @@ -62,8 +62,8 @@ LL - wtf: None, LL - x: (), LL - })), LL + wtf: Some(Box::new_in(_, _)), - ╰╴ - and 12 other candidates + │ + ╰ and 12 other candidates help: consider using the `Default` trait ╭╴ LL - wtf: Some(Box(U { @@ -117,8 +117,8 @@ LL + let _ = Box::new_zeroed(); ├╴ LL - let _ = Box {}; LL + let _ = Box::new_in(_, _); - ╰╴ - and 12 other candidates + │ + ╰ and 12 other candidates help: consider using the `Default` trait ╭╴ LL - let _ = Box {}; diff --git a/tests/ui/suggestions/too-many-field-suggestions.stderr b/tests/ui/suggestions/too-many-field-suggestions.stderr index ac5c8cb60ccdc..0cb0c8bec07f1 100644 --- a/tests/ui/suggestions/too-many-field-suggestions.stderr +++ b/tests/ui/suggestions/too-many-field-suggestions.stderr @@ -17,7 +17,7 @@ LL | t.a2.bar(); | +++ LL | t.a3.bar(); | +++ - and 6 other candidates + = and 6 other candidates error[E0609]: no field `field` on type `Thing` --> $DIR/too-many-field-suggestions.rs:26:7 @@ -35,7 +35,7 @@ LL | t.a2.field; | +++ LL | t.a3.field; | +++ - and 6 other candidates + = and 6 other candidates error: aborting due to 2 previous errors From df53b3dc04950d980bd28ec4b04f48cd0cd01237 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 10 Jul 2025 10:25:29 -0500 Subject: [PATCH 13/15] test(lexer): Add frontmatter unit test --- compiler/rustc_lexer/src/tests.rs | 86 ++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index a9fcb4817599f..a7357ba38c8e4 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -124,9 +124,9 @@ fn test_valid_shebang() { assert_eq!(strip_shebang(input), None); } -fn check_lexing(src: &str, expect: Expect) { +fn check_lexing(src: &str, frontmatter_allowed: FrontmatterAllowed, expect: Expect) { let actual: String = - tokenize(src, FrontmatterAllowed::No).map(|token| format!("{:?}\n", token)).collect(); + tokenize(src, frontmatter_allowed).map(|token| format!("{:?}\n", token)).collect(); expect.assert_eq(&actual) } @@ -134,6 +134,7 @@ fn check_lexing(src: &str, expect: Expect) { fn smoke_test() { check_lexing( "/* my source file */ fn main() { println!(\"zebra\"); }\n", + FrontmatterAllowed::No, expect![[r#" Token { kind: BlockComment { doc_style: None, terminated: true }, len: 20 } Token { kind: Whitespace, len: 1 } @@ -172,6 +173,7 @@ fn comment_flavors() { /** outer doc block */ /*! inner doc block */ ", + FrontmatterAllowed::No, expect![[r#" Token { kind: Whitespace, len: 1 } Token { kind: LineComment { doc_style: None }, len: 7 } @@ -200,6 +202,7 @@ fn comment_flavors() { fn nested_block_comments() { check_lexing( "/* /* */ */'a'", + FrontmatterAllowed::No, expect![[r#" Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 } Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } @@ -211,6 +214,7 @@ fn nested_block_comments() { fn characters() { check_lexing( "'a' ' ' '\\n'", + FrontmatterAllowed::No, expect![[r#" Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } Token { kind: Whitespace, len: 1 } @@ -225,6 +229,7 @@ fn characters() { fn lifetime() { check_lexing( "'abc", + FrontmatterAllowed::No, expect![[r#" Token { kind: Lifetime { starts_with_number: false }, len: 4 } "#]], @@ -235,6 +240,7 @@ fn lifetime() { fn raw_string() { check_lexing( "r###\"\"#a\\b\x00c\"\"###", + FrontmatterAllowed::No, expect![[r#" Token { kind: Literal { kind: RawStr { n_hashes: Some(3) }, suffix_start: 17 }, len: 17 } "#]], @@ -258,6 +264,7 @@ b"a" r###"raw"###suffix br###"raw"###suffix "####, + FrontmatterAllowed::No, expect![[r#" Token { kind: Whitespace, len: 1 } Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } @@ -287,3 +294,78 @@ br###"raw"###suffix "#]], ) } + +#[test] +fn frontmatter_allowed() { + check_lexing( + r#" +---cargo +[dependencies] +clap = "4" +--- + +fn main() {} +"#, + FrontmatterAllowed::Yes, + expect![[r#" + Token { kind: Whitespace, len: 1 } + Token { kind: Frontmatter { has_invalid_preceding_whitespace: false, invalid_infostring: false }, len: 38 } + Token { kind: Whitespace, len: 2 } + Token { kind: Ident, len: 2 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 4 } + Token { kind: OpenParen, len: 1 } + Token { kind: CloseParen, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: OpenBrace, len: 1 } + Token { kind: CloseBrace, len: 1 } + Token { kind: Whitespace, len: 1 } + "#]], + ) +} + +#[test] +fn frontmatter_disallowed() { + check_lexing( + r#" +---cargo +[dependencies] +clap = "4" +--- + +fn main() {} +"#, + FrontmatterAllowed::No, + expect![[r#" + Token { kind: Whitespace, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Ident, len: 5 } + Token { kind: Whitespace, len: 1 } + Token { kind: OpenBracket, len: 1 } + Token { kind: Ident, len: 12 } + Token { kind: CloseBracket, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 4 } + Token { kind: Whitespace, len: 1 } + Token { kind: Eq, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 3 }, len: 3 } + Token { kind: Whitespace, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Minus, len: 1 } + Token { kind: Whitespace, len: 2 } + Token { kind: Ident, len: 2 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 4 } + Token { kind: OpenParen, len: 1 } + Token { kind: CloseParen, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: OpenBrace, len: 1 } + Token { kind: CloseBrace, len: 1 } + Token { kind: Whitespace, len: 1 } + "#]], + ) +} From a11ee5614c052d6339c56c2673780468c96dbc16 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 9 Jul 2025 15:35:52 -0500 Subject: [PATCH 14/15] fix: Include frontmatter in -Zunpretty output In the implementation (#140035), this was left as an open question for the tracking issue (#136889). My assumption is that this should be carried over. Thankfully, either way, `-Zunpretty` is unstable and we can always change it even if we stabilize frontmatter. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 10 +++++++++- tests/ui/unpretty/frontmatter.stdout | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 9d656253f720d..def0cb74d295b 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -120,7 +120,7 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec pos += shebang_len; } - for token in rustc_lexer::tokenize(&text[pos..], rustc_lexer::FrontmatterAllowed::No) { + for token in rustc_lexer::tokenize(&text[pos..], rustc_lexer::FrontmatterAllowed::Yes) { let token_text = &text[pos..pos + token.len as usize]; match token.kind { rustc_lexer::TokenKind::Whitespace => { @@ -171,6 +171,14 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec }) } } + rustc_lexer::TokenKind::Frontmatter { .. } => { + code_to_the_left = false; + comments.push(Comment { + style: CommentStyle::Isolated, + lines: vec![token_text.to_string()], + pos: start_bpos + BytePos(pos as u32), + }); + } _ => { code_to_the_left = true; } diff --git a/tests/ui/unpretty/frontmatter.stdout b/tests/ui/unpretty/frontmatter.stdout index 9ad6bbbe5774b..2ccbb1b258255 100644 --- a/tests/ui/unpretty/frontmatter.stdout +++ b/tests/ui/unpretty/frontmatter.stdout @@ -1,3 +1,5 @@ +--- +--- //@ compile-flags: -Zunpretty=normal //@ check-pass From f5fc8727dbbf8c9e93bb0822b2e5bfa77dbd0208 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 10 Jul 2025 09:17:28 -0700 Subject: [PATCH 15/15] Add `BuilderMethods::unreachable_nonterminator` So places that need `unreachable` but in the middle of a basic block can call that instead of figuring out the best way to do it. --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 8 +--- .../rustc_codegen_ssa/src/traits/builder.rs | 10 +++++ tests/codegen/intrinsics/transmute.rs | 41 +++++++++---------- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 1e3b76e5f933d..bf3b1e73b94c8 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -207,9 +207,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { { // These cases are all UB to actually hit, so don't emit code for them. // (The size mismatches are reachable via `transmute_unchecked`.) - // We can't use unreachable because that's a terminator, and we - // need something that can be in the middle of a basic block. - bx.assume(bx.cx().const_bool(false)) + bx.unreachable_nonterminator(); } else { // Since in this path we have a place anyway, we can store or copy to it, // making sure we use the destination place's alignment even if the @@ -236,9 +234,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { || operand.layout.is_uninhabited() || cast.is_uninhabited() { - // We can't use unreachable because that's a terminator, and we - // need something that can be in the middle of a basic block. - bx.assume(bx.cx().const_bool(false)); + bx.unreachable_nonterminator(); // We still need to return a value of the appropriate type, but // it's already UB so do the easiest thing available. diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 9d367748c2a8a..0f1358ee50850 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -136,6 +136,16 @@ pub trait BuilderMethods<'a, 'tcx>: ) -> Self::Value; fn unreachable(&mut self); + /// Like [`Self::unreachable`], but for use in the middle of a basic block. + fn unreachable_nonterminator(&mut self) { + // This is the preferred LLVM incantation for this per + // https://llvm.org/docs/Frontend/PerformanceTips.html#other-things-to-consider + // Other backends may override if they have a better way. + let const_true = self.cx().const_bool(true); + let poison_ptr = self.const_poison(self.cx().type_ptr()); + self.store(const_true, poison_ptr, Align::ONE); + } + fn add(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fadd(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fadd_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index 36d6a2f722f23..c9a1cd58af338 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -29,28 +29,28 @@ pub struct Aggregate8(u8); // CHECK-LABEL: @check_bigger_size( #[no_mangle] pub unsafe fn check_bigger_size(x: u16) -> u32 { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_size( #[no_mangle] pub unsafe fn check_smaller_size(x: u32) -> u16 { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_array( #[no_mangle] pub unsafe fn check_smaller_array(x: [u32; 7]) -> [u32; 3] { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } // CHECK-LABEL: @check_bigger_array( #[no_mangle] pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { - // CHECK: call void @llvm.assume(i1 false) + // CHECK: store i1 true, ptr poison, align 1 transmute_unchecked(x) } @@ -58,9 +58,9 @@ pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] { - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { { RET = CastTransmute(x); @@ -73,9 +73,9 @@ pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] { - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { { RET = CastTransmute(x); @@ -88,9 +88,9 @@ pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_uninhabited(x: u16) { - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { let temp: BigNever; { @@ -104,10 +104,9 @@ pub unsafe fn check_to_uninhabited(x: u16) { #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 { - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call - // CHECK: ret i16 poison + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret i16 poison mir! { { RET = CastTransmute(x); @@ -404,9 +403,9 @@ pub unsafe fn check_issue_109992(x: ()) -> [(); 1] { pub unsafe fn check_unit_to_never(x: ()) { // This uses custom MIR to avoid MIR optimizations having removed ZST ops. - // CHECK-NOT: call - // CHECK: call void @llvm.assume(i1 false) - // CHECK-NOT: call + // CHECK: start + // CHECK-NEXT: store i1 true, ptr poison, align 1 + // CHECK-NEXT: ret void mir! { let temp: ZstNever; { @@ -423,7 +422,7 @@ pub unsafe fn check_unit_from_never(x: ZstNever) -> () { // This uses custom MIR to avoid MIR optimizations having removed ZST ops. // CHECK: start - // CHECK-NEXT: call void @llvm.assume(i1 false) + // CHECK-NEXT: store i1 true, ptr poison, align 1 // CHECK-NEXT: ret void mir! { {