From 25ab022f2951318e8ffdec2d8566c3a7d164e00d Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 29 Jun 2025 15:37:28 +0800 Subject: move `tests/ui/resolve/suggest*` to `tests/ui/resolve/suggestions/` Signed-off-by: xizheyin --- .../auxiliary/suggest-constructor-cycle-error.rs | 12 -- tests/ui/resolve/suggest-builder-fn.rs | 64 -------- tests/ui/resolve/suggest-builder-fn.stderr | 51 ------ .../ui/resolve/suggest-constructor-cycle-error.rs | 10 -- .../resolve/suggest-constructor-cycle-error.stderr | 15 -- .../suggest-import-without-clobbering-attrs.fixed | 16 -- .../suggest-import-without-clobbering-attrs.rs | 15 -- .../suggest-import-without-clobbering-attrs.stderr | 14 -- tests/ui/resolve/suggest-path-for-tuple-struct.rs | 26 --- .../resolve/suggest-path-for-tuple-struct.stderr | 27 ---- .../suggest-path-instead-of-mod-dot-item.rs | 111 ------------- .../suggest-path-instead-of-mod-dot-item.stderr | 178 --------------------- .../auxiliary/suggest-constructor-cycle-error.rs | 12 ++ tests/ui/resolve/suggestions/suggest-builder-fn.rs | 64 ++++++++ .../resolve/suggestions/suggest-builder-fn.stderr | 51 ++++++ .../suggestions/suggest-constructor-cycle-error.rs | 10 ++ .../suggest-constructor-cycle-error.stderr | 15 ++ .../suggest-import-without-clobbering-attrs.fixed | 16 ++ .../suggest-import-without-clobbering-attrs.rs | 15 ++ .../suggest-import-without-clobbering-attrs.stderr | 14 ++ .../suggestions/suggest-path-for-tuple-struct.rs | 26 +++ .../suggest-path-for-tuple-struct.stderr | 27 ++++ .../suggest-path-instead-of-mod-dot-item.rs | 111 +++++++++++++ .../suggest-path-instead-of-mod-dot-item.stderr | 178 +++++++++++++++++++++ 24 files changed, 539 insertions(+), 539 deletions(-) delete mode 100644 tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs delete mode 100644 tests/ui/resolve/suggest-builder-fn.rs delete mode 100644 tests/ui/resolve/suggest-builder-fn.stderr delete mode 100644 tests/ui/resolve/suggest-constructor-cycle-error.rs delete mode 100644 tests/ui/resolve/suggest-constructor-cycle-error.stderr delete mode 100644 tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed delete mode 100644 tests/ui/resolve/suggest-import-without-clobbering-attrs.rs delete mode 100644 tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr delete mode 100644 tests/ui/resolve/suggest-path-for-tuple-struct.rs delete mode 100644 tests/ui/resolve/suggest-path-for-tuple-struct.stderr delete mode 100644 tests/ui/resolve/suggest-path-instead-of-mod-dot-item.rs delete mode 100644 tests/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr create mode 100644 tests/ui/resolve/suggestions/auxiliary/suggest-constructor-cycle-error.rs create mode 100644 tests/ui/resolve/suggestions/suggest-builder-fn.rs create mode 100644 tests/ui/resolve/suggestions/suggest-builder-fn.stderr create mode 100644 tests/ui/resolve/suggestions/suggest-constructor-cycle-error.rs create mode 100644 tests/ui/resolve/suggestions/suggest-constructor-cycle-error.stderr create mode 100644 tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed create mode 100644 tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs create mode 100644 tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.stderr create mode 100644 tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.rs create mode 100644 tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.stderr create mode 100644 tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.rs create mode 100644 tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr diff --git a/tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs b/tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs deleted file mode 100644 index 8de68c38bc3..00000000000 --- a/tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs +++ /dev/null @@ -1,12 +0,0 @@ -mod m { - pub struct Uuid(()); - - impl Uuid { - pub fn encode_buffer() -> [u8; LENGTH] { - [] - } - } - const LENGTH: usize = 0; -} - -pub use m::Uuid; diff --git a/tests/ui/resolve/suggest-builder-fn.rs b/tests/ui/resolve/suggest-builder-fn.rs deleted file mode 100644 index 959675ef2c9..00000000000 --- a/tests/ui/resolve/suggest-builder-fn.rs +++ /dev/null @@ -1,64 +0,0 @@ -// Tests that we suggest the right alternatives when -// a builder method cannot be resolved - -use std::net::TcpStream; - -trait SomeTrait {} - -struct Foo { - v : T -} - -impl Foo { - // Should not be suggested if constraint on the impl not met - fn new() -> Self { - Self { v: T::default() } - } -} - -struct Bar; - -impl Bar { - // Should be suggested - fn build() -> Self { - Self {} - } - - // Method with self can't be a builder. - // Should not be suggested - fn build_with_self(&self) -> Self { - Self {} - } -} - -mod SomeMod { - use crate::Bar; - - impl Bar { - // Public method. Should be suggested - pub fn build_public() -> Self { - Self {} - } - - // Private method. Should not be suggested - fn build_private() -> Self { - Self {} - } - } -} - -fn main() { - // `new` not found on `TcpStream` and `connect` should be suggested - let _stream = TcpStream::new(); - //~^ ERROR no function or associated item named `new` found - - // Although `new` is found on `>` it should not be - // suggested because `u8` does not meet the `T: SomeTrait` constraint - let _foo = Foo::::new(); - //~^ ERROR the function or associated item `new` exists for struct `Foo`, but its trait bounds were not satisfied - - // Should suggest only `::build()` and `SomeMod::::build_public()`. - // Other methods should not suggested because they are private or are not a builder - let _bar = Bar::new(); - //~^ ERROR no function or associated item named `new` found -} diff --git a/tests/ui/resolve/suggest-builder-fn.stderr b/tests/ui/resolve/suggest-builder-fn.stderr deleted file mode 100644 index 9c5eed35ccf..00000000000 --- a/tests/ui/resolve/suggest-builder-fn.stderr +++ /dev/null @@ -1,51 +0,0 @@ -error[E0599]: no function or associated item named `new` found for struct `TcpStream` in the current scope - --> $DIR/suggest-builder-fn.rs:52:29 - | -LL | let _stream = TcpStream::new(); - | ^^^ function or associated item not found in `TcpStream` - | -note: if you're trying to build a new `TcpStream` consider using one of the following associated functions: - TcpStream::connect - TcpStream::connect_timeout - --> $SRC_DIR/std/src/net/tcp.rs:LL:COL - -error[E0599]: the function or associated item `new` exists for struct `Foo`, but its trait bounds were not satisfied - --> $DIR/suggest-builder-fn.rs:57:27 - | -LL | struct Foo { - | ------------- function or associated item `new` not found for this struct -... -LL | let _foo = Foo::::new(); - | ^^^ function or associated item cannot be called on `Foo` due to unsatisfied trait bounds - | -note: trait bound `u8: SomeTrait` was not satisfied - --> $DIR/suggest-builder-fn.rs:12:9 - | -LL | impl Foo { - | ^^^^^^^^^ ------ - | | - | unsatisfied trait bound introduced here - -error[E0599]: no function or associated item named `new` found for struct `Bar` in the current scope - --> $DIR/suggest-builder-fn.rs:62:21 - | -LL | struct Bar; - | ---------- function or associated item `new` not found for this struct -... -LL | let _bar = Bar::new(); - | ^^^ function or associated item not found in `Bar` - | -note: if you're trying to build a new `Bar` consider using one of the following associated functions: - Bar::build - SomeMod::::build_public - --> $DIR/suggest-builder-fn.rs:23:5 - | -LL | fn build() -> Self { - | ^^^^^^^^^^^^^^^^^^ -... -LL | pub fn build_public() -> Self { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/resolve/suggest-constructor-cycle-error.rs b/tests/ui/resolve/suggest-constructor-cycle-error.rs deleted file mode 100644 index c23d6788eef..00000000000 --- a/tests/ui/resolve/suggest-constructor-cycle-error.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ aux-build:suggest-constructor-cycle-error.rs - -// Regression test for https://github.com/rust-lang/rust/issues/119625 - -extern crate suggest_constructor_cycle_error as a; - -const CONST_NAME: a::Uuid = a::Uuid(()); -//~^ ERROR: cannot initialize a tuple struct which contains private fields [E0423] - -fn main() {} diff --git a/tests/ui/resolve/suggest-constructor-cycle-error.stderr b/tests/ui/resolve/suggest-constructor-cycle-error.stderr deleted file mode 100644 index c6ec2465a43..00000000000 --- a/tests/ui/resolve/suggest-constructor-cycle-error.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0423]: cannot initialize a tuple struct which contains private fields - --> $DIR/suggest-constructor-cycle-error.rs:7:29 - | -LL | const CONST_NAME: a::Uuid = a::Uuid(()); - | ^^^^^^^ - | -note: constructor is not visible here due to private fields - --> $DIR/auxiliary/suggest-constructor-cycle-error.rs:2:21 - | -LL | pub struct Uuid(()); - | ^^ private field - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed b/tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed deleted file mode 100644 index 607c9af4927..00000000000 --- a/tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed +++ /dev/null @@ -1,16 +0,0 @@ -//@ run-rustfix -//@ compile-flags: -Aunused - -use y::z; -#[cfg(all())] -use y::Whatever; - -mod y { - pub(crate) fn z() {} - pub(crate) struct Whatever; -} - -fn main() { - z(); - //~^ ERROR cannot find function `z` in this scope -} diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.rs b/tests/ui/resolve/suggest-import-without-clobbering-attrs.rs deleted file mode 100644 index 6cc53fb1086..00000000000 --- a/tests/ui/resolve/suggest-import-without-clobbering-attrs.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-rustfix -//@ compile-flags: -Aunused - -#[cfg(all())] -use y::Whatever; - -mod y { - pub(crate) fn z() {} - pub(crate) struct Whatever; -} - -fn main() { - z(); - //~^ ERROR cannot find function `z` in this scope -} diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr b/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr deleted file mode 100644 index de65d695dd2..00000000000 --- a/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0425]: cannot find function `z` in this scope - --> $DIR/suggest-import-without-clobbering-attrs.rs:13:5 - | -LL | z(); - | ^ not found in this scope - | -help: consider importing this function - | -LL + use y::z; - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/suggest-path-for-tuple-struct.rs b/tests/ui/resolve/suggest-path-for-tuple-struct.rs deleted file mode 100644 index c8bc3e79fe2..00000000000 --- a/tests/ui/resolve/suggest-path-for-tuple-struct.rs +++ /dev/null @@ -1,26 +0,0 @@ -mod module { - pub struct SomeTupleStruct(u8); - pub struct SomeRegularStruct { - foo: u8 - } - - impl SomeTupleStruct { - pub fn new() -> Self { - Self(0) - } - } - impl SomeRegularStruct { - pub fn new() -> Self { - Self { foo: 0 } - } - } -} - -use module::{SomeTupleStruct, SomeRegularStruct}; - -fn main() { - let _ = SomeTupleStruct.new(); - //~^ ERROR expected value, found struct `SomeTupleStruct` - let _ = SomeRegularStruct.new(); - //~^ ERROR expected value, found struct `SomeRegularStruct` -} diff --git a/tests/ui/resolve/suggest-path-for-tuple-struct.stderr b/tests/ui/resolve/suggest-path-for-tuple-struct.stderr deleted file mode 100644 index 68a5b550978..00000000000 --- a/tests/ui/resolve/suggest-path-for-tuple-struct.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0423]: expected value, found struct `SomeTupleStruct` - --> $DIR/suggest-path-for-tuple-struct.rs:22:13 - | -LL | let _ = SomeTupleStruct.new(); - | ^^^^^^^^^^^^^^^ - | -help: use the path separator to refer to an item - | -LL - let _ = SomeTupleStruct.new(); -LL + let _ = SomeTupleStruct::new(); - | - -error[E0423]: expected value, found struct `SomeRegularStruct` - --> $DIR/suggest-path-for-tuple-struct.rs:24:13 - | -LL | let _ = SomeRegularStruct.new(); - | ^^^^^^^^^^^^^^^^^ - | -help: use the path separator to refer to an item - | -LL - let _ = SomeRegularStruct.new(); -LL + let _ = SomeRegularStruct::new(); - | - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.rs b/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.rs deleted file mode 100644 index d5d6b13d62c..00000000000 --- a/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.rs +++ /dev/null @@ -1,111 +0,0 @@ -// Beginners write `mod.item` when they should write `mod::item`. -// This tests that we suggest the latter when we encounter the former. - -pub mod a { - pub const I: i32 = 1; - - pub fn f() -> i32 { 2 } - - pub mod b { - pub const J: i32 = 3; - - pub fn g() -> i32 { 4 } - } -} - -fn h1() -> i32 { - a.I - //~^ ERROR expected value, found module `a` - //~| HELP use the path separator -} - -fn h2() -> i32 { - a.g() - //~^ ERROR expected value, found module `a` - //~| HELP use the path separator -} - -fn h3() -> i32 { - a.b.J - //~^ ERROR expected value, found module `a` - //~| HELP use the path separator -} - -fn h4() -> i32 { - a::b.J - //~^ ERROR expected value, found module `a::b` - //~| HELP a constant with a similar name exists - //~| HELP use the path separator -} - -fn h5() { - a.b.f(); - //~^ ERROR expected value, found module `a` - //~| HELP use the path separator - let v = Vec::new(); - v.push(a::b); - //~^ ERROR expected value, found module `a::b` - //~| HELP a constant with a similar name exists -} - -fn h6() -> i32 { - a::b.f() - //~^ ERROR expected value, found module `a::b` - //~| HELP a constant with a similar name exists - //~| HELP use the path separator -} - -fn h7() { - a::b - //~^ ERROR expected value, found module `a::b` - //~| HELP a constant with a similar name exists -} - -fn h8() -> i32 { - a::b() - //~^ ERROR expected function, found module `a::b` - //~| HELP a constant with a similar name exists -} - -macro_rules! module { - () => { - a - //~^ ERROR expected value, found module `a` - //~| ERROR expected value, found module `a` - }; -} - -macro_rules! create { - (method) => { - a.f() - //~^ ERROR expected value, found module `a` - //~| HELP use the path separator - }; - (field) => { - a.f - //~^ ERROR expected value, found module `a` - //~| HELP use the path separator - }; -} - -fn h9() { - // - // Note that if the receiver is a macro call, we do not want to suggest to replace - // `.` with `::` as that would be a syntax error. - // Since the receiver is a module and not a type, we cannot suggest to surround - // it with angle brackets. - // - - module!().g::<()>(); // no `help` here! - - module!().g; // no `help` here! - - // - // Ensure that the suggestion is shown for expressions inside of macro definitions. - // - - let _ = create!(method); - let _ = create!(field); -} - -fn main() {} diff --git a/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr deleted file mode 100644 index 5db943cd10d..00000000000 --- a/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr +++ /dev/null @@ -1,178 +0,0 @@ -error[E0423]: expected value, found module `a` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:17:5 - | -LL | a.I - | ^ - | -help: use the path separator to refer to an item - | -LL - a.I -LL + a::I - | - -error[E0423]: expected value, found module `a` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:23:5 - | -LL | a.g() - | ^ - | -help: use the path separator to refer to an item - | -LL - a.g() -LL + a::g() - | - -error[E0423]: expected value, found module `a` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:29:5 - | -LL | a.b.J - | ^ - | -help: use the path separator to refer to an item - | -LL - a.b.J -LL + a::b.J - | - -error[E0423]: expected value, found module `a::b` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:35:5 - | -LL | pub const I: i32 = 1; - | --------------------- similarly named constant `I` defined here -... -LL | a::b.J - | ^^^^ - | -help: use the path separator to refer to an item - | -LL - a::b.J -LL + a::b::J - | -help: a constant with a similar name exists - | -LL - a::b.J -LL + a::I.J - | - -error[E0423]: expected value, found module `a` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:42:5 - | -LL | a.b.f(); - | ^ - | -help: use the path separator to refer to an item - | -LL - a.b.f(); -LL + a::b.f(); - | - -error[E0423]: expected value, found module `a::b` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:46:12 - | -LL | pub const I: i32 = 1; - | --------------------- similarly named constant `I` defined here -... -LL | v.push(a::b); - | ^^^- - | | - | help: a constant with a similar name exists: `I` - -error[E0423]: expected value, found module `a::b` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:52:5 - | -LL | pub const I: i32 = 1; - | --------------------- similarly named constant `I` defined here -... -LL | a::b.f() - | ^^^^ - | -help: use the path separator to refer to an item - | -LL - a::b.f() -LL + a::b::f() - | -help: a constant with a similar name exists - | -LL - a::b.f() -LL + a::I.f() - | - -error[E0423]: expected value, found module `a::b` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:59:5 - | -LL | pub const I: i32 = 1; - | --------------------- similarly named constant `I` defined here -... -LL | a::b - | ^^^- - | | - | help: a constant with a similar name exists: `I` - -error[E0423]: expected function, found module `a::b` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:65:5 - | -LL | pub const I: i32 = 1; - | --------------------- similarly named constant `I` defined here -... -LL | a::b() - | ^^^- - | | - | help: a constant with a similar name exists: `I` - -error[E0423]: expected value, found module `a` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9 - | -LL | a - | ^ not a value -... -LL | module!().g::<()>(); // no `help` here! - | --------- in this macro invocation - | - = note: this error originates in the macro `module` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0423]: expected value, found module `a` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9 - | -LL | a - | ^ not a value -... -LL | module!().g; // no `help` here! - | --------- in this macro invocation - | - = note: this error originates in the macro `module` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0423]: expected value, found module `a` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:80:9 - | -LL | a.f() - | ^ -... -LL | let _ = create!(method); - | --------------- in this macro invocation - | - = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use the path separator to refer to an item - | -LL - a.f() -LL + a::f() - | - -error[E0423]: expected value, found module `a` - --> $DIR/suggest-path-instead-of-mod-dot-item.rs:85:9 - | -LL | a.f - | ^ -... -LL | let _ = create!(field); - | -------------- in this macro invocation - | - = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use the path separator to refer to an item - | -LL - a.f -LL + a::f - | - -error: aborting due to 13 previous errors - -For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/resolve/suggestions/auxiliary/suggest-constructor-cycle-error.rs b/tests/ui/resolve/suggestions/auxiliary/suggest-constructor-cycle-error.rs new file mode 100644 index 00000000000..8de68c38bc3 --- /dev/null +++ b/tests/ui/resolve/suggestions/auxiliary/suggest-constructor-cycle-error.rs @@ -0,0 +1,12 @@ +mod m { + pub struct Uuid(()); + + impl Uuid { + pub fn encode_buffer() -> [u8; LENGTH] { + [] + } + } + const LENGTH: usize = 0; +} + +pub use m::Uuid; diff --git a/tests/ui/resolve/suggestions/suggest-builder-fn.rs b/tests/ui/resolve/suggestions/suggest-builder-fn.rs new file mode 100644 index 00000000000..959675ef2c9 --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-builder-fn.rs @@ -0,0 +1,64 @@ +// Tests that we suggest the right alternatives when +// a builder method cannot be resolved + +use std::net::TcpStream; + +trait SomeTrait {} + +struct Foo { + v : T +} + +impl Foo { + // Should not be suggested if constraint on the impl not met + fn new() -> Self { + Self { v: T::default() } + } +} + +struct Bar; + +impl Bar { + // Should be suggested + fn build() -> Self { + Self {} + } + + // Method with self can't be a builder. + // Should not be suggested + fn build_with_self(&self) -> Self { + Self {} + } +} + +mod SomeMod { + use crate::Bar; + + impl Bar { + // Public method. Should be suggested + pub fn build_public() -> Self { + Self {} + } + + // Private method. Should not be suggested + fn build_private() -> Self { + Self {} + } + } +} + +fn main() { + // `new` not found on `TcpStream` and `connect` should be suggested + let _stream = TcpStream::new(); + //~^ ERROR no function or associated item named `new` found + + // Although `new` is found on `>` it should not be + // suggested because `u8` does not meet the `T: SomeTrait` constraint + let _foo = Foo::::new(); + //~^ ERROR the function or associated item `new` exists for struct `Foo`, but its trait bounds were not satisfied + + // Should suggest only `::build()` and `SomeMod::::build_public()`. + // Other methods should not suggested because they are private or are not a builder + let _bar = Bar::new(); + //~^ ERROR no function or associated item named `new` found +} diff --git a/tests/ui/resolve/suggestions/suggest-builder-fn.stderr b/tests/ui/resolve/suggestions/suggest-builder-fn.stderr new file mode 100644 index 00000000000..9c5eed35ccf --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-builder-fn.stderr @@ -0,0 +1,51 @@ +error[E0599]: no function or associated item named `new` found for struct `TcpStream` in the current scope + --> $DIR/suggest-builder-fn.rs:52:29 + | +LL | let _stream = TcpStream::new(); + | ^^^ function or associated item not found in `TcpStream` + | +note: if you're trying to build a new `TcpStream` consider using one of the following associated functions: + TcpStream::connect + TcpStream::connect_timeout + --> $SRC_DIR/std/src/net/tcp.rs:LL:COL + +error[E0599]: the function or associated item `new` exists for struct `Foo`, but its trait bounds were not satisfied + --> $DIR/suggest-builder-fn.rs:57:27 + | +LL | struct Foo { + | ------------- function or associated item `new` not found for this struct +... +LL | let _foo = Foo::::new(); + | ^^^ function or associated item cannot be called on `Foo` due to unsatisfied trait bounds + | +note: trait bound `u8: SomeTrait` was not satisfied + --> $DIR/suggest-builder-fn.rs:12:9 + | +LL | impl Foo { + | ^^^^^^^^^ ------ + | | + | unsatisfied trait bound introduced here + +error[E0599]: no function or associated item named `new` found for struct `Bar` in the current scope + --> $DIR/suggest-builder-fn.rs:62:21 + | +LL | struct Bar; + | ---------- function or associated item `new` not found for this struct +... +LL | let _bar = Bar::new(); + | ^^^ function or associated item not found in `Bar` + | +note: if you're trying to build a new `Bar` consider using one of the following associated functions: + Bar::build + SomeMod::::build_public + --> $DIR/suggest-builder-fn.rs:23:5 + | +LL | fn build() -> Self { + | ^^^^^^^^^^^^^^^^^^ +... +LL | pub fn build_public() -> Self { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.rs b/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.rs new file mode 100644 index 00000000000..c23d6788eef --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.rs @@ -0,0 +1,10 @@ +//@ aux-build:suggest-constructor-cycle-error.rs + +// Regression test for https://github.com/rust-lang/rust/issues/119625 + +extern crate suggest_constructor_cycle_error as a; + +const CONST_NAME: a::Uuid = a::Uuid(()); +//~^ ERROR: cannot initialize a tuple struct which contains private fields [E0423] + +fn main() {} diff --git a/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.stderr b/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.stderr new file mode 100644 index 00000000000..c6ec2465a43 --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.stderr @@ -0,0 +1,15 @@ +error[E0423]: cannot initialize a tuple struct which contains private fields + --> $DIR/suggest-constructor-cycle-error.rs:7:29 + | +LL | const CONST_NAME: a::Uuid = a::Uuid(()); + | ^^^^^^^ + | +note: constructor is not visible here due to private fields + --> $DIR/auxiliary/suggest-constructor-cycle-error.rs:2:21 + | +LL | pub struct Uuid(()); + | ^^ private field + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed new file mode 100644 index 00000000000..607c9af4927 --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed @@ -0,0 +1,16 @@ +//@ run-rustfix +//@ compile-flags: -Aunused + +use y::z; +#[cfg(all())] +use y::Whatever; + +mod y { + pub(crate) fn z() {} + pub(crate) struct Whatever; +} + +fn main() { + z(); + //~^ ERROR cannot find function `z` in this scope +} diff --git a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs new file mode 100644 index 00000000000..6cc53fb1086 --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs @@ -0,0 +1,15 @@ +//@ run-rustfix +//@ compile-flags: -Aunused + +#[cfg(all())] +use y::Whatever; + +mod y { + pub(crate) fn z() {} + pub(crate) struct Whatever; +} + +fn main() { + z(); + //~^ ERROR cannot find function `z` in this scope +} diff --git a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.stderr b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.stderr new file mode 100644 index 00000000000..de65d695dd2 --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.stderr @@ -0,0 +1,14 @@ +error[E0425]: cannot find function `z` in this scope + --> $DIR/suggest-import-without-clobbering-attrs.rs:13:5 + | +LL | z(); + | ^ not found in this scope + | +help: consider importing this function + | +LL + use y::z; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.rs b/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.rs new file mode 100644 index 00000000000..c8bc3e79fe2 --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.rs @@ -0,0 +1,26 @@ +mod module { + pub struct SomeTupleStruct(u8); + pub struct SomeRegularStruct { + foo: u8 + } + + impl SomeTupleStruct { + pub fn new() -> Self { + Self(0) + } + } + impl SomeRegularStruct { + pub fn new() -> Self { + Self { foo: 0 } + } + } +} + +use module::{SomeTupleStruct, SomeRegularStruct}; + +fn main() { + let _ = SomeTupleStruct.new(); + //~^ ERROR expected value, found struct `SomeTupleStruct` + let _ = SomeRegularStruct.new(); + //~^ ERROR expected value, found struct `SomeRegularStruct` +} diff --git a/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.stderr b/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.stderr new file mode 100644 index 00000000000..68a5b550978 --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.stderr @@ -0,0 +1,27 @@ +error[E0423]: expected value, found struct `SomeTupleStruct` + --> $DIR/suggest-path-for-tuple-struct.rs:22:13 + | +LL | let _ = SomeTupleStruct.new(); + | ^^^^^^^^^^^^^^^ + | +help: use the path separator to refer to an item + | +LL - let _ = SomeTupleStruct.new(); +LL + let _ = SomeTupleStruct::new(); + | + +error[E0423]: expected value, found struct `SomeRegularStruct` + --> $DIR/suggest-path-for-tuple-struct.rs:24:13 + | +LL | let _ = SomeRegularStruct.new(); + | ^^^^^^^^^^^^^^^^^ + | +help: use the path separator to refer to an item + | +LL - let _ = SomeRegularStruct.new(); +LL + let _ = SomeRegularStruct::new(); + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.rs b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.rs new file mode 100644 index 00000000000..d5d6b13d62c --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.rs @@ -0,0 +1,111 @@ +// Beginners write `mod.item` when they should write `mod::item`. +// This tests that we suggest the latter when we encounter the former. + +pub mod a { + pub const I: i32 = 1; + + pub fn f() -> i32 { 2 } + + pub mod b { + pub const J: i32 = 3; + + pub fn g() -> i32 { 4 } + } +} + +fn h1() -> i32 { + a.I + //~^ ERROR expected value, found module `a` + //~| HELP use the path separator +} + +fn h2() -> i32 { + a.g() + //~^ ERROR expected value, found module `a` + //~| HELP use the path separator +} + +fn h3() -> i32 { + a.b.J + //~^ ERROR expected value, found module `a` + //~| HELP use the path separator +} + +fn h4() -> i32 { + a::b.J + //~^ ERROR expected value, found module `a::b` + //~| HELP a constant with a similar name exists + //~| HELP use the path separator +} + +fn h5() { + a.b.f(); + //~^ ERROR expected value, found module `a` + //~| HELP use the path separator + let v = Vec::new(); + v.push(a::b); + //~^ ERROR expected value, found module `a::b` + //~| HELP a constant with a similar name exists +} + +fn h6() -> i32 { + a::b.f() + //~^ ERROR expected value, found module `a::b` + //~| HELP a constant with a similar name exists + //~| HELP use the path separator +} + +fn h7() { + a::b + //~^ ERROR expected value, found module `a::b` + //~| HELP a constant with a similar name exists +} + +fn h8() -> i32 { + a::b() + //~^ ERROR expected function, found module `a::b` + //~| HELP a constant with a similar name exists +} + +macro_rules! module { + () => { + a + //~^ ERROR expected value, found module `a` + //~| ERROR expected value, found module `a` + }; +} + +macro_rules! create { + (method) => { + a.f() + //~^ ERROR expected value, found module `a` + //~| HELP use the path separator + }; + (field) => { + a.f + //~^ ERROR expected value, found module `a` + //~| HELP use the path separator + }; +} + +fn h9() { + // + // Note that if the receiver is a macro call, we do not want to suggest to replace + // `.` with `::` as that would be a syntax error. + // Since the receiver is a module and not a type, we cannot suggest to surround + // it with angle brackets. + // + + module!().g::<()>(); // no `help` here! + + module!().g; // no `help` here! + + // + // Ensure that the suggestion is shown for expressions inside of macro definitions. + // + + let _ = create!(method); + let _ = create!(field); +} + +fn main() {} diff --git a/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr new file mode 100644 index 00000000000..5db943cd10d --- /dev/null +++ b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr @@ -0,0 +1,178 @@ +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:17:5 + | +LL | a.I + | ^ + | +help: use the path separator to refer to an item + | +LL - a.I +LL + a::I + | + +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:23:5 + | +LL | a.g() + | ^ + | +help: use the path separator to refer to an item + | +LL - a.g() +LL + a::g() + | + +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:29:5 + | +LL | a.b.J + | ^ + | +help: use the path separator to refer to an item + | +LL - a.b.J +LL + a::b.J + | + +error[E0423]: expected value, found module `a::b` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:35:5 + | +LL | pub const I: i32 = 1; + | --------------------- similarly named constant `I` defined here +... +LL | a::b.J + | ^^^^ + | +help: use the path separator to refer to an item + | +LL - a::b.J +LL + a::b::J + | +help: a constant with a similar name exists + | +LL - a::b.J +LL + a::I.J + | + +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:42:5 + | +LL | a.b.f(); + | ^ + | +help: use the path separator to refer to an item + | +LL - a.b.f(); +LL + a::b.f(); + | + +error[E0423]: expected value, found module `a::b` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:46:12 + | +LL | pub const I: i32 = 1; + | --------------------- similarly named constant `I` defined here +... +LL | v.push(a::b); + | ^^^- + | | + | help: a constant with a similar name exists: `I` + +error[E0423]: expected value, found module `a::b` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:52:5 + | +LL | pub const I: i32 = 1; + | --------------------- similarly named constant `I` defined here +... +LL | a::b.f() + | ^^^^ + | +help: use the path separator to refer to an item + | +LL - a::b.f() +LL + a::b::f() + | +help: a constant with a similar name exists + | +LL - a::b.f() +LL + a::I.f() + | + +error[E0423]: expected value, found module `a::b` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:59:5 + | +LL | pub const I: i32 = 1; + | --------------------- similarly named constant `I` defined here +... +LL | a::b + | ^^^- + | | + | help: a constant with a similar name exists: `I` + +error[E0423]: expected function, found module `a::b` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:65:5 + | +LL | pub const I: i32 = 1; + | --------------------- similarly named constant `I` defined here +... +LL | a::b() + | ^^^- + | | + | help: a constant with a similar name exists: `I` + +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9 + | +LL | a + | ^ not a value +... +LL | module!().g::<()>(); // no `help` here! + | --------- in this macro invocation + | + = note: this error originates in the macro `module` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9 + | +LL | a + | ^ not a value +... +LL | module!().g; // no `help` here! + | --------- in this macro invocation + | + = note: this error originates in the macro `module` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:80:9 + | +LL | a.f() + | ^ +... +LL | let _ = create!(method); + | --------------- in this macro invocation + | + = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - a.f() +LL + a::f() + | + +error[E0423]: expected value, found module `a` + --> $DIR/suggest-path-instead-of-mod-dot-item.rs:85:9 + | +LL | a.f + | ^ +... +LL | let _ = create!(field); + | -------------- in this macro invocation + | + = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - a.f +LL + a::f + | + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0423`. -- cgit 1.4.1-3-g733a5 From 000f038e9999ebdbaf3167c42dadc3db872a5d3f Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 29 Jun 2025 15:38:09 +0800 Subject: Add ui test resolve/false-self-in-macro-issue-143134.rs Signed-off-by: xizheyin --- tests/ui/resolve/false-self-in-macro-issue-143134.rs | 10 ++++++++++ tests/ui/resolve/false-self-in-macro-issue-143134.stderr | 12 ++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 tests/ui/resolve/false-self-in-macro-issue-143134.rs create mode 100644 tests/ui/resolve/false-self-in-macro-issue-143134.stderr diff --git a/tests/ui/resolve/false-self-in-macro-issue-143134.rs b/tests/ui/resolve/false-self-in-macro-issue-143134.rs new file mode 100644 index 00000000000..0983b8b3dc3 --- /dev/null +++ b/tests/ui/resolve/false-self-in-macro-issue-143134.rs @@ -0,0 +1,10 @@ +trait T { + fn f(self); + } + impl T for () { + fn f(self) { + let self = (); //~ ERROR expected unit struct, unit variant or constant, found local variable `self` + } +} + +fn main() {} diff --git a/tests/ui/resolve/false-self-in-macro-issue-143134.stderr b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr new file mode 100644 index 00000000000..43e77e183ae --- /dev/null +++ b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr @@ -0,0 +1,12 @@ +error[E0424]: expected unit struct, unit variant or constant, found local variable `self` + --> $DIR/false-self-in-macro-issue-143134.rs:6:13 + | +LL | / fn f(self) { +LL | | let self = (); + | | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed +LL | | } + | |_____- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0424`. -- cgit 1.4.1-3-g733a5 From 236b392904d234d9ec2968c55ae20132405a555d Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 29 Jun 2025 16:10:52 +0800 Subject: Return early when `self` resolve failure because of `let self = ...` Signed-off-by: xizheyin --- compiler/rustc_resolve/src/late/diagnostics.rs | 16 ++++++++++++---- tests/ui/error-codes/E0424.stderr | 2 -- tests/ui/resolve/false-self-in-macro-issue-143134.stderr | 7 ++----- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index e7b8c988cd4..0b78835326f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1183,15 +1183,23 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { _ => "`self` value is a keyword only available in methods with a `self` parameter", }, ); + + // using `let self` is wrong even if we're not in an associated method or if we're in a macro expansion. + // So, we should return early if we're in a pattern, see issue #143134. + if matches!(source, PathSource::Pat) { + return true; + } + let is_assoc_fn = self.self_type_is_available(); let self_from_macro = "a `self` parameter, but a macro invocation can only \ access identifiers it receives from parameters"; - if let Some((fn_kind, span)) = &self.diag_metadata.current_function { + if let Some((fn_kind, fn_span)) = &self.diag_metadata.current_function { // The current function has a `self` parameter, but we were unable to resolve // a reference to `self`. This can only happen if the `self` identifier we - // are resolving came from a different hygiene context. + // are resolving came from a different hygiene context or a variable binding. + // But variable binding error is returned early above. if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) { - err.span_label(*span, format!("this function has {self_from_macro}")); + err.span_label(*fn_span, format!("this function has {self_from_macro}")); } else { let doesnt = if is_assoc_fn { let (span, sugg) = fn_kind @@ -1204,7 +1212,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // This avoids placing the suggestion into the visibility specifier. let span = fn_kind .ident() - .map_or(*span, |ident| span.with_lo(ident.span.hi())); + .map_or(*fn_span, |ident| fn_span.with_lo(ident.span.hi())); ( self.r .tcx diff --git a/tests/ui/error-codes/E0424.stderr b/tests/ui/error-codes/E0424.stderr index d02da3e4ecb..831a070bf6c 100644 --- a/tests/ui/error-codes/E0424.stderr +++ b/tests/ui/error-codes/E0424.stderr @@ -40,8 +40,6 @@ LL | fn qux(&self) { error[E0424]: expected unit struct, unit variant or constant, found module `self` --> $DIR/E0424.rs:20:9 | -LL | fn main () { - | ---- this function can't have a `self` parameter LL | let self = "self"; | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed diff --git a/tests/ui/resolve/false-self-in-macro-issue-143134.stderr b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr index 43e77e183ae..48c979575ea 100644 --- a/tests/ui/resolve/false-self-in-macro-issue-143134.stderr +++ b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr @@ -1,11 +1,8 @@ error[E0424]: expected unit struct, unit variant or constant, found local variable `self` --> $DIR/false-self-in-macro-issue-143134.rs:6:13 | -LL | / fn f(self) { -LL | | let self = (); - | | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed -LL | | } - | |_____- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters +LL | let self = (); + | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed error: aborting due to 1 previous error -- cgit 1.4.1-3-g733a5 From 1a1b52acbf44f55f7458dd38b260479843fe3810 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 4 Jul 2025 11:33:36 +0000 Subject: clippy fix: indentation --- library/core/src/alloc/layout.rs | 4 ++-- library/core/src/cell.rs | 28 ++++++++++++++-------------- library/core/src/error.rs | 24 ++++++++++++------------ library/core/src/fmt/mod.rs | 14 +++++++------- library/core/src/marker.rs | 4 ++-- library/core/src/ops/drop.rs | 2 +- library/core/src/option.rs | 1 + library/core/src/pin.rs | 16 ++++++++-------- 8 files changed, 47 insertions(+), 46 deletions(-) diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 380f67f91f9..49275975f04 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -61,8 +61,8 @@ impl Layout { /// * `align` must be a power of two, /// /// * `size`, when rounded up to the nearest multiple of `align`, - /// must not overflow `isize` (i.e., the rounded value must be - /// less than or equal to `isize::MAX`). + /// must not overflow `isize` (i.e., the rounded value must be + /// less than or equal to `isize::MAX`). #[stable(feature = "alloc_layout", since = "1.28.0")] #[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")] #[inline] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 7ce03e3d831..2cd5c19bf4e 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1941,21 +1941,21 @@ impl fmt::Display for RefMut<'_, T> { /// The precise Rust aliasing rules are somewhat in flux, but the main points are not contentious: /// /// - If you create a safe reference with lifetime `'a` (either a `&T` or `&mut T` reference), then -/// you must not access the data in any way that contradicts that reference for the remainder of -/// `'a`. For example, this means that if you take the `*mut T` from an `UnsafeCell` and cast it -/// to an `&T`, then the data in `T` must remain immutable (modulo any `UnsafeCell` data found -/// within `T`, of course) until that reference's lifetime expires. Similarly, if you create a `&mut -/// T` reference that is released to safe code, then you must not access the data within the -/// `UnsafeCell` until that reference expires. +/// you must not access the data in any way that contradicts that reference for the remainder of +/// `'a`. For example, this means that if you take the `*mut T` from an `UnsafeCell` and cast it +/// to an `&T`, then the data in `T` must remain immutable (modulo any `UnsafeCell` data found +/// within `T`, of course) until that reference's lifetime expires. Similarly, if you create a +/// `&mut T` reference that is released to safe code, then you must not access the data within the +/// `UnsafeCell` until that reference expires. /// /// - For both `&T` without `UnsafeCell<_>` and `&mut T`, you must also not deallocate the data -/// until the reference expires. As a special exception, given an `&T`, any part of it that is -/// inside an `UnsafeCell<_>` may be deallocated during the lifetime of the reference, after the -/// last time the reference is used (dereferenced or reborrowed). Since you cannot deallocate a part -/// of what a reference points to, this means the memory an `&T` points to can be deallocated only if -/// *every part of it* (including padding) is inside an `UnsafeCell`. +/// until the reference expires. As a special exception, given an `&T`, any part of it that is +/// inside an `UnsafeCell<_>` may be deallocated during the lifetime of the reference, after the +/// last time the reference is used (dereferenced or reborrowed). Since you cannot deallocate a part +/// of what a reference points to, this means the memory an `&T` points to can be deallocated only if +/// *every part of it* (including padding) is inside an `UnsafeCell`. /// -/// However, whenever a `&UnsafeCell` is constructed or dereferenced, it must still point to +/// However, whenever a `&UnsafeCell` is constructed or dereferenced, it must still point to /// live memory and the compiler is allowed to insert spurious reads if it can prove that this /// memory has not yet been deallocated. /// @@ -1963,10 +1963,10 @@ impl fmt::Display for RefMut<'_, T> { /// for single-threaded code: /// /// 1. A `&T` reference can be released to safe code and there it can co-exist with other `&T` -/// references, but not with a `&mut T` +/// references, but not with a `&mut T` /// /// 2. A `&mut T` reference may be released to safe code provided neither other `&mut T` nor `&T` -/// co-exist with it. A `&mut T` must always be unique. +/// co-exist with it. A `&mut T` must always be unique. /// /// Note that whilst mutating the contents of an `&UnsafeCell` (even while other /// `&UnsafeCell` references alias the cell) is diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 7f5c6ac42bc..88e633c9eef 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -447,28 +447,28 @@ where /// separated by API boundaries: /// /// * Consumer - the consumer requests objects using a Request instance; eg a crate that offers -/// fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`. +/// fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`. /// /// * Producer - the producer provides objects when requested via Request; eg. a library with an -/// an `Error` implementation that automatically captures backtraces at the time instances are -/// created. +/// an `Error` implementation that automatically captures backtraces at the time instances are +/// created. /// /// The consumer only needs to know where to submit their request and are expected to handle the /// request not being fulfilled by the use of `Option` in the responses offered by the producer. /// /// * A Producer initializes the value of one of its fields of a specific type. (or is otherwise -/// prepared to generate a value requested). eg, `backtrace::Backtrace` or -/// `std::backtrace::Backtrace` +/// prepared to generate a value requested). eg, `backtrace::Backtrace` or +/// `std::backtrace::Backtrace` /// * A Consumer requests an object of a specific type (say `std::backtrace::Backtrace`). In the -/// case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and -/// `request_value` to simplify obtaining an `Option` for a given type. +/// case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and +/// `request_value` to simplify obtaining an `Option` for a given type. /// * The Producer, when requested, populates the given Request object which is given as a mutable -/// reference. +/// reference. /// * The Consumer extracts a value or reference to the requested type from the `Request` object -/// wrapped in an `Option`; in the case of `dyn Error` the aforementioned `request_ref` and ` -/// request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at -/// all (but `Error` implementors do). The `None` case of the `Option` suggests only that the -/// Producer cannot currently offer an instance of the requested type, not it can't or never will. +/// wrapped in an `Option`; in the case of `dyn Error` the aforementioned `request_ref` and ` +/// request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at +/// all (but `Error` implementors do). The `None` case of the `Option` suggests only that the +/// Producer cannot currently offer an instance of the requested type, not it can't or never will. /// /// # Examples /// diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index c593737af8a..223b50dda09 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -349,10 +349,10 @@ impl FormattingOptions { /// Sets or removes the sign (the `+` or the `-` flag). /// /// - `+`: This is intended for numeric types and indicates that the sign - /// should always be printed. By default only the negative sign of signed - /// values is printed, and the sign of positive or unsigned values is - /// omitted. This flag indicates that the correct sign (+ or -) should - /// always be printed. + /// should always be printed. By default only the negative sign of signed + /// values is printed, and the sign of positive or unsigned values is + /// omitted. This flag indicates that the correct sign (+ or -) should + /// always be printed. /// - `-`: Currently not used #[unstable(feature = "formatting_options", issue = "118117")] pub fn sign(&mut self, sign: Option) -> &mut Self { @@ -439,9 +439,9 @@ impl FormattingOptions { /// Sets or removes the precision. /// /// - For non-numeric types, this can be considered a “maximum width”. If - /// the resulting string is longer than this width, then it is truncated - /// down to this many characters and that truncated value is emitted with - /// proper fill, alignment and width if those parameters are set. + /// the resulting string is longer than this width, then it is truncated + /// down to this many characters and that truncated value is emitted with + /// proper fill, alignment and width if those parameters are set. /// - For integral types, this is ignored. /// - For floating-point types, this indicates how many digits after the /// decimal point should be printed. diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 67f95a02af3..0f9a1ff02d1 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -211,8 +211,8 @@ pub trait PointeeSized { /// - The type is sized. /// - The type outlives `'a`. /// - Structs `Foo<..., T1, ..., Tn, ...>` implement `Unsize>` -/// where any number of (type and const) parameters may be changed if all of these conditions -/// are met: +/// where any number of (type and const) parameters may be changed if all of these conditions +/// are met: /// - Only the last field of `Foo` has a type involving the parameters `T1`, ..., `Tn`. /// - All other parameters of the struct are equal. /// - `Field: Unsize>`, where `Field<...>` stands for the actual diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs index 5d040804a8d..bbef7023207 100644 --- a/library/core/src/ops/drop.rs +++ b/library/core/src/ops/drop.rs @@ -11,7 +11,7 @@ /// This destructor consists of two components: /// - A call to `Drop::drop` for that value, if this special `Drop` trait is implemented for its type. /// - The automatically generated "drop glue" which recursively calls the destructors -/// of all the fields of this value. +/// of all the fields of this value. /// /// As Rust automatically calls the destructors of all contained fields, /// you don't have to implement `Drop` in most cases. But there are some cases where diff --git a/library/core/src/option.rs b/library/core/src/option.rs index f2a1e901188..f83a73fa566 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -125,6 +125,7 @@ //! `Option::::None` //! - `transmute::<_, [u8; size_of::()]>(Option::::None)` is sound and produces //! `[0u8; size_of::()]` +//! //! These cases are identified by the second column: //! //! | `T` | Transmuting between `[0u8; size_of::()]` and `Option::::None` sound? | diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 3ca6feb679b..14bf7ba9015 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -137,10 +137,10 @@ //! 2. An operation causes the value to depend on its own address not changing //! * e.g. calling [`poll`] for the first time on the produced [`Future`] //! 3. Further pieces of the safe interface of the type use internal [`unsafe`] operations which -//! assume that the address of the value is stable +//! assume that the address of the value is stable //! * e.g. subsequent calls to [`poll`] //! 4. Before the value is invalidated (e.g. deallocated), it is *dropped*, giving it a chance to -//! notify anything with pointers to itself that those pointers will be invalidated +//! notify anything with pointers to itself that those pointers will be invalidated //! * e.g. [`drop`]ping the [`Future`] [^pin-drop-future] //! //! There are two possible ways to ensure the invariants required for 2. and 3. above (which @@ -148,8 +148,8 @@ //! //! 1. Have the value detect when it is moved and update all the pointers that point to itself. //! 2. Guarantee that the address of the value does not change (and that memory is not re-used -//! for anything else) during the time that the pointers to it are expected to be valid to -//! dereference. +//! for anything else) during the time that the pointers to it are expected to be valid to +//! dereference. //! //! Since, as we discussed, Rust can move values without notifying them that they have moved, the //! first option is ruled out. @@ -160,11 +160,11 @@ //! be able to enforce this invariant in Rust: //! //! 1. Offer a wholly `unsafe` API to interact with the object, thus requiring every caller to -//! uphold the invariant themselves +//! uphold the invariant themselves //! 2. Store the value that must not be moved behind a carefully managed pointer internal to -//! the object +//! the object //! 3. Leverage the type system to encode and enforce this invariant by presenting a restricted -//! API surface to interact with *any* object that requires these invariants +//! API surface to interact with *any* object that requires these invariants //! //! The first option is quite obviously undesirable, as the [`unsafe`]ty of the interface will //! become viral throughout all code that interacts with the object. @@ -530,7 +530,7 @@ //! but it also implies that, //! //! 2. The memory location that stores the value must not get invalidated or otherwise repurposed -//! during the lifespan of the pinned value until its [`drop`] returns or panics +//! during the lifespan of the pinned value until its [`drop`] returns or panics //! //! This point is subtle but required for intrusive data structures to be implemented soundly. //! -- cgit 1.4.1-3-g733a5 From c4d9c0f248f05542024ad55a52774ea84406db81 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 5 Jul 2025 01:46:49 -0500 Subject: tests: Use `cfg_target_has_reliable_f16_f128` `conv-bits-runtime-const` gates `f16` and `f128` tests behind `x86_64`, but this isn't always accurate. In particular, x86 `MinGW` has an ABI bug [1] which means things work when linked to our Rust math libraries but don't work with host libraries. RUST-143405 slightly adjusts which targets we provide `f16` and `f128` symbols for and effectively removes MinGW from that list, meaning host libraries start getting linked, meaning `f16` and `f128` tests start to fail. Account for this by changing the gates in one such test to `cfg(target_has_reliable_{f16,f128})` which is the way we should be gating all behavior related to the types going forward. `rustfmt` also seems to have formatted the macros which is fine. [1]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054 --- tests/ui/float/conv-bits-runtime-const.rs | 43 ++++++++++++++----------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/tests/ui/float/conv-bits-runtime-const.rs b/tests/ui/float/conv-bits-runtime-const.rs index 3046728fe66..1373001b74d 100644 --- a/tests/ui/float/conv-bits-runtime-const.rs +++ b/tests/ui/float/conv-bits-runtime-const.rs @@ -5,25 +5,24 @@ #![feature(f16)] #![feature(f128)] +#![feature(cfg_target_has_reliable_f16_f128)] #![allow(unused_macro_rules)] +// expect the unexpected (`target_has_reliable_*` are not "known" configs since they are unstable) +#![expect(unexpected_cfgs)] use std::hint::black_box; macro_rules! both_assert { - ($a:expr) => { - { - const _: () = assert!($a); - // `black_box` prevents promotion, and MIR opts are disabled above, so this is truly - // going through LLVM. - assert!(black_box($a)); - } - }; - ($a:expr, $b:expr) => { - { - const _: () = assert!($a == $b); - assert_eq!(black_box($a), black_box($b)); - } - }; + ($a:expr) => {{ + const _: () = assert!($a); + // `black_box` prevents promotion, and MIR opts are disabled above, so this is truly + // going through LLVM. + assert!(black_box($a)); + }}; + ($a:expr, $b:expr) => {{ + const _: () = assert!($a == $b); + assert_eq!(black_box($a), black_box($b)); + }}; } fn has_broken_floats() -> bool { @@ -31,8 +30,8 @@ fn has_broken_floats() -> bool { cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) } -#[cfg(target_arch = "x86_64")] -fn f16(){ +#[cfg(target_has_reliable_f16)] +fn f16() { both_assert!((1f16).to_bits(), 0x3c00); both_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00); both_assert!((12.5f16).to_bits(), 0x4a40); @@ -122,7 +121,7 @@ fn f64() { } } -#[cfg(target_arch = "x86_64")] +#[cfg(target_has_reliable_f128)] fn f128() { both_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000); both_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000); @@ -154,12 +153,10 @@ fn f128() { } fn main() { + #[cfg(target_has_reliable_f16)] + f16(); f32(); f64(); - - #[cfg(target_arch = "x86_64")] - { - f16(); - f128(); - } + #[cfg(target_has_reliable_f128)] + f128(); } -- cgit 1.4.1-3-g733a5 From 995eeeb54cda2f3c7884e14a82bbe1f279143388 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 5 Jul 2025 17:47:28 +0000 Subject: Don't call predicates_of on a dummy obligation cause's body id --- .../src/error_reporting/traits/ambiguity.rs | 33 +++++++++++++--------- .../ambiguity-in-dropck-err-reporting.rs | 18 ++++++++++++ .../ambiguity-in-dropck-err-reporting.stderr | 19 +++++++++++++ 3 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs create mode 100644 tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 39f115ce0cd..a8ba1baf6b9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -4,7 +4,7 @@ use rustc_errors::{Applicability, Diag, E0283, E0284, E0790, MultiSpan, struct_s use rustc_hir as hir; use rustc_hir::LangItem; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_hir::intravisit::Visitor as _; use rustc_infer::infer::{BoundRegionConversionTime, InferCtxt}; use rustc_infer::traits::util::elaborate; @@ -128,19 +128,26 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( }, ); - let predicates = - tcx.predicates_of(obligation.cause.body_id.to_def_id()).instantiate_identity(tcx); - for (pred, span) in elaborate(tcx, predicates.into_iter()) { - let kind = pred.kind(); - if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder() - && param_env_candidate_may_apply(kind.rebind(trait_pred)) - { - if kind.rebind(trait_pred.trait_ref) - == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id())) + // If our `body_id` has been set (and isn't just from a dummy obligation cause), + // then try to look for a param-env clause that would apply. The way we compute + // this is somewhat manual, since we need the spans, so we elaborate this directly + // from `predicates_of` rather than actually looking at the param-env which + // otherwise would be more appropriate. + let body_id = obligation.cause.body_id; + if body_id != CRATE_DEF_ID { + let predicates = tcx.predicates_of(body_id.to_def_id()).instantiate_identity(tcx); + for (pred, span) in elaborate(tcx, predicates.into_iter()) { + let kind = pred.kind(); + if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder() + && param_env_candidate_may_apply(kind.rebind(trait_pred)) { - ambiguities.push(CandidateSource::ParamEnv(tcx.def_span(trait_pred.def_id()))) - } else { - ambiguities.push(CandidateSource::ParamEnv(span)) + if kind.rebind(trait_pred.trait_ref) + == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id())) + { + ambiguities.push(CandidateSource::ParamEnv(tcx.def_span(trait_pred.def_id()))) + } else { + ambiguities.push(CandidateSource::ParamEnv(span)) + } } } } diff --git a/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs new file mode 100644 index 00000000000..ad313823fe4 --- /dev/null +++ b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs @@ -0,0 +1,18 @@ +// Regression test for #143481, where we were calling `predicates_of` on +// a Crate HIR node because we were using a dummy obligation cause's body id +// without checking that it was meaningful first. + +trait Role { + type Inner; +} +struct HandshakeCallback(C); +impl Role for HandshakeCallback { + //~^ ERROR missing generics + type Inner = usize; +} +struct Handshake(R::Inner); +fn accept() -> Handshake> { + todo!() +} + +fn main() {} diff --git a/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr new file mode 100644 index 00000000000..17ace03e891 --- /dev/null +++ b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr @@ -0,0 +1,19 @@ +error[E0107]: missing generics for struct `HandshakeCallback` + --> $DIR/ambiguity-in-dropck-err-reporting.rs:9:25 + | +LL | impl Role for HandshakeCallback { + | ^^^^^^^^^^^^^^^^^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `C` + --> $DIR/ambiguity-in-dropck-err-reporting.rs:8:8 + | +LL | struct HandshakeCallback(C); + | ^^^^^^^^^^^^^^^^^ - +help: add missing generic argument + | +LL | impl Role for HandshakeCallback { + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. -- cgit 1.4.1-3-g733a5 From b63f920ccf6e148547aea4c0fd045c4536aac483 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 6 Jul 2025 17:30:09 +0000 Subject: More carefully consider span context when suggesting remove &mut --- .../src/error_reporting/traits/suggestions.rs | 13 ++++++++----- tests/ui/suggestions/suggest-remove-refs-6.rs | 12 ++++++++++++ tests/ui/suggestions/suggest-remove-refs-6.stderr | 22 ++++++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 tests/ui/suggestions/suggest-remove-refs-6.rs create mode 100644 tests/ui/suggestions/suggest-remove-refs-6.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 362052e9fdb..1dc1588842f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1511,12 +1511,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { 'outer: loop { while let hir::ExprKind::AddrOf(_, _, borrowed) = expr.kind { count += 1; - let span = if expr.span.eq_ctxt(borrowed.span) { - expr.span.until(borrowed.span) - } else { - expr.span.with_hi(expr.span.lo() + BytePos(1)) - }; + let span = + if let Some(borrowed_span) = borrowed.span.find_ancestor_inside(expr.span) { + expr.span.until(borrowed_span) + } else { + break 'outer; + }; + // Double check that the span we extracted actually corresponds to a borrow, + // rather than some macro garbage. match self.tcx.sess.source_map().span_to_snippet(span) { Ok(snippet) if snippet.starts_with("&") => {} _ => break 'outer, diff --git a/tests/ui/suggestions/suggest-remove-refs-6.rs b/tests/ui/suggestions/suggest-remove-refs-6.rs new file mode 100644 index 00000000000..0d06aed4806 --- /dev/null +++ b/tests/ui/suggestions/suggest-remove-refs-6.rs @@ -0,0 +1,12 @@ +// Regression test for #143523. + +trait Trait {} + +impl Trait for Vec {} + +fn foo(_: impl Trait) {} + +fn main() { + foo(&mut vec![1]); + //~^ ERROR the trait bound `&mut Vec<{integer}>: Trait` is not satisfied +} diff --git a/tests/ui/suggestions/suggest-remove-refs-6.stderr b/tests/ui/suggestions/suggest-remove-refs-6.stderr new file mode 100644 index 00000000000..bdc5a8a9049 --- /dev/null +++ b/tests/ui/suggestions/suggest-remove-refs-6.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `&mut Vec<{integer}>: Trait` is not satisfied + --> $DIR/suggest-remove-refs-6.rs:10:9 + | +LL | foo(&mut vec![1]); + | --- ^^^^^^^^^^^^ the trait `Trait` is not implemented for `&mut Vec<{integer}>` + | | + | required by a bound introduced by this call + | +note: required by a bound in `foo` + --> $DIR/suggest-remove-refs-6.rs:7:16 + | +LL | fn foo(_: impl Trait) {} + | ^^^^^ required by this bound in `foo` +help: consider removing the leading `&`-reference + | +LL - foo(&mut vec![1]); +LL + foo(vec![1]); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. -- cgit 1.4.1-3-g733a5 From b4e68e212ece6896ea574c6345e14d4350c5c517 Mon Sep 17 00:00:00 2001 From: Bastian Kersting Date: Wed, 2 Jul 2025 20:33:28 +0300 Subject: Respect endianness correctly in CheckEnums test suite The endianness can change the test expectation for the enum check. This change is fixing the failing tests on big endian by changing the tests so that they behave the same as on little endian. --- tests/ui/mir/enum/convert_non_enum_break.rs | 20 --------------- tests/ui/mir/enum/convert_non_enum_niche_break.rs | 27 -------------------- tests/ui/mir/enum/convert_non_enum_niche_ok.rs | 29 ---------------------- tests/ui/mir/enum/convert_non_enum_ok.rs | 20 --------------- tests/ui/mir/enum/convert_non_integer_break.rs | 19 ++++++++++++++ .../ui/mir/enum/convert_non_integer_niche_break.rs | 27 ++++++++++++++++++++ tests/ui/mir/enum/convert_non_integer_niche_ok.rs | 29 ++++++++++++++++++++++ tests/ui/mir/enum/convert_non_integer_ok.rs | 19 ++++++++++++++ tests/ui/mir/enum/niche_option_tuple_break.rs | 11 ++++---- tests/ui/mir/enum/with_niche_int_break.rs | 4 +-- 10 files changed, 102 insertions(+), 103 deletions(-) delete mode 100644 tests/ui/mir/enum/convert_non_enum_break.rs delete mode 100644 tests/ui/mir/enum/convert_non_enum_niche_break.rs delete mode 100644 tests/ui/mir/enum/convert_non_enum_niche_ok.rs delete mode 100644 tests/ui/mir/enum/convert_non_enum_ok.rs create mode 100644 tests/ui/mir/enum/convert_non_integer_break.rs create mode 100644 tests/ui/mir/enum/convert_non_integer_niche_break.rs create mode 100644 tests/ui/mir/enum/convert_non_integer_niche_ok.rs create mode 100644 tests/ui/mir/enum/convert_non_integer_ok.rs diff --git a/tests/ui/mir/enum/convert_non_enum_break.rs b/tests/ui/mir/enum/convert_non_enum_break.rs deleted file mode 100644 index de062c39907..00000000000 --- a/tests/ui/mir/enum/convert_non_enum_break.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ run-fail -//@ compile-flags: -C debug-assertions -//@ error-pattern: trying to construct an enum from an invalid value 0x10000 - -#[allow(dead_code)] -#[repr(u32)] -enum Foo { - A, - B, -} - -#[allow(dead_code)] -struct Bar { - a: u16, - b: u16, -} - -fn main() { - let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 0, b: 1 }) }; -} diff --git a/tests/ui/mir/enum/convert_non_enum_niche_break.rs b/tests/ui/mir/enum/convert_non_enum_niche_break.rs deleted file mode 100644 index 9ff4849c5b1..00000000000 --- a/tests/ui/mir/enum/convert_non_enum_niche_break.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ run-fail -//@ compile-flags: -C debug-assertions -//@ error-pattern: trying to construct an enum from an invalid value 0x5 - -#[allow(dead_code)] -#[repr(u16)] -enum Mix { - A, - B(u16), -} - -#[allow(dead_code)] -enum Nested { - C(Mix), - D, - E, -} - -#[allow(dead_code)] -struct Bar { - a: u16, - b: u16, -} - -fn main() { - let _val: Nested = unsafe { std::mem::transmute::<_, Nested>(Bar { a: 5, b: 0 }) }; -} diff --git a/tests/ui/mir/enum/convert_non_enum_niche_ok.rs b/tests/ui/mir/enum/convert_non_enum_niche_ok.rs deleted file mode 100644 index 24027da5458..00000000000 --- a/tests/ui/mir/enum/convert_non_enum_niche_ok.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ run-pass -//@ compile-flags: -C debug-assertions - -#[allow(dead_code)] -#[repr(u16)] -enum Mix { - A, - B(u16), -} - -#[allow(dead_code)] -enum Nested { - C(Mix), - D, - E, -} - -#[allow(dead_code)] -struct Bar { - a: u16, - b: u16, -} - -fn main() { - let _val: Nested = unsafe { std::mem::transmute::<_, Nested>(Bar { a: 0, b: 0 }) }; - let _val: Nested = unsafe { std::mem::transmute::<_, Nested>(Bar { a: 1, b: 0 }) }; - let _val: Nested = unsafe { std::mem::transmute::<_, Nested>(Bar { a: 2, b: 0 }) }; - let _val: Nested = unsafe { std::mem::transmute::<_, Nested>(Bar { a: 3, b: 0 }) }; -} diff --git a/tests/ui/mir/enum/convert_non_enum_ok.rs b/tests/ui/mir/enum/convert_non_enum_ok.rs deleted file mode 100644 index 37fc64342ca..00000000000 --- a/tests/ui/mir/enum/convert_non_enum_ok.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ run-pass -//@ compile-flags: -C debug-assertions - -#[allow(dead_code)] -#[repr(u32)] -enum Foo { - A, - B, -} - -#[allow(dead_code)] -struct Bar { - a: u16, - b: u16, -} - -fn main() { - let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 0, b: 0 }) }; - let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 1, b: 0 }) }; -} diff --git a/tests/ui/mir/enum/convert_non_integer_break.rs b/tests/ui/mir/enum/convert_non_integer_break.rs new file mode 100644 index 00000000000..29795190bf6 --- /dev/null +++ b/tests/ui/mir/enum/convert_non_integer_break.rs @@ -0,0 +1,19 @@ +//@ run-fail +//@ compile-flags: -C debug-assertions +//@ error-pattern: trying to construct an enum from an invalid value + +#[allow(dead_code)] +#[repr(u32)] +enum Foo { + A, + B, +} + +#[allow(dead_code)] +struct Bar { + a: u32, +} + +fn main() { + let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 3 }) }; +} diff --git a/tests/ui/mir/enum/convert_non_integer_niche_break.rs b/tests/ui/mir/enum/convert_non_integer_niche_break.rs new file mode 100644 index 00000000000..9ff4849c5b1 --- /dev/null +++ b/tests/ui/mir/enum/convert_non_integer_niche_break.rs @@ -0,0 +1,27 @@ +//@ run-fail +//@ compile-flags: -C debug-assertions +//@ error-pattern: trying to construct an enum from an invalid value 0x5 + +#[allow(dead_code)] +#[repr(u16)] +enum Mix { + A, + B(u16), +} + +#[allow(dead_code)] +enum Nested { + C(Mix), + D, + E, +} + +#[allow(dead_code)] +struct Bar { + a: u16, + b: u16, +} + +fn main() { + let _val: Nested = unsafe { std::mem::transmute::<_, Nested>(Bar { a: 5, b: 0 }) }; +} diff --git a/tests/ui/mir/enum/convert_non_integer_niche_ok.rs b/tests/ui/mir/enum/convert_non_integer_niche_ok.rs new file mode 100644 index 00000000000..24027da5458 --- /dev/null +++ b/tests/ui/mir/enum/convert_non_integer_niche_ok.rs @@ -0,0 +1,29 @@ +//@ run-pass +//@ compile-flags: -C debug-assertions + +#[allow(dead_code)] +#[repr(u16)] +enum Mix { + A, + B(u16), +} + +#[allow(dead_code)] +enum Nested { + C(Mix), + D, + E, +} + +#[allow(dead_code)] +struct Bar { + a: u16, + b: u16, +} + +fn main() { + let _val: Nested = unsafe { std::mem::transmute::<_, Nested>(Bar { a: 0, b: 0 }) }; + let _val: Nested = unsafe { std::mem::transmute::<_, Nested>(Bar { a: 1, b: 0 }) }; + let _val: Nested = unsafe { std::mem::transmute::<_, Nested>(Bar { a: 2, b: 0 }) }; + let _val: Nested = unsafe { std::mem::transmute::<_, Nested>(Bar { a: 3, b: 0 }) }; +} diff --git a/tests/ui/mir/enum/convert_non_integer_ok.rs b/tests/ui/mir/enum/convert_non_integer_ok.rs new file mode 100644 index 00000000000..c9831531386 --- /dev/null +++ b/tests/ui/mir/enum/convert_non_integer_ok.rs @@ -0,0 +1,19 @@ +//@ run-pass +//@ compile-flags: -C debug-assertions + +#[allow(dead_code)] +#[repr(u32)] +enum Foo { + A, + B, +} + +#[allow(dead_code)] +struct Bar { + a: u32, +} + +fn main() { + let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 0 }) }; + let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 1 }) }; +} diff --git a/tests/ui/mir/enum/niche_option_tuple_break.rs b/tests/ui/mir/enum/niche_option_tuple_break.rs index 43eef3a4cc5..affdc4784a3 100644 --- a/tests/ui/mir/enum/niche_option_tuple_break.rs +++ b/tests/ui/mir/enum/niche_option_tuple_break.rs @@ -1,8 +1,9 @@ //@ run-fail //@ compile-flags: -C debug-assertions -//@ error-pattern: trying to construct an enum from an invalid value 0x3 +//@ error-pattern: trying to construct an enum from an invalid value #[allow(dead_code)] +#[repr(u32)] enum Foo { A, B, @@ -10,11 +11,11 @@ enum Foo { #[allow(dead_code)] struct Bar { - a: usize, - b: usize, + a: u32, + b: u32, } fn main() { - let _val: Option<(usize, Foo)> = - unsafe { std::mem::transmute::<_, Option<(usize, Foo)>>(Bar { a: 3, b: 3 }) }; + let _val: Option<(u32, Foo)> = + unsafe { std::mem::transmute::<_, Option<(u32, Foo)>>(Bar { a: 3, b: 3 }) }; } diff --git a/tests/ui/mir/enum/with_niche_int_break.rs b/tests/ui/mir/enum/with_niche_int_break.rs index 0ec60a33564..6a97eaa8f4f 100644 --- a/tests/ui/mir/enum/with_niche_int_break.rs +++ b/tests/ui/mir/enum/with_niche_int_break.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -C debug-assertions -//@ error-pattern: trying to construct an enum from an invalid value 0x4 +//@ error-pattern: trying to construct an enum from an invalid value #[allow(dead_code)] #[repr(u16)] @@ -17,5 +17,5 @@ enum Nested { } fn main() { - let _val: Nested = unsafe { std::mem::transmute::(4) }; + let _val: Nested = unsafe { std::mem::transmute::(u32::MAX) }; } -- cgit 1.4.1-3-g733a5 From e2891c0fb9060f80e6aa24e0dc0a9c43b0861b8f Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 7 Jul 2025 14:54:50 -0400 Subject: configure.py: Write last key in each section The loop that writes the keys in each section of bootstrap.toml accumulates all the commented lines before a given key and emits them when it reaches the next key in the section. This ends up dropping lines accumulated for the last key --- src/bootstrap/configure.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index c077555b906..bec7a1c41b4 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -752,6 +752,10 @@ def write_uncommented(target, f): is_comment = True continue is_comment = is_comment and line.startswith("#") + # Write the last accumulated block + if len(block) > 0 and not is_comment: + for ln in block: + f.write(ln + "\n") return f -- cgit 1.4.1-3-g733a5 From b6d21308672c9a0aa5c73beeb1d528aab3d347ed Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 7 Jul 2025 15:45:18 -0400 Subject: Add docstring --- src/bootstrap/configure.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index bec7a1c41b4..94e02f942dc 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -739,6 +739,10 @@ def configure_file(sections, top_level_keys, targets, config): def write_uncommented(target, f): + """Writes each block in 'target' that is not composed entirely of comments to 'f'. + + A block is a sequence of non-empty lines separated by empty lines. + """ block = [] is_comment = True -- cgit 1.4.1-3-g733a5 From 754d46e33a2a01fef9732b4bb7c2bb479f744195 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Tue, 10 Jun 2025 20:15:36 +0200 Subject: Remove `extra_features` from `LlvmBitcodeLinker` It wasn't used anywhere. --- src/bootstrap/src/core/build_steps/compile.rs | 1 - src/bootstrap/src/core/build_steps/dist.rs | 3 +-- src/bootstrap/src/core/build_steps/tool.rs | 4 +--- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 3e2bdc2d6b5..c84f451bbb2 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2061,7 +2061,6 @@ impl Step for Assemble { builder.ensure(crate::core::build_steps::tool::LlvmBitcodeLinker { compiler, target: target_compiler.host, - extra_features: vec![], }); let tool_exe = exe("llvm-bitcode-linker", target_compiler.host); builder.copy_link( diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 25b7e5a1b5d..f2aace76896 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2374,8 +2374,7 @@ impl Step for LlvmBitcodeLinker { builder.ensure(compile::Rustc::new(compiler, target)); - let llbc_linker = - builder.ensure(tool::LlvmBitcodeLinker { compiler, target, extra_features: vec![] }); + let llbc_linker = builder.ensure(tool::LlvmBitcodeLinker { compiler, target }); let self_contained_bin_dir = format!("lib/rustlib/{}/bin/self-contained", target.triple); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index b05b34b9b22..b906409aedd 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1016,7 +1016,6 @@ impl Step for RustAnalyzerProcMacroSrv { pub struct LlvmBitcodeLinker { pub compiler: Compiler, pub target: TargetSelection, - pub extra_features: Vec, } impl Step for LlvmBitcodeLinker { @@ -1033,7 +1032,6 @@ impl Step for LlvmBitcodeLinker { fn make_run(run: RunConfig<'_>) { run.builder.ensure(LlvmBitcodeLinker { compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), - extra_features: Vec::new(), target: run.target, }); } @@ -1050,7 +1048,7 @@ impl Step for LlvmBitcodeLinker { mode: Mode::ToolRustc, path: "src/tools/llvm-bitcode-linker", source_type: SourceType::InTree, - extra_features: self.extra_features, + extra_features: vec![], allow_features: "", cargo_args: Vec::new(), artifact_kind: ToolArtifactKind::Binary, -- cgit 1.4.1-3-g733a5 From c33f908f57cf1f3ea1a1261440062d2757909dc4 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 11 Jun 2025 08:50:09 +0200 Subject: Remove sysroot copy from `LlvmBitcodeLinker` step That step should be responsible for building the tool, not performing side-effects. Also, only copy the tool to the `self-contained` directory, not to the `rustlib//bin` directory. --- src/bootstrap/src/core/build_steps/compile.rs | 9 ++++++++- src/bootstrap/src/core/build_steps/tool.rs | 21 ++------------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index c84f451bbb2..1d095cfc58e 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2062,10 +2062,17 @@ impl Step for Assemble { compiler, target: target_compiler.host, }); + + // Copy the llvm-bitcode-linker to the self-contained binary directory + let bindir_self_contained = builder + .sysroot(compiler) + .join(format!("lib/rustlib/{}/bin/self-contained", compiler.host)); let tool_exe = exe("llvm-bitcode-linker", target_compiler.host); + + t!(fs::create_dir_all(&bindir_self_contained)); builder.copy_link( &llvm_bitcode_linker.tool_path, - &libdir_bin.join(tool_exe), + &bindir_self_contained.join(tool_exe), FileType::Executable, ); } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index b906409aedd..8396099d380 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1041,7 +1041,7 @@ impl Step for LlvmBitcodeLinker { instrument(level = "debug", name = "LlvmBitcodeLinker::run", skip_all) )] fn run(self, builder: &Builder<'_>) -> ToolBuildResult { - let tool_result = builder.ensure(ToolBuild { + builder.ensure(ToolBuild { compiler: self.compiler, target: self.target, tool: "llvm-bitcode-linker", @@ -1052,24 +1052,7 @@ impl Step for LlvmBitcodeLinker { allow_features: "", cargo_args: Vec::new(), artifact_kind: ToolArtifactKind::Binary, - }); - - if tool_result.target_compiler.stage > 0 { - let bindir_self_contained = builder - .sysroot(tool_result.target_compiler) - .join(format!("lib/rustlib/{}/bin/self-contained", self.target.triple)); - t!(fs::create_dir_all(&bindir_self_contained)); - let bin_destination = bindir_self_contained - .join(exe("llvm-bitcode-linker", tool_result.target_compiler.host)); - builder.copy_link(&tool_result.tool_path, &bin_destination, FileType::Executable); - ToolBuildResult { - tool_path: bin_destination, - build_compiler: tool_result.build_compiler, - target_compiler: tool_result.target_compiler, - } - } else { - tool_result - } + }) } } -- cgit 1.4.1-3-g733a5 From fd3772200140b82324a7af8b4153c2a1a2ac1e89 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Tue, 8 Jul 2025 11:47:57 +0200 Subject: Update llvm-bitcode-linker tests --- src/bootstrap/src/core/build_steps/compile.rs | 2 +- src/bootstrap/src/core/build_steps/dist.rs | 3 ++- src/bootstrap/src/core/build_steps/tool.rs | 12 +++++++++--- src/bootstrap/src/core/builder/tests.rs | 23 +++++++++++++++++++++++ 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 1d095cfc58e..29300ff56f5 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2059,7 +2059,7 @@ impl Step for Assemble { trace!("llvm-bitcode-linker enabled, installing"); let llvm_bitcode_linker = builder.ensure(crate::core::build_steps::tool::LlvmBitcodeLinker { - compiler, + build_compiler: compiler, target: target_compiler.host, }); diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index f2aace76896..8b2d65ace50 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2374,7 +2374,8 @@ impl Step for LlvmBitcodeLinker { builder.ensure(compile::Rustc::new(compiler, target)); - let llbc_linker = builder.ensure(tool::LlvmBitcodeLinker { compiler, target }); + let llbc_linker = + builder.ensure(tool::LlvmBitcodeLinker { build_compiler: compiler, target }); let self_contained_bin_dir = format!("lib/rustlib/{}/bin/self-contained", target.triple); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 8396099d380..a7f6a2c7bae 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1014,7 +1014,7 @@ impl Step for RustAnalyzerProcMacroSrv { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct LlvmBitcodeLinker { - pub compiler: Compiler, + pub build_compiler: Compiler, pub target: TargetSelection, } @@ -1031,7 +1031,9 @@ impl Step for LlvmBitcodeLinker { fn make_run(run: RunConfig<'_>) { run.builder.ensure(LlvmBitcodeLinker { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), + build_compiler: run + .builder + .compiler(run.builder.top_stage, run.builder.config.host_target), target: run.target, }); } @@ -1042,7 +1044,7 @@ impl Step for LlvmBitcodeLinker { )] fn run(self, builder: &Builder<'_>) -> ToolBuildResult { builder.ensure(ToolBuild { - compiler: self.compiler, + compiler: self.build_compiler, target: self.target, tool: "llvm-bitcode-linker", mode: Mode::ToolRustc, @@ -1054,6 +1056,10 @@ impl Step for LlvmBitcodeLinker { artifact_kind: ToolArtifactKind::Binary, }) } + + fn metadata(&self) -> Option { + Some(StepMetadata::build("LlvmBitcodeLinker", self.target).built_by(self.build_compiler)) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 1d5690a8197..131394f2a65 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -757,6 +757,27 @@ mod snapshot { "); } + #[test] + fn build_compiler_tools() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx + .config("build") + .stage(2) + .args(&["--set", "rust.llvm-bitcode-linker=true"]) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> LlvmBitcodeLinker 2 + [build] rustc 1 -> std 1 + [build] rustc 1 -> rustc 2 + [build] rustc 2 -> LlvmBitcodeLinker 3 + [build] rustc 2 -> std 2 + [build] rustdoc 1 + " + ); + } + #[test] fn build_library_no_explicit_stage() { let ctx = TestCtx::new(); @@ -1040,6 +1061,7 @@ mod snapshot { [build] rustc 0 -> cargo-clippy 1 [build] rustc 0 -> miri 1 [build] rustc 0 -> cargo-miri 1 + [build] rustc 1 -> LlvmBitcodeLinker 2 "); } @@ -1230,6 +1252,7 @@ mod snapshot { [build] rustc 0 -> cargo-clippy 1 [build] rustc 0 -> miri 1 [build] rustc 0 -> cargo-miri 1 + [build] rustc 1 -> LlvmBitcodeLinker 2 "); } -- cgit 1.4.1-3-g733a5 From b14323aedcfef75bde97aff4f2562dcab8e9a3cd Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Tue, 8 Jul 2025 11:49:08 +0200 Subject: Also test `LldWrapper` and remove `llvm-config` override from tests --- src/bootstrap/src/core/build_steps/tool.rs | 7 +++++++ src/bootstrap/src/core/builder/tests.rs | 4 +++- src/bootstrap/src/utils/tests/mod.rs | 2 -- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index a7f6a2c7bae..5de1b472d79 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -910,6 +910,13 @@ impl Step for LldWrapper { tool_result } + + fn metadata(&self) -> Option { + Some( + StepMetadata::build("LldWrapper", self.target_compiler.host) + .built_by(self.build_compiler), + ) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 131394f2a65..b240d670b6b 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -764,13 +764,15 @@ mod snapshot { ctx .config("build") .stage(2) - .args(&["--set", "rust.llvm-bitcode-linker=true"]) + .args(&["--set", "rust.lld=true", "--set", "rust.llvm-bitcode-linker=true"]) .render_steps(), @r" [build] llvm [build] rustc 0 -> rustc 1 + [build] rustc 0 -> LldWrapper 1 [build] rustc 1 -> LlvmBitcodeLinker 2 [build] rustc 1 -> std 1 [build] rustc 1 -> rustc 2 + [build] rustc 1 -> LldWrapper 2 [build] rustc 2 -> LlvmBitcodeLinker 3 [build] rustc 2 -> std 2 [build] rustdoc 1 diff --git a/src/bootstrap/src/utils/tests/mod.rs b/src/bootstrap/src/utils/tests/mod.rs index 59c169b0f2b..5b568c1df5b 100644 --- a/src/bootstrap/src/utils/tests/mod.rs +++ b/src/bootstrap/src/utils/tests/mod.rs @@ -96,8 +96,6 @@ impl ConfigBuilder { // in-tree LLVM from sources. self.args.push("--set".to_string()); self.args.push("llvm.download-ci-llvm=false".to_string()); - self.args.push("--set".to_string()); - self.args.push(format!("target.'{}'.llvm-config=false", get_host_target())); // Do not mess with the local rustc checkout build directory self.args.push("--build-dir".to_string()); -- cgit 1.4.1-3-g733a5 From 3ba8e330f9960a52b2c8ca10c8cba425514919f9 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 8 Jul 2025 07:34:51 -0400 Subject: Rewrite for clarity move common code to a helper function Co-Authored-By: Kobzol --- src/bootstrap/configure.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 94e02f942dc..86208b94261 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -744,22 +744,24 @@ def write_uncommented(target, f): A block is a sequence of non-empty lines separated by empty lines. """ block = [] - is_comment = True + + def flush(last): + # If the block is entiry made of comments, ignore it + entire_block_comments = all(ln.startswith("#") or ln == "" for ln in block) + if not entire_block_comments and len(block) > 0: + for line in block: + f.write(line + "\n") + # Required to output a newline before the start of a new section + if last: + f.write("\n") + block.clear() for line in target: block.append(line) if len(line) == 0: - if not is_comment: - for ln in block: - f.write(ln + "\n") - block = [] - is_comment = True - continue - is_comment = is_comment and line.startswith("#") - # Write the last accumulated block - if len(block) > 0 and not is_comment: - for ln in block: - f.write(ln + "\n") + flush(last=False) + + flush(last=True) return f -- cgit 1.4.1-3-g733a5 From 961bac0b197bf5ded0da8faf1395c96598923b20 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Tue, 8 Jul 2025 15:06:27 +0200 Subject: Add cross-compilation tool test --- src/bootstrap/src/core/builder/tests.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index b240d670b6b..bbcb58fca14 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -780,6 +780,35 @@ mod snapshot { ); } + #[test] + fn build_compiler_tools_cross() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx + .config("build") + .stage(2) + .args(&["--set", "rust.lld=true", "--set", "rust.llvm-bitcode-linker=true"]) + .hosts(&[TEST_TRIPLE_1]) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 0 -> LldWrapper 1 + [build] rustc 1 -> LlvmBitcodeLinker 2 + [build] rustc 1 -> std 1 + [build] rustc 1 -> rustc 2 + [build] rustc 1 -> LldWrapper 2 + [build] rustc 2 -> LlvmBitcodeLinker 3 + [build] rustc 1 -> std 1 + [build] rustc 2 -> std 2 + [build] llvm + [build] rustc 1 -> rustc 2 + [build] rustc 1 -> LldWrapper 2 + [build] rustc 2 -> LlvmBitcodeLinker 3 + [build] rustdoc 1 + " + ); + } + #[test] fn build_library_no_explicit_stage() { let ctx = TestCtx::new(); -- cgit 1.4.1-3-g733a5 From c4bf37d35824cf22dade0c1c4595186a29a8714d Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 2 Jul 2025 18:10:57 +0200 Subject: Always inline InterpCx::layout_of after perf regression --- compiler/rustc_const_eval/src/interpret/eval_context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 068d6369f87..41fc8d47cd3 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -96,7 +96,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// This inherent method takes priority over the trait method with the same name in LayoutOf, /// and allows wrapping the actual [LayoutOf::layout_of] with a tracing span. /// See [LayoutOf::layout_of] for the original documentation. - #[inline] + #[inline(always)] pub fn layout_of( &self, ty: Ty<'tcx>, -- cgit 1.4.1-3-g733a5 From 07143afee43a4b516ca446e5e49570411043dfdb Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 5 Jul 2025 11:13:04 +0200 Subject: Replace TRACING_ENABLED with enter_trace_span() Hopefully this will make tracing calls be optimized out properly when tracing is disabled --- compiler/rustc_const_eval/src/interpret/machine.rs | 20 +++++++++++-------- compiler/rustc_const_eval/src/interpret/mod.rs | 1 + compiler/rustc_const_eval/src/interpret/util.rs | 23 +++++++++++----------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 844c19fea2d..33afadd94f5 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -18,8 +18,8 @@ use rustc_target::callconv::FnAbi; use super::{ AllocBytes, AllocId, AllocKind, AllocRange, Allocation, CTFE_ALLOC_SALT, ConstAllocation, - CtfeProvenance, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, MemoryKind, - Misalignment, OpTy, PlaceTy, Pointer, Provenance, RangeSet, interp_ok, throw_unsup, + CtfeProvenance, EnteredTraceSpan, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, + MemoryKind, Misalignment, OpTy, PlaceTy, Pointer, Provenance, RangeSet, interp_ok, throw_unsup, }; /// Data returned by [`Machine::after_stack_pop`], and consumed by @@ -147,12 +147,6 @@ pub trait Machine<'tcx>: Sized { /// already been checked before. const ALL_CONSTS_ARE_PRECHECKED: bool = true; - /// Determines whether rustc_const_eval functions that make use of the [Machine] should make - /// tracing calls (to the `tracing` library). By default this is `false`, meaning the tracing - /// calls will supposedly be optimized out. This flag is set to `true` inside Miri, to allow - /// tracing the interpretation steps, among other things. - const TRACING_ENABLED: bool = false; - /// Whether memory accesses should be alignment-checked. fn enforce_alignment(ecx: &InterpCx<'tcx, Self>) -> bool; @@ -634,6 +628,16 @@ pub trait Machine<'tcx>: Sized { /// Compute the value passed to the constructors of the `AllocBytes` type for /// abstract machine allocations. fn get_default_alloc_params(&self) -> ::AllocParams; + + /// Allows enabling/disabling tracing calls from within `rustc_const_eval` at compile time, by + /// delegating the entering of [tracing::Span]s to implementors of the [Machine] trait. The + /// default implementation corresponds to tracing being disabled, meaning the tracing calls will + /// supposedly be optimized out completely. To enable tracing, override this trait method and + /// return `span.entered()`. Also see [crate::enter_trace_span]. + #[must_use] + fn enter_trace_span(_span: tracing::Span) -> impl EnteredTraceSpan { + () + } } /// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 8303f891f98..2fc372dd019 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -37,6 +37,7 @@ pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable}; use self::place::{MemPlace, Place}; pub use self::projection::{OffsetMode, Projectable}; pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation, StackPopInfo}; +pub use self::util::EnteredTraceSpan; pub(crate) use self::util::create_static_alloc; pub use self::validity::{CtfeValidationMode, RangeSet, RefTracking}; pub use self::visitor::ValueVisitor; diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 99add01f95c..eeab32fd79c 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -46,21 +46,20 @@ pub(crate) fn create_static_alloc<'tcx>( interp_ok(ecx.ptr_to_mplace(Pointer::from(alloc_id).into(), layout)) } -/// This struct is needed to enforce `#[must_use]` on [tracing::span::EnteredSpan] -/// while wrapping them in an `Option`. -#[must_use] -pub enum MaybeEnteredSpan { - Some(tracing::span::EnteredSpan), - None, -} +/// A marker trait returned by [crate::interpret::Machine::enter_trace_span], identifying either a +/// real [tracing::span::EnteredSpan] in case tracing is enabled, or the dummy type `()` when +/// tracing is disabled. +pub trait EnteredTraceSpan {} +impl EnteredTraceSpan for () {} +impl EnteredTraceSpan for tracing::span::EnteredSpan {} +/// Shortand for calling [crate::interpret::Machine::enter_trace_span] on a [tracing::info_span]. +/// This is supposed to be compiled out when [crate::interpret::Machine::enter_trace_span] has the +/// default implementation (i.e. when it does not actually enter the span but instead returns `()`). +/// Note: the result of this macro **must be used** because the span is exited when it's dropped. #[macro_export] macro_rules! enter_trace_span { ($machine:ident, $($tt:tt)*) => { - if $machine::TRACING_ENABLED { - $crate::interpret::util::MaybeEnteredSpan::Some(tracing::info_span!($($tt)*).entered()) - } else { - $crate::interpret::util::MaybeEnteredSpan::None - } + $machine::enter_trace_span(tracing::info_span!($($tt)*)) } } -- cgit 1.4.1-3-g733a5 From 3cacaa7d0ebd8994f521fbcfc5277f8725f9348c Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Jul 2025 08:53:50 +0200 Subject: Add inline(always) to Machine::enter_trace_span --- compiler/rustc_const_eval/src/interpret/machine.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 33afadd94f5..64aa971d14e 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -635,6 +635,7 @@ pub trait Machine<'tcx>: Sized { /// supposedly be optimized out completely. To enable tracing, override this trait method and /// return `span.entered()`. Also see [crate::enter_trace_span]. #[must_use] + #[inline(always)] fn enter_trace_span(_span: tracing::Span) -> impl EnteredTraceSpan { () } -- cgit 1.4.1-3-g733a5 From e8c8330ba1a0fb7dcf8e74a8758569ab71261ef7 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Jul 2025 08:58:19 +0200 Subject: Make enter_trace_span take a closure for better optimization --- compiler/rustc_const_eval/src/interpret/machine.rs | 2 +- compiler/rustc_const_eval/src/interpret/util.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 64aa971d14e..d150ed69250 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -636,7 +636,7 @@ pub trait Machine<'tcx>: Sized { /// return `span.entered()`. Also see [crate::enter_trace_span]. #[must_use] #[inline(always)] - fn enter_trace_span(_span: tracing::Span) -> impl EnteredTraceSpan { + fn enter_trace_span(_span: impl FnOnce() -> tracing::Span) -> impl EnteredTraceSpan { () } } diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index eeab32fd79c..72650d545c3 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -60,6 +60,6 @@ impl EnteredTraceSpan for tracing::span::EnteredSpan {} #[macro_export] macro_rules! enter_trace_span { ($machine:ident, $($tt:tt)*) => { - $machine::enter_trace_span(tracing::info_span!($($tt)*)) + $machine::enter_trace_span(|| tracing::info_span!($($tt)*)) } } -- cgit 1.4.1-3-g733a5 From e5f7d4d783c1567ddc16e02091bae8bacfca1418 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 8 Jul 2025 15:37:01 +0200 Subject: Implement enter_trace_span() in MiriMachine --- src/tools/miri/src/machine.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 693b8916d89..35399dbf4cb 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1014,8 +1014,6 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { const PANIC_ON_ALLOC_FAIL: bool = false; - const TRACING_ENABLED: bool = cfg!(feature = "tracing"); - #[inline(always)] fn enforce_alignment(ecx: &MiriInterpCx<'tcx>) -> bool { ecx.machine.check_alignment != AlignmentCheck::None @@ -1827,6 +1825,16 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { #[cfg(not(target_os = "linux"))] MiriAllocParams::Global } + + fn enter_trace_span(span: impl FnOnce() -> tracing::Span) -> impl EnteredTraceSpan { + #[cfg(feature = "tracing")] + { span().entered() } + #[cfg(not(feature = "tracing"))] + { + let _ = span; // so we avoid the "unused variable" warning + () + } + } } /// Trait for callbacks handling asynchronous machine operations. -- cgit 1.4.1-3-g733a5 From 7c8a6d978bb47827eeef15448ca95f82af32c381 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 8 Jul 2025 14:18:07 -0400 Subject: Spelling --- src/bootstrap/configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 86208b94261..b05a5cc8b81 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -746,7 +746,7 @@ def write_uncommented(target, f): block = [] def flush(last): - # If the block is entiry made of comments, ignore it + # If the block is entirely made of comments, ignore it entire_block_comments = all(ln.startswith("#") or ln == "" for ln in block) if not entire_block_comments and len(block) > 0: for line in block: -- cgit 1.4.1-3-g733a5