From 395f0c9ecd1c3f238707c7a0788e4b1d84e2e70e Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 12 Jan 2025 20:18:45 +0000 Subject: [PATCH 01/16] Stabilize `const_black_box` This has been unstably const since [1], but a tracking issue was never created. Per discussion on Zulip [2], there should not be any blockers to making this const-stable. The function does not provide any functionality at compile time but does allow code reuse between const- and non-const functions, so stabilize it here. [1]: https://github.com/rust-lang/rust/pull/92226 [2]: https://rust-lang.zulipchat.com/#narrow/channel/146212-t-compiler.2Fconst-eval/topic/const_black_box --- compiler/rustc_codegen_gcc/tests/run/int.rs | 2 -- library/core/src/hint.rs | 4 +++- library/core/src/intrinsics/mod.rs | 1 + library/coretests/tests/lib.rs | 1 - 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_gcc/tests/run/int.rs b/compiler/rustc_codegen_gcc/tests/run/int.rs index bfe73c38435a3..58a26801b678c 100644 --- a/compiler/rustc_codegen_gcc/tests/run/int.rs +++ b/compiler/rustc_codegen_gcc/tests/run/int.rs @@ -3,8 +3,6 @@ // Run-time: // status: 0 -#![feature(const_black_box)] - /* * Code */ diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 80f6e32b6b2cd..e5c1a64c12ee5 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -468,9 +468,11 @@ pub fn spin_loop() { /// // No assumptions can be made about either operand, so the multiplication is not optimized out. /// let y = black_box(5) * black_box(10); /// ``` +/// +/// During constant evaluation, `black_box` is treated as a no-op. #[inline] #[stable(feature = "bench_black_box", since = "1.66.0")] -#[rustc_const_unstable(feature = "const_black_box", issue = "none")] +#[rustc_const_stable(feature = "const_black_box", since = "CURRENT_RUSTC_VERSION")] pub const fn black_box(dummy: T) -> T { crate::intrinsics::black_box(dummy) } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 41b2ffad6680d..c0d435f99c0ca 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3725,6 +3725,7 @@ pub const unsafe fn compare_bytes(_left: *const u8, _right: *const u8, _bytes: u #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] +#[rustc_intrinsic_const_stable_indirect] pub const fn black_box(_dummy: T) -> T { unimplemented!() } diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 0607d508a48e5..7fe7286260858 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -14,7 +14,6 @@ #![feature(bstr)] #![feature(cell_update)] #![feature(clone_to_uninit)] -#![feature(const_black_box)] #![feature(const_eval_select)] #![feature(const_swap_nonoverlapping)] #![feature(const_trait_impl)] From fdef34b4ddfeebf614bb58622b4053cff616234a Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 29 Jan 2025 11:20:22 -0700 Subject: [PATCH 02/16] Add URL and `crate_name` to test cases --- tests/rustdoc/inline_cross/issue-24183.rs | 1 + tests/rustdoc/inline_cross/issue-28480.rs | 5 ++++- tests/rustdoc/inline_cross/issue-31948-1.rs | 13 ++++++++----- tests/rustdoc/inline_cross/issue-31948-2.rs | 13 ++++++++----- tests/rustdoc/inline_cross/issue-31948.rs | 17 ++++++++++------- tests/rustdoc/inline_cross/issue-32881.rs | 5 ++++- tests/rustdoc/inline_cross/issue-33113.rs | 5 ++++- tests/rustdoc/inline_cross/issue-76736-1.rs | 2 ++ tests/rustdoc/inline_cross/issue-76736-2.rs | 2 ++ tests/rustdoc/inline_cross/issue-76736-3.rs | 2 ++ tests/rustdoc/inline_cross/issue-76736-4.rs | 2 ++ tests/rustdoc/inline_local/issue-28537.rs | 7 +++++-- tests/rustdoc/inline_local/issue-32343.rs | 13 ++++++++----- tests/rustdoc/intra-doc/issue-103463.rs | 2 ++ tests/rustdoc/intra-doc/issue-104145.rs | 2 ++ tests/rustdoc/intra-doc/issue-108459.rs | 11 +++++++---- tests/rustdoc/intra-doc/issue-66159.rs | 5 ++++- tests/rustdoc/intra-doc/issue-82209.rs | 2 ++ 18 files changed, 77 insertions(+), 32 deletions(-) diff --git a/tests/rustdoc/inline_cross/issue-24183.rs b/tests/rustdoc/inline_cross/issue-24183.rs index 8299eecc575d1..909005532f505 100644 --- a/tests/rustdoc/inline_cross/issue-24183.rs +++ b/tests/rustdoc/inline_cross/issue-24183.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/24183 #![crate_type = "lib"] #![crate_name = "usr"] diff --git a/tests/rustdoc/inline_cross/issue-28480.rs b/tests/rustdoc/inline_cross/issue-28480.rs index 004510fd9225e..e1ca7403c03f6 100644 --- a/tests/rustdoc/inline_cross/issue-28480.rs +++ b/tests/rustdoc/inline_cross/issue-28480.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/28480 +#![crate_name="foobar"] + //@ aux-build:rustdoc-hidden-sig.rs //@ build-aux-docs //@ ignore-cross-compile @@ -7,7 +10,7 @@ //@ has - '//a' 'u8' extern crate rustdoc_hidden_sig; -//@ has issue_28480/struct.Bar.html +//@ has foobar/struct.Bar.html //@ !has - '//a/@title' 'Hidden' //@ has - '//a' 'u8' pub use rustdoc_hidden_sig::Bar; diff --git a/tests/rustdoc/inline_cross/issue-31948-1.rs b/tests/rustdoc/inline_cross/issue-31948-1.rs index e59da87c29de7..baab1da95470c 100644 --- a/tests/rustdoc/inline_cross/issue-31948-1.rs +++ b/tests/rustdoc/inline_cross/issue-31948-1.rs @@ -1,27 +1,30 @@ +// https://github.com/rust-lang/rust/issues/31948 +#![crate_name="foobar"] + //@ aux-build:rustdoc-nonreachable-impls.rs //@ build-aux-docs //@ ignore-cross-compile extern crate rustdoc_nonreachable_impls; -//@ has issue_31948_1/struct.Wobble.html +//@ has foobar/struct.Wobble.html //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for' //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for' //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for' //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for' pub use rustdoc_nonreachable_impls::hidden::Wobble; -//@ has issue_31948_1/trait.Bark.html +//@ has foobar/trait.Bark.html //@ has - '//h3[@class="code-header"]' 'for Foo' //@ has - '//h3[@class="code-header"]' 'for Wobble' //@ !has - '//h3[@class="code-header"]' 'for Wibble' pub use rustdoc_nonreachable_impls::Bark; -//@ has issue_31948_1/trait.Woof.html +//@ has foobar/trait.Woof.html //@ has - '//h3[@class="code-header"]' 'for Foo' //@ has - '//h3[@class="code-header"]' 'for Wobble' //@ !has - '//h3[@class="code-header"]' 'for Wibble' pub use rustdoc_nonreachable_impls::Woof; -//@ !has issue_31948_1/trait.Bar.html -//@ !has issue_31948_1/trait.Qux.html +//@ !has foobar/trait.Bar.html +//@ !has foobar/trait.Qux.html diff --git a/tests/rustdoc/inline_cross/issue-31948-2.rs b/tests/rustdoc/inline_cross/issue-31948-2.rs index 34b570528832a..40e9108ec62ef 100644 --- a/tests/rustdoc/inline_cross/issue-31948-2.rs +++ b/tests/rustdoc/inline_cross/issue-31948-2.rs @@ -1,21 +1,24 @@ +// https://github.com/rust-lang/rust/issues/31948 +#![crate_name="foobar"] + //@ aux-build:rustdoc-nonreachable-impls.rs //@ build-aux-docs //@ ignore-cross-compile extern crate rustdoc_nonreachable_impls; -//@ has issue_31948_2/struct.Wobble.html +//@ has foobar/struct.Wobble.html //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for' //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for' //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for' //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for' pub use rustdoc_nonreachable_impls::hidden::Wobble; -//@ has issue_31948_2/trait.Qux.html +//@ has foobar/trait.Qux.html //@ has - '//h3[@class="code-header"]' 'for Foo' //@ has - '//h3[@class="code-header"]' 'for Wobble' pub use rustdoc_nonreachable_impls::hidden::Qux; -//@ !has issue_31948_2/trait.Bar.html -//@ !has issue_31948_2/trait.Woof.html -//@ !has issue_31948_2/trait.Bark.html +//@ !has foobar/trait.Bar.html +//@ !has foobar/trait.Woof.html +//@ !has foobar/trait.Bark.html diff --git a/tests/rustdoc/inline_cross/issue-31948.rs b/tests/rustdoc/inline_cross/issue-31948.rs index 7a43fc7b279de..ab0048513c729 100644 --- a/tests/rustdoc/inline_cross/issue-31948.rs +++ b/tests/rustdoc/inline_cross/issue-31948.rs @@ -1,29 +1,32 @@ +// https://github.com/rust-lang/rust/issues/31948 +#![crate_name="foobar"] + //@ aux-build:rustdoc-nonreachable-impls.rs //@ build-aux-docs //@ ignore-cross-compile extern crate rustdoc_nonreachable_impls; -//@ has issue_31948/struct.Foo.html +//@ has foobar/struct.Foo.html //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for' //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for' //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for' //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for' pub use rustdoc_nonreachable_impls::Foo; -//@ has issue_31948/trait.Bark.html +//@ has foobar/trait.Bark.html //@ has - '//h3[@class="code-header"]' 'for Foo' //@ !has - '//h3[@class="code-header"]' 'for Wibble' //@ !has - '//h3[@class="code-header"]' 'for Wobble' pub use rustdoc_nonreachable_impls::Bark; -//@ has issue_31948/trait.Woof.html +//@ has foobar/trait.Woof.html //@ has - '//h3[@class="code-header"]' 'for Foo' //@ !has - '//h3[@class="code-header"]' 'for Wibble' //@ !has - '//h3[@class="code-header"]' 'for Wobble' pub use rustdoc_nonreachable_impls::Woof; -//@ !has issue_31948/trait.Bar.html -//@ !has issue_31948/trait.Qux.html -//@ !has issue_31948/struct.Wibble.html -//@ !has issue_31948/struct.Wobble.html +//@ !has foobar/trait.Bar.html +//@ !has foobar/trait.Qux.html +//@ !has foobar/struct.Wibble.html +//@ !has foobar/struct.Wobble.html diff --git a/tests/rustdoc/inline_cross/issue-32881.rs b/tests/rustdoc/inline_cross/issue-32881.rs index d4ebf10a1ca9a..f7dc741445520 100644 --- a/tests/rustdoc/inline_cross/issue-32881.rs +++ b/tests/rustdoc/inline_cross/issue-32881.rs @@ -1,10 +1,13 @@ +// https://github.com/rust-lang/rust/issues/32881 +#![crate_name="foobar"] + //@ aux-build:rustdoc-trait-object-impl.rs //@ build-aux-docs //@ ignore-cross-compile extern crate rustdoc_trait_object_impl; -//@ has issue_32881/trait.Bar.html +//@ has foobar/trait.Bar.html //@ has - '//h3[@class="code-header"]' "impl<'a> dyn Bar" //@ has - '//h3[@class="code-header"]' "impl<'a> Debug for dyn Bar" diff --git a/tests/rustdoc/inline_cross/issue-33113.rs b/tests/rustdoc/inline_cross/issue-33113.rs index 05e87d962cb67..9ac4f02e00c15 100644 --- a/tests/rustdoc/inline_cross/issue-33113.rs +++ b/tests/rustdoc/inline_cross/issue-33113.rs @@ -1,10 +1,13 @@ +// https://github.com/rust-lang/rust/issues/33113 +#![crate_name="foobar"] + //@ aux-build:issue-33113.rs //@ build-aux-docs //@ ignore-cross-compile extern crate bar; -//@ has issue_33113/trait.Bar.html +//@ has foobar/trait.Bar.html //@ has - '//h3[@class="code-header"]' "for &'a char" //@ has - '//h3[@class="code-header"]' "for Foo" pub use bar::Bar; diff --git a/tests/rustdoc/inline_cross/issue-76736-1.rs b/tests/rustdoc/inline_cross/issue-76736-1.rs index fe52702fd6f51..3ffa5e6cc06e9 100644 --- a/tests/rustdoc/inline_cross/issue-76736-1.rs +++ b/tests/rustdoc/inline_cross/issue-76736-1.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/76736 + //@ aux-build:issue-76736-1.rs //@ aux-build:issue-76736-2.rs diff --git a/tests/rustdoc/inline_cross/issue-76736-2.rs b/tests/rustdoc/inline_cross/issue-76736-2.rs index df376ebe9a143..843b2941602cb 100644 --- a/tests/rustdoc/inline_cross/issue-76736-2.rs +++ b/tests/rustdoc/inline_cross/issue-76736-2.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/76736 + //@ aux-build:issue-76736-1.rs //@ aux-build:issue-76736-2.rs diff --git a/tests/rustdoc/inline_cross/issue-76736-3.rs b/tests/rustdoc/inline_cross/issue-76736-3.rs index 1bed4621c049e..f9b46caa02ff6 100644 --- a/tests/rustdoc/inline_cross/issue-76736-3.rs +++ b/tests/rustdoc/inline_cross/issue-76736-3.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/76736 + //@ compile-flags: -Zforce-unstable-if-unmarked //@ aux-build:issue-76736-1.rs //@ aux-build:issue-76736-2.rs diff --git a/tests/rustdoc/inline_cross/issue-76736-4.rs b/tests/rustdoc/inline_cross/issue-76736-4.rs index 487e90301082b..511464f2c498f 100644 --- a/tests/rustdoc/inline_cross/issue-76736-4.rs +++ b/tests/rustdoc/inline_cross/issue-76736-4.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/76736 + //@ aux-build:issue-76736-1.rs //@ aux-build:issue-76736-2.rs diff --git a/tests/rustdoc/inline_local/issue-28537.rs b/tests/rustdoc/inline_local/issue-28537.rs index d5ba94d2e6c9e..0e9836c7ceeab 100644 --- a/tests/rustdoc/inline_local/issue-28537.rs +++ b/tests/rustdoc/inline_local/issue-28537.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/28537 +#![crate_name="foo"] + #[doc(hidden)] pub mod foo { pub struct Foo; @@ -10,8 +13,8 @@ mod bar { } } -//@ has issue_28537/struct.Foo.html +//@ has foo/struct.Foo.html pub use foo::Foo; -//@ has issue_28537/struct.Bar.html +//@ has foo/struct.Bar.html pub use self::bar::Bar; diff --git a/tests/rustdoc/inline_local/issue-32343.rs b/tests/rustdoc/inline_local/issue-32343.rs index 2ec123fdc5cfe..ed11614a50038 100644 --- a/tests/rustdoc/inline_local/issue-32343.rs +++ b/tests/rustdoc/inline_local/issue-32343.rs @@ -1,12 +1,15 @@ -//@ !has issue_32343/struct.Foo.html -//@ has issue_32343/index.html +// https://github.com/rust-lang/rust/issues/32343 +#![crate_name="foobar"] + +//@ !has foobar/struct.Foo.html +//@ has foobar/index.html //@ has - '//code' 'pub use foo::Foo' //@ !has - '//code/a' 'Foo' #[doc(no_inline)] pub use foo::Foo; -//@ !has issue_32343/struct.Bar.html -//@ has issue_32343/index.html +//@ !has foobar/struct.Bar.html +//@ has foobar/index.html //@ has - '//code' 'pub use foo::Bar' //@ has - '//code/a' 'Bar' #[doc(no_inline)] @@ -18,6 +21,6 @@ mod foo { } pub mod bar { - //@ has issue_32343/bar/struct.Bar.html + //@ has foobar/bar/struct.Bar.html pub use ::foo::Bar; } diff --git a/tests/rustdoc/intra-doc/issue-103463.rs b/tests/rustdoc/intra-doc/issue-103463.rs index 9b5cb67fd32a6..bfe5c4f05d4da 100644 --- a/tests/rustdoc/intra-doc/issue-103463.rs +++ b/tests/rustdoc/intra-doc/issue-103463.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/103463 + // The `Trait` is not pulled into the crate resulting in doc links in its methods being resolved. //@ aux-build:issue-103463-aux.rs diff --git a/tests/rustdoc/intra-doc/issue-104145.rs b/tests/rustdoc/intra-doc/issue-104145.rs index 5690803af5ae9..92c7fa31b4fec 100644 --- a/tests/rustdoc/intra-doc/issue-104145.rs +++ b/tests/rustdoc/intra-doc/issue-104145.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/104145 + // Doc links in `Trait`'s methods are resolved because it has a local impl. //@ aux-build:issue-103463-aux.rs diff --git a/tests/rustdoc/intra-doc/issue-108459.rs b/tests/rustdoc/intra-doc/issue-108459.rs index 18424c069d359..0328e6435a530 100644 --- a/tests/rustdoc/intra-doc/issue-108459.rs +++ b/tests/rustdoc/intra-doc/issue-108459.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/108459 +#![crate_name="foobar"] + #![deny(rustdoc::broken_intra_doc_links)] #![allow(rustdoc::redundant_explicit_links)] @@ -13,13 +16,13 @@ pub struct MyStruct1; // the same target but different text /// See also [crate::char] and [mod@char] and [prim@char] -//@ has issue_108459/struct.MyStruct2.html '//*[@href="char/index.html"]' 'crate::char' +//@ has foobar/struct.MyStruct2.html '//*[@href="char/index.html"]' 'crate::char' //@ has - '//*[@href="char/index.html"]' 'char' //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char' pub struct MyStruct2; /// See also [mod@char] and [prim@char] and [crate::char] -//@ has issue_108459/struct.MyStruct3.html '//*[@href="char/index.html"]' 'crate::char' +//@ has foobar/struct.MyStruct3.html '//*[@href="char/index.html"]' 'crate::char' //@ has - '//*[@href="char/index.html"]' 'char' //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char' pub struct MyStruct3; @@ -28,11 +31,11 @@ pub struct MyStruct3; // different targets /// See also [char][mod@char] and [char][prim@char] -//@ has issue_108459/struct.MyStruct4.html '//*[@href="char/index.html"]' 'char' +//@ has foobar/struct.MyStruct4.html '//*[@href="char/index.html"]' 'char' //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char' pub struct MyStruct4; /// See also [char][prim@char] and [char][crate::char] -//@ has issue_108459/struct.MyStruct5.html '//*[@href="char/index.html"]' 'char' +//@ has foobar/struct.MyStruct5.html '//*[@href="char/index.html"]' 'char' //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char' pub struct MyStruct5; diff --git a/tests/rustdoc/intra-doc/issue-66159.rs b/tests/rustdoc/intra-doc/issue-66159.rs index 5d50f63f299f9..7e3ace9355aeb 100644 --- a/tests/rustdoc/intra-doc/issue-66159.rs +++ b/tests/rustdoc/intra-doc/issue-66159.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/66159 +#![crate_name="foobar"] + //@ aux-crate:priv:pub_struct=pub-struct.rs //@ compile-flags:-Z unstable-options @@ -6,5 +9,5 @@ // Since we don't generate the docs for the auxiliary files, we can't actually // verify that the struct is linked correctly. -//@ has issue_66159/index.html +//@ has foobar/index.html //! [pub_struct::SomeStruct] diff --git a/tests/rustdoc/intra-doc/issue-82209.rs b/tests/rustdoc/intra-doc/issue-82209.rs index 46d028e535c2f..615115a5f8b2c 100644 --- a/tests/rustdoc/intra-doc/issue-82209.rs +++ b/tests/rustdoc/intra-doc/issue-82209.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/82209 + #![crate_name = "foo"] #![deny(rustdoc::broken_intra_doc_links)] pub enum Foo { From eb457da5cafc0eb907a0ecf70ffae5a37cd4e8f0 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 29 Jan 2025 11:36:36 -0700 Subject: [PATCH 03/16] rustdoc: rename `issue-\d+.rs` tests to have meaningful names --- .../intra-doc/auxiliary/issue-103463-aux.rs | 0 .../issue-103463.rs => rustdoc-ui/intra-doc/ice-103463.rs} | 1 + .../issue-104145.rs => rustdoc-ui/intra-doc/ice-104145.rs} | 1 + .../{issue-28480.rs => doc-hidden-broken-link-28480.rs} | 0 .../{issue-31948-1.rs => doc-hidden-module-impl-31948-1.rs} | 0 .../{issue-31948-2.rs => doc-hidden-module-impl-31948-2.rs} | 0 .../{issue-31948.rs => doc-hidden-module-impl-31948.rs} | 0 .../inline_cross/{issue-32881.rs => impl-dyn-trait-32881.rs} | 0 tests/rustdoc/inline_cross/{issue-33113.rs => impl-ref-33113.rs} | 0 .../inline_cross/{issue-76736-1.rs => rustc-private-76736-1.rs} | 0 .../inline_cross/{issue-76736-2.rs => rustc-private-76736-2.rs} | 0 .../inline_cross/{issue-76736-3.rs => rustc-private-76736-3.rs} | 0 .../inline_cross/{issue-76736-4.rs => rustc-private-76736-4.rs} | 0 ...l => self-sized-bounds-24183.method_no_where_self_sized.html} | 0 .../inline_cross/{issue-24183.rs => self-sized-bounds-24183.rs} | 0 .../inline_local/{issue-32343.rs => doc-no-inline-32343.rs} | 0 .../inline_local/{issue-28537.rs => pub-re-export-28537.rs} | 0 tests/rustdoc/intra-doc/{issue-82209.rs => enum-self-82209.rs} | 0 ...08459.rs => link-same-name-different-disambiguator-108459.rs} | 0 .../{issue-66159.rs => same-name-different-crates-66159.rs} | 0 20 files changed, 2 insertions(+) rename tests/{rustdoc => rustdoc-ui}/intra-doc/auxiliary/issue-103463-aux.rs (100%) rename tests/{rustdoc/intra-doc/issue-103463.rs => rustdoc-ui/intra-doc/ice-103463.rs} (94%) rename tests/{rustdoc/intra-doc/issue-104145.rs => rustdoc-ui/intra-doc/ice-104145.rs} (95%) rename tests/rustdoc/inline_cross/{issue-28480.rs => doc-hidden-broken-link-28480.rs} (100%) rename tests/rustdoc/inline_cross/{issue-31948-1.rs => doc-hidden-module-impl-31948-1.rs} (100%) rename tests/rustdoc/inline_cross/{issue-31948-2.rs => doc-hidden-module-impl-31948-2.rs} (100%) rename tests/rustdoc/inline_cross/{issue-31948.rs => doc-hidden-module-impl-31948.rs} (100%) rename tests/rustdoc/inline_cross/{issue-32881.rs => impl-dyn-trait-32881.rs} (100%) rename tests/rustdoc/inline_cross/{issue-33113.rs => impl-ref-33113.rs} (100%) rename tests/rustdoc/inline_cross/{issue-76736-1.rs => rustc-private-76736-1.rs} (100%) rename tests/rustdoc/inline_cross/{issue-76736-2.rs => rustc-private-76736-2.rs} (100%) rename tests/rustdoc/inline_cross/{issue-76736-3.rs => rustc-private-76736-3.rs} (100%) rename tests/rustdoc/inline_cross/{issue-76736-4.rs => rustc-private-76736-4.rs} (100%) rename tests/rustdoc/inline_cross/{issue-24183.method_no_where_self_sized.html => self-sized-bounds-24183.method_no_where_self_sized.html} (100%) rename tests/rustdoc/inline_cross/{issue-24183.rs => self-sized-bounds-24183.rs} (100%) rename tests/rustdoc/inline_local/{issue-32343.rs => doc-no-inline-32343.rs} (100%) rename tests/rustdoc/inline_local/{issue-28537.rs => pub-re-export-28537.rs} (100%) rename tests/rustdoc/intra-doc/{issue-82209.rs => enum-self-82209.rs} (100%) rename tests/rustdoc/intra-doc/{issue-108459.rs => link-same-name-different-disambiguator-108459.rs} (100%) rename tests/rustdoc/intra-doc/{issue-66159.rs => same-name-different-crates-66159.rs} (100%) diff --git a/tests/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs b/tests/rustdoc-ui/intra-doc/auxiliary/issue-103463-aux.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs rename to tests/rustdoc-ui/intra-doc/auxiliary/issue-103463-aux.rs diff --git a/tests/rustdoc/intra-doc/issue-103463.rs b/tests/rustdoc-ui/intra-doc/ice-103463.rs similarity index 94% rename from tests/rustdoc/intra-doc/issue-103463.rs rename to tests/rustdoc-ui/intra-doc/ice-103463.rs index bfe5c4f05d4da..10894282e55b4 100644 --- a/tests/rustdoc/intra-doc/issue-103463.rs +++ b/tests/rustdoc-ui/intra-doc/ice-103463.rs @@ -1,4 +1,5 @@ // https://github.com/rust-lang/rust/issues/103463 +//@ check-pass // The `Trait` is not pulled into the crate resulting in doc links in its methods being resolved. diff --git a/tests/rustdoc/intra-doc/issue-104145.rs b/tests/rustdoc-ui/intra-doc/ice-104145.rs similarity index 95% rename from tests/rustdoc/intra-doc/issue-104145.rs rename to tests/rustdoc-ui/intra-doc/ice-104145.rs index 92c7fa31b4fec..0e403b21c8a18 100644 --- a/tests/rustdoc/intra-doc/issue-104145.rs +++ b/tests/rustdoc-ui/intra-doc/ice-104145.rs @@ -1,4 +1,5 @@ // https://github.com/rust-lang/rust/issues/104145 +//@ check-pass // Doc links in `Trait`'s methods are resolved because it has a local impl. diff --git a/tests/rustdoc/inline_cross/issue-28480.rs b/tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-28480.rs rename to tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs diff --git a/tests/rustdoc/inline_cross/issue-31948-1.rs b/tests/rustdoc/inline_cross/doc-hidden-module-impl-31948-1.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-31948-1.rs rename to tests/rustdoc/inline_cross/doc-hidden-module-impl-31948-1.rs diff --git a/tests/rustdoc/inline_cross/issue-31948-2.rs b/tests/rustdoc/inline_cross/doc-hidden-module-impl-31948-2.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-31948-2.rs rename to tests/rustdoc/inline_cross/doc-hidden-module-impl-31948-2.rs diff --git a/tests/rustdoc/inline_cross/issue-31948.rs b/tests/rustdoc/inline_cross/doc-hidden-module-impl-31948.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-31948.rs rename to tests/rustdoc/inline_cross/doc-hidden-module-impl-31948.rs diff --git a/tests/rustdoc/inline_cross/issue-32881.rs b/tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-32881.rs rename to tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs diff --git a/tests/rustdoc/inline_cross/issue-33113.rs b/tests/rustdoc/inline_cross/impl-ref-33113.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-33113.rs rename to tests/rustdoc/inline_cross/impl-ref-33113.rs diff --git a/tests/rustdoc/inline_cross/issue-76736-1.rs b/tests/rustdoc/inline_cross/rustc-private-76736-1.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-76736-1.rs rename to tests/rustdoc/inline_cross/rustc-private-76736-1.rs diff --git a/tests/rustdoc/inline_cross/issue-76736-2.rs b/tests/rustdoc/inline_cross/rustc-private-76736-2.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-76736-2.rs rename to tests/rustdoc/inline_cross/rustc-private-76736-2.rs diff --git a/tests/rustdoc/inline_cross/issue-76736-3.rs b/tests/rustdoc/inline_cross/rustc-private-76736-3.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-76736-3.rs rename to tests/rustdoc/inline_cross/rustc-private-76736-3.rs diff --git a/tests/rustdoc/inline_cross/issue-76736-4.rs b/tests/rustdoc/inline_cross/rustc-private-76736-4.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-76736-4.rs rename to tests/rustdoc/inline_cross/rustc-private-76736-4.rs diff --git a/tests/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html b/tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html similarity index 100% rename from tests/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html rename to tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html diff --git a/tests/rustdoc/inline_cross/issue-24183.rs b/tests/rustdoc/inline_cross/self-sized-bounds-24183.rs similarity index 100% rename from tests/rustdoc/inline_cross/issue-24183.rs rename to tests/rustdoc/inline_cross/self-sized-bounds-24183.rs diff --git a/tests/rustdoc/inline_local/issue-32343.rs b/tests/rustdoc/inline_local/doc-no-inline-32343.rs similarity index 100% rename from tests/rustdoc/inline_local/issue-32343.rs rename to tests/rustdoc/inline_local/doc-no-inline-32343.rs diff --git a/tests/rustdoc/inline_local/issue-28537.rs b/tests/rustdoc/inline_local/pub-re-export-28537.rs similarity index 100% rename from tests/rustdoc/inline_local/issue-28537.rs rename to tests/rustdoc/inline_local/pub-re-export-28537.rs diff --git a/tests/rustdoc/intra-doc/issue-82209.rs b/tests/rustdoc/intra-doc/enum-self-82209.rs similarity index 100% rename from tests/rustdoc/intra-doc/issue-82209.rs rename to tests/rustdoc/intra-doc/enum-self-82209.rs diff --git a/tests/rustdoc/intra-doc/issue-108459.rs b/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs similarity index 100% rename from tests/rustdoc/intra-doc/issue-108459.rs rename to tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs diff --git a/tests/rustdoc/intra-doc/issue-66159.rs b/tests/rustdoc/intra-doc/same-name-different-crates-66159.rs similarity index 100% rename from tests/rustdoc/intra-doc/issue-66159.rs rename to tests/rustdoc/intra-doc/same-name-different-crates-66159.rs From aeabd4bebe5a129ab226ee4f5e834a9ce001437f Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Wed, 29 Jan 2025 21:26:39 +0100 Subject: [PATCH 04/16] ci: use windows 2025 for i686-mingw --- src/ci/github-actions/jobs.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index c6bc19f9e6c43..9af887096251c 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -43,6 +43,10 @@ runners: os: windows-2022-8core-32gb <<: *base-job + - &job-windows-25-8c + os: windows-2025-8core-32gb + <<: *base-job + - &job-aarch64-linux # Free some disk space to avoid running out of space during the build. free_disk: true @@ -524,7 +528,7 @@ auto: # We are intentionally allowing an old toolchain on this builder (and that's # incompatible with LLVM downloads today). NO_DOWNLOAD_CI_LLVM: 1 - <<: *job-windows-8c + <<: *job-windows-25-8c # x86_64-mingw is split into two jobs to run tests in parallel. - name: x86_64-mingw-1 From 022c0ce94787a76587fd39519f1358acd98fed49 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 30 Jan 2025 09:12:35 +1100 Subject: [PATCH 05/16] Remove `NamedVarMap`. `NamedVarMap` is extremely similar to `ResolveBoundVars`. The former contains two `UnordMap` fields (obscured behind `ItemLocalMap` typedefs). The latter contains two `SortedMap` fields. We construct a `NamedVarMap` and then convert it into a `ResolveBoundVars` by sorting the `UnordMap`s, which is unnecessary busywork. This commit removes `NamedVarMap` and constructs a `ResolveBoundVars` directly. `SortedMap` and `NamedVarMap` have slightly different perf characteristics during construction (e.g. speed of insertion) but this code isn't hot enough for that to matter. A few details to note. - A `FIXME` comment is removed. - The detailed comments on the fields of `NamedVarMap` are copied to `ResolveBoundVars` (which has a single, incorrect comment). - `BoundVarContext::map` is renamed. - `ResolveBoundVars` gets a derived `Default` impl. --- .../src/collect/resolve_bound_vars.rs | 94 +++++-------------- .../src/middle/resolve_bound_vars.rs | 15 ++- 2 files changed, 37 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 72baf5c4b58db..d67b9d3359601 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -12,13 +12,11 @@ use std::ops::ControlFlow; use rustc_ast::visit::walk_list; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_data_structures::sorted_map::SortedMap; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt}; use rustc_hir::{ - self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, ItemLocalMap, - LifetimeName, Node, + self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeName, Node, }; use rustc_macros::extension; use rustc_middle::hir::nested_filter; @@ -26,7 +24,7 @@ use rustc_middle::middle::resolve_bound_vars::*; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_middle::{bug, span_bug}; -use rustc_span::def_id::{DefId, LocalDefId, LocalDefIdMap}; +use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::{Ident, Span, sym}; use tracing::{debug, debug_span, instrument}; @@ -62,33 +60,9 @@ impl ResolvedArg { } } -/// Maps the id of each bound variable reference to the variable decl -/// that it corresponds to. -/// -/// FIXME. This struct gets converted to a `ResolveBoundVars` for -/// actual use. It has the same data, but indexed by `LocalDefId`. This -/// is silly. -#[derive(Debug, Default)] -struct NamedVarMap { - // maps from every use of a named (not anonymous) bound var to a - // `ResolvedArg` describing how that variable is bound - defs: ItemLocalMap, - - // Maps relevant hir items to the bound vars on them. These include: - // - function defs - // - function pointers - // - closures - // - trait refs - // - bound types (like `T` in `for<'a> T<'a>: Foo`) - late_bound_vars: ItemLocalMap>, - - // List captured variables for each opaque type. - opaque_captured_lifetimes: LocalDefIdMap>, -} - struct BoundVarContext<'a, 'tcx> { tcx: TyCtxt<'tcx>, - map: &'a mut NamedVarMap, + rbv: &'a mut ResolveBoundVars, scope: ScopeRef<'a>, } @@ -267,19 +241,12 @@ pub(crate) fn provide(providers: &mut Providers) { /// Computes the `ResolveBoundVars` map that contains data for an entire `Item`. /// You should not read the result of this query directly, but rather use -/// `named_variable_map`, `is_late_bound_map`, etc. +/// `named_variable_map`, `late_bound_vars_map`, etc. #[instrument(level = "debug", skip(tcx))] fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBoundVars { - let mut named_variable_map = NamedVarMap { - defs: Default::default(), - late_bound_vars: Default::default(), - opaque_captured_lifetimes: Default::default(), - }; - let mut visitor = BoundVarContext { - tcx, - map: &mut named_variable_map, - scope: &Scope::Root { opt_parent_item: None }, - }; + let mut rbv = ResolveBoundVars::default(); + let mut visitor = + BoundVarContext { tcx, rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None } }; match tcx.hir_owner_node(local_def_id) { hir::OwnerNode::Item(item) => visitor.visit_item(item), hir::OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item), @@ -299,19 +266,10 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou hir::OwnerNode::Synthetic => unreachable!(), } - let defs = named_variable_map.defs.into_sorted_stable_ord(); - let late_bound_vars = named_variable_map.late_bound_vars.into_sorted_stable_ord(); - let opaque_captured_lifetimes = named_variable_map.opaque_captured_lifetimes; - let rl = ResolveBoundVars { - defs: SortedMap::from_presorted_elements(defs), - late_bound_vars: SortedMap::from_presorted_elements(late_bound_vars), - opaque_captured_lifetimes, - }; - - debug!(?rl.defs); - debug!(?rl.late_bound_vars); - debug!(?rl.opaque_captured_lifetimes); - rl + debug!(?rbv.defs); + debug!(?rbv.late_bound_vars); + debug!(?rbv.opaque_captured_lifetimes); + rbv } fn late_arg_as_bound_arg<'tcx>( @@ -404,7 +362,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { Scope::Binder { hir_id, .. } => { // Nested poly trait refs have the binders concatenated let mut full_binders = - self.map.late_bound_vars.entry(hir_id.local_id).or_default().clone(); + self.rbv.late_bound_vars.get_mut_or_insert_default(hir_id.local_id).clone(); full_binders.extend(supertrait_bound_vars); break (full_binders, BinderScopeType::Concatenating); } @@ -646,7 +604,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { let captures = captures.into_inner().into_iter().collect(); debug!(?captures); - self.map.opaque_captured_lifetimes.insert(opaque.def_id, captures); + self.rbv.opaque_captured_lifetimes.insert(opaque.def_id, captures); } #[instrument(level = "debug", skip(self))] @@ -848,7 +806,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { hir::TyKind::Ref(lifetime_ref, ref mt) => { self.visit_lifetime(lifetime_ref); let scope = Scope::ObjectLifetimeDefault { - lifetime: self.map.defs.get(&lifetime_ref.hir_id.local_id).cloned(), + lifetime: self.rbv.defs.get(&lifetime_ref.hir_id.local_id).cloned(), s: self.scope, }; self.with(scope, |this| this.visit_ty_unambig(mt.ty)); @@ -966,7 +924,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { let bound_vars: Vec<_> = self.tcx.fn_sig(sig_id).skip_binder().bound_vars().iter().collect(); let hir_id = self.tcx.local_def_id_to_hir_id(def_id); - self.map.late_bound_vars.insert(hir_id.local_id, bound_vars); + self.rbv.late_bound_vars.insert(hir_id.local_id, bound_vars); } self.visit_fn_like_elision(fd.inputs, output, matches!(fk, intravisit::FnKind::Closure)); intravisit::walk_fn_kind(self, fk); @@ -1140,8 +1098,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { where F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>), { - let BoundVarContext { tcx, map, .. } = self; - let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope }; + let BoundVarContext { tcx, rbv, .. } = self; + let mut this = BoundVarContext { tcx: *tcx, rbv, scope: &wrap_scope }; let span = debug_span!("scope", scope = ?this.scope.debug_truncated()); { let _enter = span.enter(); @@ -1150,10 +1108,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec) { - if let Some(old) = self.map.late_bound_vars.insert(hir_id.local_id, binder) { + if let Some(old) = self.rbv.late_bound_vars.insert(hir_id.local_id, binder) { bug!( "overwrote bound vars for {hir_id:?}:\nold={old:?}\nnew={:?}", - self.map.late_bound_vars[&hir_id.local_id] + self.rbv.late_bound_vars[&hir_id.local_id] ) } } @@ -1597,9 +1555,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { kind.descr(param_def_id.to_def_id()) ), }; - self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar)); + self.rbv.defs.insert(hir_id.local_id, ResolvedArg::Error(guar)); } else { - self.map.defs.insert(hir_id.local_id, def); + self.rbv.defs.insert(hir_id.local_id, def); } return; } @@ -1632,7 +1590,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { bug!("unexpected def-kind: {}", kind.descr(param_def_id.to_def_id())) } }); - self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar)); + self.rbv.defs.insert(hir_id.local_id, ResolvedArg::Error(guar)); return; } Scope::Root { .. } => break, @@ -1725,7 +1683,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } }; - let map = &self.map; + let rbv = &self.rbv; let generics = self.tcx.generics_of(def_id); // `type_def_id` points to an item, so there is nothing to inherit generics from. @@ -1744,7 +1702,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // This index can be used with `generic_args` since `parent_count == 0`. let index = generics.param_def_id_to_index[¶m_def_id] as usize; generic_args.args.get(index).and_then(|arg| match arg { - GenericArg::Lifetime(lt) => map.defs.get(<.hir_id.local_id).copied(), + GenericArg::Lifetime(lt) => rbv.defs.get(<.hir_id.local_id).copied(), _ => None, }) } @@ -2042,7 +2000,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: ResolvedArg) { debug!(span = ?lifetime_ref.ident.span); - self.map.defs.insert(lifetime_ref.hir_id.local_id, def); + self.rbv.defs.insert(lifetime_ref.hir_id.local_id, def); } // When we have a return type notation type in a where clause, like @@ -2197,7 +2155,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // See where these vars are used in `HirTyLowerer::lower_ty_maybe_return_type_notation`. // And this is exercised in: // `tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs`. - let existing_bound_vars = self.map.late_bound_vars.get_mut(&hir_id.local_id).unwrap(); + let existing_bound_vars = self.rbv.late_bound_vars.get_mut(&hir_id.local_id).unwrap(); let existing_bound_vars_saved = existing_bound_vars.clone(); existing_bound_vars.extend(bound_vars); self.record_late_bound_vars(item_segment.hir_id, existing_bound_vars_saved); diff --git a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs index 111ac990bc77e..51a079e8bc122 100644 --- a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs +++ b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs @@ -45,15 +45,22 @@ pub enum ObjectLifetimeDefault { Param(DefId), } -/// Maps the id of each lifetime reference to the lifetime decl +/// Maps the id of each bound variable reference to the variable decl /// that it corresponds to. -#[derive(HashStable, Debug)] +#[derive(Debug, Default, HashStable)] pub struct ResolveBoundVars { - /// Maps from every use of a named (not anonymous) lifetime to a - /// `Region` describing how that region is bound + // Maps from every use of a named (not anonymous) bound var to a + // `ResolvedArg` describing how that variable is bound. pub defs: SortedMap, + // Maps relevant hir items to the bound vars on them. These include: + // - function defs + // - function pointers + // - closures + // - trait refs + // - bound types (like `T` in `for<'a> T<'a>: Foo`) pub late_bound_vars: SortedMap>, + // List captured variables for each opaque type. pub opaque_captured_lifetimes: LocalDefIdMap>, } From d78193381249740d769970d4ec453c5bc265f082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 28 Jan 2025 08:53:19 +0000 Subject: [PATCH 06/16] add constraint graph to polonius MIR dump --- compiler/rustc_borrowck/src/polonius/dump.rs | 110 +++++++++++++++++-- 1 file changed, 101 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs index f71e6f3e6f3a6..6d32ee17f4c2a 100644 --- a/compiler/rustc_borrowck/src/polonius/dump.rs +++ b/compiler/rustc_borrowck/src/polonius/dump.rs @@ -1,17 +1,19 @@ use std::io; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_index::IndexVec; use rustc_middle::mir::pretty::{ PassWhere, PrettyPrintMirOptions, create_dump_file, dump_enabled, dump_mir_to_writer, }; -use rustc_middle::mir::{Body, ClosureRegionRequirements}; +use rustc_middle::mir::{Body, ClosureRegionRequirements, Location}; use rustc_middle::ty::{RegionVid, TyCtxt}; +use rustc_mir_dataflow::points::PointIndex; use rustc_session::config::MirIncludeSpans; use crate::borrow_set::BorrowSet; use crate::constraints::OutlivesConstraint; use crate::polonius::{LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet}; +use crate::region_infer::values::LivenessValues; use crate::type_check::Locations; use crate::{BorrowckInferCtxt, RegionInferenceContext}; @@ -80,14 +82,27 @@ fn emit_polonius_dump<'tcx>( body, regioncx, borrow_set, - localized_outlives_constraints, + &localized_outlives_constraints, closure_region_requirements, out, )?; writeln!(out, "")?; writeln!(out, "")?; - // Section 2: mermaid visualization of the CFG. + // Section 2: mermaid visualization of the polonius constraint graph. + writeln!(out, "
")?; + writeln!(out, "Polonius constraint graph")?; + writeln!(out, "
")?;
+    let edge_count = emit_mermaid_constraint_graph(
+        borrow_set,
+        regioncx.liveness_constraints(),
+        &localized_outlives_constraints,
+        out,
+    )?;
+    writeln!(out, "
")?; + writeln!(out, "
")?; + + // Section 3: mermaid visualization of the CFG. writeln!(out, "
")?; writeln!(out, "Control-flow graph")?; writeln!(out, "
")?;
@@ -95,7 +110,7 @@ fn emit_polonius_dump<'tcx>(
     writeln!(out, "
")?; writeln!(out, "
")?; - // Section 3: mermaid visualization of the NLL region graph. + // Section 4: mermaid visualization of the NLL region graph. writeln!(out, "
")?; writeln!(out, "NLL regions")?; writeln!(out, "
")?;
@@ -103,7 +118,7 @@ fn emit_polonius_dump<'tcx>(
     writeln!(out, "
")?; writeln!(out, "
")?; - // Section 4: mermaid visualization of the NLL SCC graph. + // Section 5: mermaid visualization of the NLL SCC graph. writeln!(out, "
")?; writeln!(out, "NLL SCCs")?; writeln!(out, "
")?;
@@ -117,7 +132,11 @@ fn emit_polonius_dump<'tcx>(
         ""
     )?;
     writeln!(out, "")?;
     writeln!(out, "")?;
@@ -132,7 +151,7 @@ fn emit_html_mir<'tcx>(
     body: &Body<'tcx>,
     regioncx: &RegionInferenceContext<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
-    localized_outlives_constraints: LocalizedOutlivesConstraintSet,
+    localized_outlives_constraints: &LocalizedOutlivesConstraintSet,
     closure_region_requirements: &Option>,
     out: &mut dyn io::Write,
 ) -> io::Result<()> {
@@ -160,7 +179,7 @@ fn emit_html_mir<'tcx>(
                 regioncx,
                 closure_region_requirements,
                 borrow_set,
-                &localized_outlives_constraints,
+                localized_outlives_constraints,
                 pass_where,
                 out,
             )
@@ -392,3 +411,76 @@ fn emit_mermaid_nll_sccs<'tcx>(
 
     Ok(())
 }
+
+/// Emits a mermaid flowchart of the polonius localized outlives constraints, with subgraphs per
+/// region, and loan introductions.
+fn emit_mermaid_constraint_graph<'tcx>(
+    borrow_set: &BorrowSet<'tcx>,
+    liveness: &LivenessValues,
+    localized_outlives_constraints: &LocalizedOutlivesConstraintSet,
+    out: &mut dyn io::Write,
+) -> io::Result {
+    let location_name = |location: Location| {
+        // A MIR location looks like `bb5[2]`. As that is not a syntactically valid mermaid node id,
+        // transform it into `BB5_2`.
+        format!("BB{}_{}", location.block.index(), location.statement_index)
+    };
+    let region_name = |region: RegionVid| format!("'{}", region.index());
+    let node_name = |region: RegionVid, point: PointIndex| {
+        let location = liveness.location_from_point(point);
+        format!("{}_{}", region_name(region), location_name(location))
+    };
+
+    // The mermaid chart type: a top-down flowchart, which supports subgraphs.
+    writeln!(out, "flowchart TD")?;
+
+    // The loans subgraph: a node per loan.
+    writeln!(out, "    subgraph \"Loans\"")?;
+    for loan_idx in 0..borrow_set.len() {
+        writeln!(out, "        L{loan_idx}")?;
+    }
+    writeln!(out, "    end\n")?;
+
+    // And an edge from that loan node to where it enters the constraint graph.
+    for (loan_idx, loan) in borrow_set.iter_enumerated() {
+        writeln!(
+            out,
+            "    L{} --> {}_{}",
+            loan_idx.index(),
+            region_name(loan.region),
+            location_name(loan.reserve_location),
+        )?;
+    }
+    writeln!(out, "")?;
+
+    // The regions subgraphs containing the region/point nodes.
+    let mut points_per_region: FxIndexMap> =
+        FxIndexMap::default();
+    for constraint in &localized_outlives_constraints.outlives {
+        points_per_region.entry(constraint.source).or_default().insert(constraint.from);
+        points_per_region.entry(constraint.target).or_default().insert(constraint.to);
+    }
+    for (region, points) in points_per_region {
+        writeln!(out, "    subgraph \"{}\"", region_name(region))?;
+        for point in points {
+            writeln!(out, "        {}", node_name(region, point))?;
+        }
+        writeln!(out, "    end\n")?;
+    }
+
+    // The constraint graph edges.
+    for constraint in &localized_outlives_constraints.outlives {
+        // FIXME: add killed loans and constraint kind as edge labels.
+        writeln!(
+            out,
+            "    {} --> {}",
+            node_name(constraint.source, constraint.from),
+            node_name(constraint.target, constraint.to),
+        )?;
+    }
+
+    // Return the number of edges: this is the biggest graph in the dump and its edge count will be
+    // mermaid's max edge count to support.
+    let edge_count = borrow_set.len() + localized_outlives_constraints.outlives.len();
+    Ok(edge_count)
+}

From 23fb08bb532ed8a9b4947c213ae3fc0862b2b254 Mon Sep 17 00:00:00 2001
From: Hans Wennborg 
Date: Thu, 30 Jan 2025 11:18:36 +0100
Subject: [PATCH 07/16] LLVM changed the nocapture attribute to captures(none)

This updates RustWrapper.cpp and tests after
https://github.com/llvm/llvm-project/pull/123181
---
 .../rustc_llvm/llvm-wrapper/RustWrapper.cpp   | 11 ++++++++++
 tests/codegen/addr-of-mutate.rs               |  6 +++---
 tests/codegen/cast-target-abi.rs              |  2 +-
 tests/codegen/function-arguments.rs           |  4 ++--
 tests/codegen/i128-x86-align.rs               | 21 ++++++++++++-------
 .../loongarch-abi/loongarch64-lp64d-abi.rs    |  4 ++--
 tests/codegen/packed.rs                       |  4 ++--
 tests/codegen/riscv-abi/riscv64-lp64d-abi.rs  |  2 +-
 8 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 35186778671bc..858251ff9c8c9 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -319,7 +319,11 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
   case LLVMRustAttributeKind::NoAlias:
     return Attribute::NoAlias;
   case LLVMRustAttributeKind::NoCapture:
+#if LLVM_VERSION_GE(21, 0)
+    report_fatal_error("NoCapture doesn't exist in LLVM 21");
+#else
     return Attribute::NoCapture;
+#endif
   case LLVMRustAttributeKind::NoCfCheck:
     return Attribute::NoCfCheck;
   case LLVMRustAttributeKind::NoInline:
@@ -431,6 +435,13 @@ extern "C" void LLVMRustEraseInstFromParent(LLVMValueRef Instr) {
 
 extern "C" LLVMAttributeRef
 LLVMRustCreateAttrNoValue(LLVMContextRef C, LLVMRustAttributeKind RustAttr) {
+#if LLVM_VERSION_GE(21, 0)
+  // LLVM 21 replaced the NoCapture attribute with Captures(none).
+  if (RustAttr == LLVMRustAttributeKind::NoCapture) {
+    return wrap(Attribute::get(*unwrap(C), Attribute::Captures,
+                               CaptureInfo::none().toIntValue()));
+  }
+#endif
   return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr)));
 }
 
diff --git a/tests/codegen/addr-of-mutate.rs b/tests/codegen/addr-of-mutate.rs
index f10f01274b1f2..14bc4b8ab28ce 100644
--- a/tests/codegen/addr-of-mutate.rs
+++ b/tests/codegen/addr-of-mutate.rs
@@ -5,7 +5,7 @@
 // Test for the absence of `readonly` on the argument when it is mutated via `&raw const`.
 // See .
 
-// CHECK: i8 @foo(ptr noalias nocapture noundef align 1 dereferenceable(128) %x)
+// CHECK: i8 @foo(ptr noalias{{( nocapture)?}} noundef align 1{{( captures\(none\))?}} dereferenceable(128) %x)
 #[no_mangle]
 pub fn foo(x: [u8; 128]) -> u8 {
     let ptr = core::ptr::addr_of!(x).cast_mut();
@@ -15,7 +15,7 @@ pub fn foo(x: [u8; 128]) -> u8 {
     x[0]
 }
 
-// CHECK: i1 @second(ptr noalias nocapture noundef align {{[0-9]+}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
+// CHECK: i1 @second(ptr noalias{{( nocapture)?}} noundef align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
 #[no_mangle]
 pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
     let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut();
@@ -24,7 +24,7 @@ pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
 }
 
 // If going through a deref (and there are no other mutating accesses), then `readonly` is fine.
-// CHECK: i1 @third(ptr noalias nocapture noundef readonly align {{[0-9]+}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
+// CHECK: i1 @third(ptr noalias{{( nocapture)?}} noundef readonly align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
 #[no_mangle]
 pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
     let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut();
diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs
index db76aae3dd005..b3a35cbf3b1c6 100644
--- a/tests/codegen/cast-target-abi.rs
+++ b/tests/codegen/cast-target-abi.rs
@@ -392,7 +392,7 @@ pub fn call_fiveu16s() {
 }
 
 // CHECK-LABEL: @return_fiveu16s
-// CHECK-SAME: (ptr {{.+}} sret([10 x i8]) align [[RUST_ALIGN:2]] dereferenceable(10) [[RET_PTR:%.+]])
+// CHECK-SAME: (ptr {{.+}} sret([10 x i8]) align [[RUST_ALIGN:2]] {{.*}}dereferenceable(10) [[RET_PTR:%.+]])
 #[no_mangle]
 pub fn return_fiveu16s() -> FiveU16s {
     // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs
index 503799d3ed22d..1a211dfe096b3 100644
--- a/tests/codegen/function-arguments.rs
+++ b/tests/codegen/function-arguments.rs
@@ -135,7 +135,7 @@ pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {}
 #[no_mangle]
 pub fn notunpin_borrow(_: &NotUnpin) {}
 
-// CHECK: @indirect_struct(ptr noalias nocapture noundef readonly align 4 dereferenceable(32) %_1)
+// CHECK: @indirect_struct(ptr noalias{{( nocapture)?}} noundef readonly align 4{{( captures\(none\))?}} dereferenceable(32) %_1)
 #[no_mangle]
 pub fn indirect_struct(_: S) {}
 
@@ -198,7 +198,7 @@ pub fn notunpin_box(x: Box) -> Box {
     x
 }
 
-// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias nocapture noundef{{( writable)?}} sret([32 x i8]) align 4 dereferenceable(32){{( %_0)?}})
+// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias{{( nocapture)?}} noundef{{( writable)?}} sret([32 x i8]) align 4{{( captures\(none\))?}} dereferenceable(32){{( %_0)?}})
 #[no_mangle]
 pub fn struct_return() -> S {
     S { _field: [0, 0, 0, 0, 0, 0, 0, 0] }
diff --git a/tests/codegen/i128-x86-align.rs b/tests/codegen/i128-x86-align.rs
index 6b1da445c40ca..ac101b72513dd 100644
--- a/tests/codegen/i128-x86-align.rs
+++ b/tests/codegen/i128-x86-align.rs
@@ -19,8 +19,10 @@ pub struct ScalarPair {
 #[no_mangle]
 pub fn load(x: &ScalarPair) -> ScalarPair {
     // CHECK-LABEL: @load(
-    // CHECK-SAME: sret([32 x i8]) align 16 dereferenceable(32) %_0,
-    // CHECK-SAME: align 16 dereferenceable(32) %x
+    // CHECK-SAME: sret([32 x i8]) align 16
+    // CHECK-SAME: dereferenceable(32) %_0,
+    // CHECK-SAME: align 16
+    // CHECK-SAME: dereferenceable(32) %x
     // CHECK:      [[A:%.*]] = load i32, ptr %x, align 16
     // CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr %x, i64 16
     // CHECK-NEXT: [[B:%.*]] = load i128, ptr [[GEP]], align 16
@@ -34,7 +36,8 @@ pub fn load(x: &ScalarPair) -> ScalarPair {
 #[no_mangle]
 pub fn store(x: &mut ScalarPair) {
     // CHECK-LABEL: @store(
-    // CHECK-SAME: align 16 dereferenceable(32) %x
+    // CHECK-SAME: align 16
+    // CHECK-SAME: dereferenceable(32) %x
     // CHECK:      store i32 1, ptr %x, align 16
     // CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr %x, i64 16
     // CHECK-NEXT: store i128 2, ptr [[GEP]], align 16
@@ -55,8 +58,10 @@ pub fn alloca() {
 #[no_mangle]
 pub fn load_volatile(x: &ScalarPair) -> ScalarPair {
     // CHECK-LABEL: @load_volatile(
-    // CHECK-SAME: sret([32 x i8]) align 16 dereferenceable(32) %_0,
-    // CHECK-SAME: align 16 dereferenceable(32) %x
+    // CHECK-SAME: sret([32 x i8]) align 16
+    // CHECK-SAME: dereferenceable(32) %_0,
+    // CHECK-SAME: align 16
+    // CHECK-SAME: dereferenceable(32) %x
     // CHECK:      [[LOAD:%.*]] = load volatile %ScalarPair, ptr %x, align 16
     // CHECK-NEXT: store %ScalarPair [[LOAD]], ptr %_0, align 16
     // CHECK-NEXT: ret void
@@ -66,7 +71,8 @@ pub fn load_volatile(x: &ScalarPair) -> ScalarPair {
 #[no_mangle]
 pub fn transmute(x: ScalarPair) -> (std::mem::MaybeUninit, i128) {
     // CHECK-LABEL: @transmute(
-    // CHECK-SAME:  sret([32 x i8]) align 16 dereferenceable(32) %_0,
+    // CHECK-SAME:  sret([32 x i8]) align 16
+    // CHECK-SAME:  dereferenceable(32) %_0,
     // CHECK-SAME:  i32 noundef %x.0, i128 noundef %x.1
     // CHECK:       store i32 %x.0, ptr %_0, align 16
     // CHECK-NEXT:  [[GEP:%.*]] = getelementptr inbounds i8, ptr %_0, i64 16
@@ -86,7 +92,8 @@ pub struct Struct {
 #[no_mangle]
 pub fn store_struct(x: &mut Struct) {
     // CHECK-LABEL: @store_struct(
-    // CHECK-SAME: align 16 dereferenceable(32) %x
+    // CHECK-SAME: align 16
+    // CHECK-SAME: dereferenceable(32) %x
     // CHECK:      [[TMP:%.*]] = alloca [32 x i8], align 16
     // CHECK:      store i32 1, ptr [[TMP]], align 16
     // CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[TMP]], i64 4
diff --git a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs
index cba1a980caa72..b147d01b38e32 100644
--- a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs
+++ b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs
@@ -259,11 +259,11 @@ pub struct IntDoubleInt {
     c: i32,
 }
 
-// CHECK: define void @f_int_double_int_s_arg(ptr noalias nocapture noundef align 8 dereferenceable(24) %a)
+// CHECK: define void @f_int_double_int_s_arg(ptr noalias{{( nocapture)?}} noundef align 8{{( captures\(none\))?}} dereferenceable(24) %a)
 #[no_mangle]
 pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
 
-// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias nocapture noundef{{( writable)?}} sret([24 x i8]) align 8 dereferenceable(24) %_0)
+// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias{{( nocapture)?}} noundef{{( writable)?}} sret([24 x i8]) align 8{{( captures\(none\))?}} dereferenceable(24) %_0)
 #[no_mangle]
 pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
     IntDoubleInt { a: 1, b: 2., c: 3 }
diff --git a/tests/codegen/packed.rs b/tests/codegen/packed.rs
index 790d618b2eade..66df978d48ca2 100644
--- a/tests/codegen/packed.rs
+++ b/tests/codegen/packed.rs
@@ -52,7 +52,7 @@ pub struct BigPacked2 {
 #[no_mangle]
 pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
     // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8]
-    // CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
+    // CHECK: call void %{{.*}}(ptr{{( captures(none))?}} noalias{{( nocapture)?}} noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
     // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
     // check that calls whose destination is a field of a packed struct
     // go through an alloca rather than calling the function with an
@@ -64,7 +64,7 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
 #[no_mangle]
 pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
     // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8]
-    // CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
+    // CHECK: call void %{{.*}}(ptr{{( captures(none))?}} noalias{{( nocapture)?}} noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
     // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
     // check that calls whose destination is a field of a packed struct
     // go through an alloca rather than calling the function with an
diff --git a/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs
index bcd9b0eae71d4..c14d5c01450bc 100644
--- a/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs
+++ b/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs
@@ -263,7 +263,7 @@ pub struct IntDoubleInt {
 #[no_mangle]
 pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
 
-// CHECK: define void @f_ret_int_double_int_s(ptr {{.*}} sret([24 x i8]) align 8 dereferenceable(24) %_0)
+// CHECK: define void @f_ret_int_double_int_s(ptr {{.*}} sret([24 x i8]) align 8 {{.*}}dereferenceable(24) %_0)
 #[no_mangle]
 pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
     IntDoubleInt { a: 1, b: 2., c: 3 }

From 9788aa0cefab1914b3df257c529a0089e01f2e5c Mon Sep 17 00:00:00 2001
From: lcnr 
Date: Mon, 20 Jan 2025 16:39:13 +0100
Subject: [PATCH 08/16] remove redundant test

---
 tests/ui/traits/sized-coniductive.rs | 14 --------------
 1 file changed, 14 deletions(-)
 delete mode 100644 tests/ui/traits/sized-coniductive.rs

diff --git a/tests/ui/traits/sized-coniductive.rs b/tests/ui/traits/sized-coniductive.rs
deleted file mode 100644
index 5f63b166f988b..0000000000000
--- a/tests/ui/traits/sized-coniductive.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ check-pass
-// https://github.com/rust-lang/rust/issues/129541
-
-#[derive(Clone)]
-struct Test {
-    field: std::borrow::Cow<'static, [Self]>,
-}
-
-#[derive(Clone)]
-struct Hello {
-    a: <[Hello] as std::borrow::ToOwned>::Owned,
-}
-
-fn main(){}

From 12f86ee7f32efe58eab175a4fe89b30b2068fa3e Mon Sep 17 00:00:00 2001
From: lcnr 
Date: Mon, 20 Jan 2025 16:42:03 +0100
Subject: [PATCH 09/16] move non_lifetime_binder tests

---
 .../type-alias-impl-trait/non-lifetime-binder-in-constraint.rs    | 0
 .../non-lifetime-binder-in-constraint.stderr                      | 0
 .../type-alias-impl-trait/non-lifetime-binder.rs                  | 0
 .../type-alias-impl-trait/non-lifetime-binder.stderr              | 0
 4 files changed, 0 insertions(+), 0 deletions(-)
 rename tests/ui/{ => traits/non_lifetime_binders}/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs (100%)
 rename tests/ui/{ => traits/non_lifetime_binders}/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr (100%)
 rename tests/ui/{ => traits/non_lifetime_binders}/type-alias-impl-trait/non-lifetime-binder.rs (100%)
 rename tests/ui/{ => traits/non_lifetime_binders}/type-alias-impl-trait/non-lifetime-binder.stderr (100%)

diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
similarity index 100%
rename from tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
rename to tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
similarity index 100%
rename from tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
rename to tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.rs
similarity index 100%
rename from tests/ui/type-alias-impl-trait/non-lifetime-binder.rs
rename to tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.rs
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.stderr
similarity index 100%
rename from tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr
rename to tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.stderr

From fef480f4b890ae50dc818036fc0900238e5339b2 Mon Sep 17 00:00:00 2001
From: lcnr 
Date: Mon, 20 Jan 2025 16:42:30 +0100
Subject: [PATCH 10/16] error pattern to correct line

---
 tests/ui/generic-associated-types/issue-90014-tait2.rs     | 3 +--
 tests/ui/generic-associated-types/issue-90014-tait2.stderr | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.rs b/tests/ui/generic-associated-types/issue-90014-tait2.rs
index ef54a89aaae58..3f7a9ff63c312 100644
--- a/tests/ui/generic-associated-types/issue-90014-tait2.rs
+++ b/tests/ui/generic-associated-types/issue-90014-tait2.rs
@@ -3,8 +3,6 @@
 //! Unfortunately we don't even reach opaque type collection, as we ICE in typeck before that.
 //! See #109281 for the original report.
 //@ edition:2018
-//@ error-pattern: expected generic lifetime parameter, found `'a`
-
 #![feature(type_alias_impl_trait)]
 
 use std::future::Future;
@@ -24,6 +22,7 @@ impl<'x, T: 'x> Trait<'x> for (T,) {
 impl Foo<'_> {
     fn make_fut(&self) -> Box Trait<'a, Thing = Fut<'a>>> {
         Box::new((async { () },))
+        //~^ ERROR expected generic lifetime parameter, found `'a`
     }
 }
 
diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.stderr b/tests/ui/generic-associated-types/issue-90014-tait2.stderr
index be6f4272ce18c..aa427d42649ae 100644
--- a/tests/ui/generic-associated-types/issue-90014-tait2.stderr
+++ b/tests/ui/generic-associated-types/issue-90014-tait2.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/issue-90014-tait2.rs:26:9
+  --> $DIR/issue-90014-tait2.rs:24:9
    |
 LL | type Fut<'a> = impl Future;
    |          -- this generic parameter must be used with a generic lifetime parameter

From 8c078fde36b8b7d6757ff2bea271ecb2a85cf2eb Mon Sep 17 00:00:00 2001
From: lcnr 
Date: Mon, 20 Jan 2025 16:42:50 +0100
Subject: [PATCH 11/16] merge tests

---
 .../129541-recursive-struct-and-array-impl.rs | 23 -------------------
 .../solver-cycles/129541-recursive-struct.rs  |  5 ++++
 2 files changed, 5 insertions(+), 23 deletions(-)
 delete mode 100644 tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs

diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs
deleted file mode 100644
index defb39aae06d4..0000000000000
--- a/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Regression test for #129541
-
-//@ check-pass
-
-trait Bound {}
-trait Normalize {
-    type Assoc;
-}
-
-impl Normalize for T {
-    type Assoc = T;
-}
-
-impl Normalize for [T] {
-    type Assoc = T;
-}
-
-impl Bound for Hello {}
-struct Hello {
-    a: <[Hello] as Normalize>::Assoc,
-}
-
-fn main() {}
diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
index d4339dd54d6c7..4fbcbefec913b 100644
--- a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
+++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
@@ -1,5 +1,6 @@
 // Regression test for #129541
 
+//@ revisions: unique multiple
 //@ check-pass
 
 trait Bound {}
@@ -7,6 +8,10 @@ trait Normalize {
     type Assoc;
 }
 
+#[cfg(multiple)]
+impl Normalize for T {
+    type Assoc = T;
+}
 impl Normalize for [T] {
     type Assoc = T;
 }

From fa6b95fc4e2e0f36d52cea164544651049038074 Mon Sep 17 00:00:00 2001
From: lcnr 
Date: Mon, 20 Jan 2025 16:42:58 +0100
Subject: [PATCH 12/16] update comment

---
 tests/ui/wf/wf-trait-default-fn-ret.rs     | 3 +--
 tests/ui/wf/wf-trait-default-fn-ret.stderr | 4 ++--
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/tests/ui/wf/wf-trait-default-fn-ret.rs b/tests/ui/wf/wf-trait-default-fn-ret.rs
index 2103dae8d233a..a7f83dcf678aa 100644
--- a/tests/ui/wf/wf-trait-default-fn-ret.rs
+++ b/tests/ui/wf/wf-trait-default-fn-ret.rs
@@ -1,5 +1,4 @@
-// Check that we test WF conditions for fn arguments. Because the
-// current code is so goofy, this is only a warning for now.
+// Check that we test WF conditions for fn arguments.
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
diff --git a/tests/ui/wf/wf-trait-default-fn-ret.stderr b/tests/ui/wf/wf-trait-default-fn-ret.stderr
index f749ac7b1b3e6..f0d1b55edc49a 100644
--- a/tests/ui/wf/wf-trait-default-fn-ret.stderr
+++ b/tests/ui/wf/wf-trait-default-fn-ret.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `Self: Eq` is not satisfied
-  --> $DIR/wf-trait-default-fn-ret.rs:11:22
+  --> $DIR/wf-trait-default-fn-ret.rs:10:22
    |
 LL |     fn bar(&self) -> Bar {
    |                      ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
    |
 note: required by a bound in `Bar`
-  --> $DIR/wf-trait-default-fn-ret.rs:8:14
+  --> $DIR/wf-trait-default-fn-ret.rs:7:14
    |
 LL | struct Bar { value: Box }
    |              ^^ required by this bound in `Bar`

From 6e457b88eb6058267794ab6dbf595cf8f183368c Mon Sep 17 00:00:00 2001
From: Hans Wennborg 
Date: Thu, 30 Jan 2025 12:30:14 +0100
Subject: [PATCH 13/16] use Attribute::getWithCaptureInfo

---
 compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 858251ff9c8c9..545422682f0ba 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -438,8 +438,7 @@ LLVMRustCreateAttrNoValue(LLVMContextRef C, LLVMRustAttributeKind RustAttr) {
 #if LLVM_VERSION_GE(21, 0)
   // LLVM 21 replaced the NoCapture attribute with Captures(none).
   if (RustAttr == LLVMRustAttributeKind::NoCapture) {
-    return wrap(Attribute::get(*unwrap(C), Attribute::Captures,
-                               CaptureInfo::none().toIntValue()));
+    return wrap(Attribute::getWithCaptureInfo(*unwrap(C), CaptureInfo::none()));
   }
 #endif
   return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr)));

From 6b699ccee499949b5e4e222976e1ac8887412a5c Mon Sep 17 00:00:00 2001
From: Ralf Jung 
Date: Thu, 30 Jan 2025 13:44:13 +0100
Subject: [PATCH 14/16] float::min/max: mention the non-determinism around
 signed 0

---
 library/core/src/num/f128.rs | 6 ++++--
 library/core/src/num/f16.rs  | 6 ++++--
 library/core/src/num/f32.rs  | 6 ++++--
 library/core/src/num/f64.rs  | 6 ++++--
 4 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 8fb1588e60b35..5e45974b3d422 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -670,7 +670,8 @@ impl f128 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmax.
+    /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// #![feature(f128)]
@@ -696,7 +697,8 @@ impl f128 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids minNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmin.
+    /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// #![feature(f128)]
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index 8c2af74b8f842..e3176cd168852 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -662,7 +662,8 @@ impl f16 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmax.
+    /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// #![feature(f16)]
@@ -687,7 +688,8 @@ impl f16 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids minNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmin.
+    /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// #![feature(f16)]
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 817bedbd44f98..4d42997369ffb 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -874,7 +874,8 @@ impl f32 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmax.
+    /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// let x = 1.0f32;
@@ -895,7 +896,8 @@ impl f32 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids minNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmin.
+    /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// let x = 1.0f32;
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 1b0651a0def07..907971d303ffc 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -892,7 +892,8 @@ impl f64 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmax.
+    /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// let x = 1.0_f64;
@@ -913,7 +914,8 @@ impl f64 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids minNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmin.
+    /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// let x = 1.0_f64;

From a1a55a2e0abccb31d61ecd32b197a6f8ff287e51 Mon Sep 17 00:00:00 2001
From: Michael Howell 
Date: Thu, 30 Jan 2025 12:05:31 -0700
Subject: [PATCH 15/16] Give 104145, 103463, and 31948 more descriptive names

---
 .../{ice-104145.rs => ice-extern-trait-local-impl-104145.rs}      | 0
 .../intra-doc/{ice-103463.rs => ice-priv-use-103463.rs}           | 0
 ...en-module-impl-31948-1.rs => doc-reachability-impl-31948-1.rs} | 0
 ...en-module-impl-31948-2.rs => doc-reachability-impl-31948-2.rs} | 0
 ...hidden-module-impl-31948.rs => doc-reachability-impl-31948.rs} | 0
 5 files changed, 0 insertions(+), 0 deletions(-)
 rename tests/rustdoc-ui/intra-doc/{ice-104145.rs => ice-extern-trait-local-impl-104145.rs} (100%)
 rename tests/rustdoc-ui/intra-doc/{ice-103463.rs => ice-priv-use-103463.rs} (100%)
 rename tests/rustdoc/inline_cross/{doc-hidden-module-impl-31948-1.rs => doc-reachability-impl-31948-1.rs} (100%)
 rename tests/rustdoc/inline_cross/{doc-hidden-module-impl-31948-2.rs => doc-reachability-impl-31948-2.rs} (100%)
 rename tests/rustdoc/inline_cross/{doc-hidden-module-impl-31948.rs => doc-reachability-impl-31948.rs} (100%)

diff --git a/tests/rustdoc-ui/intra-doc/ice-104145.rs b/tests/rustdoc-ui/intra-doc/ice-extern-trait-local-impl-104145.rs
similarity index 100%
rename from tests/rustdoc-ui/intra-doc/ice-104145.rs
rename to tests/rustdoc-ui/intra-doc/ice-extern-trait-local-impl-104145.rs
diff --git a/tests/rustdoc-ui/intra-doc/ice-103463.rs b/tests/rustdoc-ui/intra-doc/ice-priv-use-103463.rs
similarity index 100%
rename from tests/rustdoc-ui/intra-doc/ice-103463.rs
rename to tests/rustdoc-ui/intra-doc/ice-priv-use-103463.rs
diff --git a/tests/rustdoc/inline_cross/doc-hidden-module-impl-31948-1.rs b/tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs
similarity index 100%
rename from tests/rustdoc/inline_cross/doc-hidden-module-impl-31948-1.rs
rename to tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs
diff --git a/tests/rustdoc/inline_cross/doc-hidden-module-impl-31948-2.rs b/tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs
similarity index 100%
rename from tests/rustdoc/inline_cross/doc-hidden-module-impl-31948-2.rs
rename to tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs
diff --git a/tests/rustdoc/inline_cross/doc-hidden-module-impl-31948.rs b/tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs
similarity index 100%
rename from tests/rustdoc/inline_cross/doc-hidden-module-impl-31948.rs
rename to tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs

From c17d5689dac5f82464ca09bbcd56a1c694effd92 Mon Sep 17 00:00:00 2001
From: Michael Howell 
Date: Thu, 30 Jan 2025 12:09:33 -0700
Subject: [PATCH 16/16] Direct link 108459 to issues -> pull redirect

---
 .../intra-doc/link-same-name-different-disambiguator-108459.rs  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs b/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs
index 0328e6435a530..0b339eaf6b27c 100644
--- a/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs
+++ b/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs
@@ -1,4 +1,4 @@
-// https://github.com/rust-lang/rust/issues/108459
+// https://github.com/rust-lang/rust/pull/108459
 #![crate_name="foobar"]
 
 #![deny(rustdoc::broken_intra_doc_links)]