From 62c92f30cf02fc56b8a774c77097f1111dc2f4ea Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Thu, 24 Jul 2025 17:45:27 +0500 Subject: [PATCH 1/9] moved 35 tests to organized locations --- .../{issues/issue-14845.rs => cast/array-field-ptr-cast-14845.rs} | 0 .../issue-14366.rs => cast/trait-object-size-error-14366.rs} | 0 .../issue-13808.rs => closures/boxed-closure-lifetime-13808.rs} | 0 .../method-return-trait-object-14399.rs} | 0 .../issue-13763.rs => consts/module-const-array-size-13763.rs} | 0 .../ui/{issues/issue-14875.rs => drop/panic-during-drop-14875.rs} | 0 .../issue-14330.rs => extern/macro-use-extern-std-14330.rs} | 0 .../issue-14959.rs => fn_traits/closure-trait-impl-14959.rs} | 0 .../issue-14092.rs => generics/box-missing-generics-14092.rs} | 0 .../explicit-lifetime-required-14285.rs} | 0 .../lifetime-bound-whitespace-13703.rs} | 0 .../missing-lifetime-specifier-13497.rs} | 0 .../ref-pattern-lifetime-annotation-13665.rs} | 0 .../return-reference-local-variable-13497-2.rs} | 0 .../trait-object-constructor-14821.rs} | 0 .../issue-14091.rs => macros/assert-mismatched-types-14091.rs} | 0 .../issue-14091-2.rs => macros/assert-unary-operator-14091-2.rs} | 0 .../issue-14865.rs => match/guard-pattern-ordering-14865.rs} | 0 .../issue-13867.rs => match/multiple-refutable-patterns-13867.rs} | 0 .../{issues/issue-14393.rs => match/tuple-usize-pattern-14393.rs} | 0 .../ui/{issues/issue-14082.rs => modules/use-shadowing-14082.rs} | 0 .../field-access-never-type-13847.rs} | 0 .../issue-14915.rs => operator-recovery/box-arithmetic-14915.rs} | 0 .../issue-13482.rs => pattern/array-length-mismatch-13482.rs} | 0 .../array-length-mismatch-verbose-13482-2.rs} | 0 .../struct-mismatch-destructure-14541.rs} | 0 .../issue-14308.rs => pattern/struct-wildcard-pattern-14308.rs} | 0 .../issue-13775.rs => trait-bounds/anonymous-parameters-13775.rs} | 0 .../{issues/issue-14229.rs => traits/impl-trait-chain-14229.rs} | 0 .../issue-14919.rs => traits/matcher-lifetime-inference-14919.rs} | 0 .../{issues/issue-14254.rs => traits/pointer-type-impls-14254.rs} | 0 .../issue-14901.rs => traits/reader-wrapper-trait-14901.rs} | 0 .../issue-14853.rs => traits/trait-bound-mismatch-14853.rs} | 0 .../{issues/issue-14721.rs => typeck/str-no-field-desc-14721.rs} | 0 34 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-14845.rs => cast/array-field-ptr-cast-14845.rs} (100%) rename tests/ui/{issues/issue-14366.rs => cast/trait-object-size-error-14366.rs} (100%) rename tests/ui/{issues/issue-13808.rs => closures/boxed-closure-lifetime-13808.rs} (100%) rename tests/ui/{issues/issue-14399.rs => coercion/method-return-trait-object-14399.rs} (100%) rename tests/ui/{issues/issue-13763.rs => consts/module-const-array-size-13763.rs} (100%) rename tests/ui/{issues/issue-14875.rs => drop/panic-during-drop-14875.rs} (100%) rename tests/ui/{issues/issue-14330.rs => extern/macro-use-extern-std-14330.rs} (100%) rename tests/ui/{issues/issue-14959.rs => fn_traits/closure-trait-impl-14959.rs} (100%) rename tests/ui/{issues/issue-14092.rs => generics/box-missing-generics-14092.rs} (100%) rename tests/ui/{issues/issue-14285.rs => lifetimes/explicit-lifetime-required-14285.rs} (100%) rename tests/ui/{issues/issue-13703.rs => lifetimes/lifetime-bound-whitespace-13703.rs} (100%) rename tests/ui/{issues/issue-13497.rs => lifetimes/missing-lifetime-specifier-13497.rs} (100%) rename tests/ui/{issues/issue-13665.rs => lifetimes/ref-pattern-lifetime-annotation-13665.rs} (100%) rename tests/ui/{issues/issue-13497-2.rs => lifetimes/return-reference-local-variable-13497-2.rs} (100%) rename tests/ui/{issues/issue-14821.rs => lifetimes/trait-object-constructor-14821.rs} (100%) rename tests/ui/{issues/issue-14091.rs => macros/assert-mismatched-types-14091.rs} (100%) rename tests/ui/{issues/issue-14091-2.rs => macros/assert-unary-operator-14091-2.rs} (100%) rename tests/ui/{issues/issue-14865.rs => match/guard-pattern-ordering-14865.rs} (100%) rename tests/ui/{issues/issue-13867.rs => match/multiple-refutable-patterns-13867.rs} (100%) rename tests/ui/{issues/issue-14393.rs => match/tuple-usize-pattern-14393.rs} (100%) rename tests/ui/{issues/issue-14082.rs => modules/use-shadowing-14082.rs} (100%) rename tests/ui/{issues/issue-13847.rs => never_type/field-access-never-type-13847.rs} (100%) rename tests/ui/{issues/issue-14915.rs => operator-recovery/box-arithmetic-14915.rs} (100%) rename tests/ui/{issues/issue-13482.rs => pattern/array-length-mismatch-13482.rs} (100%) rename tests/ui/{issues/issue-13482-2.rs => pattern/array-length-mismatch-verbose-13482-2.rs} (100%) rename tests/ui/{issues/issue-14541.rs => pattern/struct-mismatch-destructure-14541.rs} (100%) rename tests/ui/{issues/issue-14308.rs => pattern/struct-wildcard-pattern-14308.rs} (100%) rename tests/ui/{issues/issue-13775.rs => trait-bounds/anonymous-parameters-13775.rs} (100%) rename tests/ui/{issues/issue-14229.rs => traits/impl-trait-chain-14229.rs} (100%) rename tests/ui/{issues/issue-14919.rs => traits/matcher-lifetime-inference-14919.rs} (100%) rename tests/ui/{issues/issue-14254.rs => traits/pointer-type-impls-14254.rs} (100%) rename tests/ui/{issues/issue-14901.rs => traits/reader-wrapper-trait-14901.rs} (100%) rename tests/ui/{issues/issue-14853.rs => traits/trait-bound-mismatch-14853.rs} (100%) rename tests/ui/{issues/issue-14721.rs => typeck/str-no-field-desc-14721.rs} (100%) diff --git a/tests/ui/issues/issue-14845.rs b/tests/ui/cast/array-field-ptr-cast-14845.rs similarity index 100% rename from tests/ui/issues/issue-14845.rs rename to tests/ui/cast/array-field-ptr-cast-14845.rs diff --git a/tests/ui/issues/issue-14366.rs b/tests/ui/cast/trait-object-size-error-14366.rs similarity index 100% rename from tests/ui/issues/issue-14366.rs rename to tests/ui/cast/trait-object-size-error-14366.rs diff --git a/tests/ui/issues/issue-13808.rs b/tests/ui/closures/boxed-closure-lifetime-13808.rs similarity index 100% rename from tests/ui/issues/issue-13808.rs rename to tests/ui/closures/boxed-closure-lifetime-13808.rs diff --git a/tests/ui/issues/issue-14399.rs b/tests/ui/coercion/method-return-trait-object-14399.rs similarity index 100% rename from tests/ui/issues/issue-14399.rs rename to tests/ui/coercion/method-return-trait-object-14399.rs diff --git a/tests/ui/issues/issue-13763.rs b/tests/ui/consts/module-const-array-size-13763.rs similarity index 100% rename from tests/ui/issues/issue-13763.rs rename to tests/ui/consts/module-const-array-size-13763.rs diff --git a/tests/ui/issues/issue-14875.rs b/tests/ui/drop/panic-during-drop-14875.rs similarity index 100% rename from tests/ui/issues/issue-14875.rs rename to tests/ui/drop/panic-during-drop-14875.rs diff --git a/tests/ui/issues/issue-14330.rs b/tests/ui/extern/macro-use-extern-std-14330.rs similarity index 100% rename from tests/ui/issues/issue-14330.rs rename to tests/ui/extern/macro-use-extern-std-14330.rs diff --git a/tests/ui/issues/issue-14959.rs b/tests/ui/fn_traits/closure-trait-impl-14959.rs similarity index 100% rename from tests/ui/issues/issue-14959.rs rename to tests/ui/fn_traits/closure-trait-impl-14959.rs diff --git a/tests/ui/issues/issue-14092.rs b/tests/ui/generics/box-missing-generics-14092.rs similarity index 100% rename from tests/ui/issues/issue-14092.rs rename to tests/ui/generics/box-missing-generics-14092.rs diff --git a/tests/ui/issues/issue-14285.rs b/tests/ui/lifetimes/explicit-lifetime-required-14285.rs similarity index 100% rename from tests/ui/issues/issue-14285.rs rename to tests/ui/lifetimes/explicit-lifetime-required-14285.rs diff --git a/tests/ui/issues/issue-13703.rs b/tests/ui/lifetimes/lifetime-bound-whitespace-13703.rs similarity index 100% rename from tests/ui/issues/issue-13703.rs rename to tests/ui/lifetimes/lifetime-bound-whitespace-13703.rs diff --git a/tests/ui/issues/issue-13497.rs b/tests/ui/lifetimes/missing-lifetime-specifier-13497.rs similarity index 100% rename from tests/ui/issues/issue-13497.rs rename to tests/ui/lifetimes/missing-lifetime-specifier-13497.rs diff --git a/tests/ui/issues/issue-13665.rs b/tests/ui/lifetimes/ref-pattern-lifetime-annotation-13665.rs similarity index 100% rename from tests/ui/issues/issue-13665.rs rename to tests/ui/lifetimes/ref-pattern-lifetime-annotation-13665.rs diff --git a/tests/ui/issues/issue-13497-2.rs b/tests/ui/lifetimes/return-reference-local-variable-13497-2.rs similarity index 100% rename from tests/ui/issues/issue-13497-2.rs rename to tests/ui/lifetimes/return-reference-local-variable-13497-2.rs diff --git a/tests/ui/issues/issue-14821.rs b/tests/ui/lifetimes/trait-object-constructor-14821.rs similarity index 100% rename from tests/ui/issues/issue-14821.rs rename to tests/ui/lifetimes/trait-object-constructor-14821.rs diff --git a/tests/ui/issues/issue-14091.rs b/tests/ui/macros/assert-mismatched-types-14091.rs similarity index 100% rename from tests/ui/issues/issue-14091.rs rename to tests/ui/macros/assert-mismatched-types-14091.rs diff --git a/tests/ui/issues/issue-14091-2.rs b/tests/ui/macros/assert-unary-operator-14091-2.rs similarity index 100% rename from tests/ui/issues/issue-14091-2.rs rename to tests/ui/macros/assert-unary-operator-14091-2.rs diff --git a/tests/ui/issues/issue-14865.rs b/tests/ui/match/guard-pattern-ordering-14865.rs similarity index 100% rename from tests/ui/issues/issue-14865.rs rename to tests/ui/match/guard-pattern-ordering-14865.rs diff --git a/tests/ui/issues/issue-13867.rs b/tests/ui/match/multiple-refutable-patterns-13867.rs similarity index 100% rename from tests/ui/issues/issue-13867.rs rename to tests/ui/match/multiple-refutable-patterns-13867.rs diff --git a/tests/ui/issues/issue-14393.rs b/tests/ui/match/tuple-usize-pattern-14393.rs similarity index 100% rename from tests/ui/issues/issue-14393.rs rename to tests/ui/match/tuple-usize-pattern-14393.rs diff --git a/tests/ui/issues/issue-14082.rs b/tests/ui/modules/use-shadowing-14082.rs similarity index 100% rename from tests/ui/issues/issue-14082.rs rename to tests/ui/modules/use-shadowing-14082.rs diff --git a/tests/ui/issues/issue-13847.rs b/tests/ui/never_type/field-access-never-type-13847.rs similarity index 100% rename from tests/ui/issues/issue-13847.rs rename to tests/ui/never_type/field-access-never-type-13847.rs diff --git a/tests/ui/issues/issue-14915.rs b/tests/ui/operator-recovery/box-arithmetic-14915.rs similarity index 100% rename from tests/ui/issues/issue-14915.rs rename to tests/ui/operator-recovery/box-arithmetic-14915.rs diff --git a/tests/ui/issues/issue-13482.rs b/tests/ui/pattern/array-length-mismatch-13482.rs similarity index 100% rename from tests/ui/issues/issue-13482.rs rename to tests/ui/pattern/array-length-mismatch-13482.rs diff --git a/tests/ui/issues/issue-13482-2.rs b/tests/ui/pattern/array-length-mismatch-verbose-13482-2.rs similarity index 100% rename from tests/ui/issues/issue-13482-2.rs rename to tests/ui/pattern/array-length-mismatch-verbose-13482-2.rs diff --git a/tests/ui/issues/issue-14541.rs b/tests/ui/pattern/struct-mismatch-destructure-14541.rs similarity index 100% rename from tests/ui/issues/issue-14541.rs rename to tests/ui/pattern/struct-mismatch-destructure-14541.rs diff --git a/tests/ui/issues/issue-14308.rs b/tests/ui/pattern/struct-wildcard-pattern-14308.rs similarity index 100% rename from tests/ui/issues/issue-14308.rs rename to tests/ui/pattern/struct-wildcard-pattern-14308.rs diff --git a/tests/ui/issues/issue-13775.rs b/tests/ui/trait-bounds/anonymous-parameters-13775.rs similarity index 100% rename from tests/ui/issues/issue-13775.rs rename to tests/ui/trait-bounds/anonymous-parameters-13775.rs diff --git a/tests/ui/issues/issue-14229.rs b/tests/ui/traits/impl-trait-chain-14229.rs similarity index 100% rename from tests/ui/issues/issue-14229.rs rename to tests/ui/traits/impl-trait-chain-14229.rs diff --git a/tests/ui/issues/issue-14919.rs b/tests/ui/traits/matcher-lifetime-inference-14919.rs similarity index 100% rename from tests/ui/issues/issue-14919.rs rename to tests/ui/traits/matcher-lifetime-inference-14919.rs diff --git a/tests/ui/issues/issue-14254.rs b/tests/ui/traits/pointer-type-impls-14254.rs similarity index 100% rename from tests/ui/issues/issue-14254.rs rename to tests/ui/traits/pointer-type-impls-14254.rs diff --git a/tests/ui/issues/issue-14901.rs b/tests/ui/traits/reader-wrapper-trait-14901.rs similarity index 100% rename from tests/ui/issues/issue-14901.rs rename to tests/ui/traits/reader-wrapper-trait-14901.rs diff --git a/tests/ui/issues/issue-14853.rs b/tests/ui/traits/trait-bound-mismatch-14853.rs similarity index 100% rename from tests/ui/issues/issue-14853.rs rename to tests/ui/traits/trait-bound-mismatch-14853.rs diff --git a/tests/ui/issues/issue-14721.rs b/tests/ui/typeck/str-no-field-desc-14721.rs similarity index 100% rename from tests/ui/issues/issue-14721.rs rename to tests/ui/typeck/str-no-field-desc-14721.rs From b6e13e35911d1aabc7164fc069b09c4e8c91981e Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Thu, 24 Jul 2025 17:52:22 +0500 Subject: [PATCH 2/9] comments --- tests/ui/cast/array-field-ptr-cast-14845.rs | 2 ++ .../array-field-ptr-cast-14845.stderr} | 4 ++-- tests/ui/cast/trait-object-size-error-14366.rs | 2 ++ .../trait-object-size-error-14366.stderr} | 2 +- .../ui/closures/boxed-closure-lifetime-13808.rs | 2 ++ .../method-return-trait-object-14399.rs | 2 ++ .../method-return-trait-object-14399.stderr} | 2 +- .../ui/consts/module-const-array-size-13763.rs | 2 ++ tests/ui/drop/panic-during-drop-14875.rs | 2 ++ tests/ui/extern/macro-use-extern-std-14330.rs | 6 ------ tests/ui/fn_traits/closure-trait-impl-14959.rs | 2 ++ tests/ui/generics/box-missing-generics-14092.rs | 2 ++ .../box-missing-generics-14092.stderr} | 2 +- .../matcher-lifetime-inference-14919.rs | 2 ++ tests/ui/issues/issue-14091-2.stderr | 17 ----------------- tests/ui/issues/issue-14091.stderr | 9 --------- .../explicit-lifetime-required-14285.rs | 2 ++ .../explicit-lifetime-required-14285.stderr} | 2 +- .../lifetime-bound-whitespace-13703.rs | 2 ++ .../missing-lifetime-specifier-13497.rs | 2 ++ .../missing-lifetime-specifier-13497.stderr} | 2 +- .../reader-wrapper-trait-14901.rs | 2 ++ .../ref-pattern-lifetime-annotation-13665.rs | 2 ++ ...=> return-reference-local-variable-13497.rs} | 6 +++++- ...eturn-reference-local-variable-13497.stderr} | 8 +++++--- .../lifetimes/trait-object-constructor-14821.rs | 2 ++ .../ui/macros/assert-mismatched-types-14091.rs | 4 ---- .../ui/macros/assert-unary-operator-14091-2.rs | 17 ----------------- tests/ui/match/guard-pattern-ordering-14865.rs | 2 ++ .../match/multiple-refutable-patterns-13867.rs | 2 ++ tests/ui/match/tuple-usize-pattern-14393.rs | 2 ++ .../never_type/field-access-never-type-13847.rs | 2 ++ .../field-access-never-type-13847.stderr} | 2 +- .../operator-recovery/box-arithmetic-14915.rs | 2 ++ .../box-arithmetic-14915.stderr} | 2 +- tests/ui/pattern/array-length-mismatch-13482.rs | 2 ++ .../array-length-mismatch-13482.stderr} | 2 +- ...s => array-length-mismatch-verbose-13482.rs} | 0 .../array-length-mismatch-verbose-13482.stderr} | 2 +- .../struct-mismatch-destructure-14541.rs | 2 ++ .../struct-mismatch-destructure-14541.stderr} | 2 +- .../ui/pattern/struct-wildcard-pattern-14308.rs | 2 ++ .../pointer-type-impls-14254.rs | 2 ++ .../{modules => resolve}/use-shadowing-14082.rs | 2 ++ .../trait-bounds/anonymous-parameters-13775.rs | 2 ++ tests/ui/traits/impl-trait-chain-14229.rs | 2 ++ tests/ui/traits/trait-bound-mismatch-14853.rs | 2 ++ .../trait-bound-mismatch-14853.stderr} | 2 +- .../float-type-inference-unification-14382.rs | 4 ++-- tests/ui/typeck/str-no-field-desc-14721.rs | 2 ++ .../str-no-field-desc-14721.stderr} | 2 +- 51 files changed, 84 insertions(+), 73 deletions(-) rename tests/ui/{issues/issue-14845.stderr => cast/array-field-ptr-cast-14845.stderr} (80%) rename tests/ui/{issues/issue-14366.stderr => cast/trait-object-size-error-14366.stderr} (92%) rename tests/ui/{issues/issue-14399.stderr => coercion/method-return-trait-object-14399.stderr} (80%) delete mode 100644 tests/ui/extern/macro-use-extern-std-14330.rs rename tests/ui/{issues/issue-14092.stderr => generics/box-missing-generics-14092.stderr} (87%) rename tests/ui/{traits => inference}/matcher-lifetime-inference-14919.rs (94%) delete mode 100644 tests/ui/issues/issue-14091-2.stderr delete mode 100644 tests/ui/issues/issue-14091.stderr rename tests/ui/{issues/issue-14285.stderr => lifetimes/explicit-lifetime-required-14285.stderr} (88%) rename tests/ui/{issues/issue-13497.stderr => lifetimes/missing-lifetime-specifier-13497.stderr} (92%) rename tests/ui/{traits => lifetimes}/reader-wrapper-trait-14901.rs (81%) rename tests/ui/lifetimes/{return-reference-local-variable-13497-2.rs => return-reference-local-variable-13497.rs} (62%) rename tests/ui/{issues/issue-13497-2.stderr => lifetimes/return-reference-local-variable-13497.stderr} (55%) delete mode 100644 tests/ui/macros/assert-mismatched-types-14091.rs delete mode 100644 tests/ui/macros/assert-unary-operator-14091-2.rs rename tests/ui/{issues/issue-13847.stderr => never_type/field-access-never-type-13847.stderr} (82%) rename tests/ui/{issues/issue-14915.stderr => operator-recovery/box-arithmetic-14915.stderr} (92%) rename tests/ui/{issues/issue-13482.stderr => pattern/array-length-mismatch-13482.stderr} (83%) rename tests/ui/pattern/{array-length-mismatch-verbose-13482-2.rs => array-length-mismatch-verbose-13482.rs} (100%) rename tests/ui/{issues/issue-13482-2.stderr => pattern/array-length-mismatch-verbose-13482.stderr} (81%) rename tests/ui/{issues/issue-14541.stderr => pattern/struct-mismatch-destructure-14541.stderr} (85%) rename tests/ui/{traits => resolve}/pointer-type-impls-14254.rs (96%) rename tests/ui/{modules => resolve}/use-shadowing-14082.rs (74%) rename tests/ui/{issues/issue-14853.stderr => traits/trait-bound-mismatch-14853.stderr} (90%) rename tests/ui/{issues/issue-14721.stderr => typeck/str-no-field-desc-14721.stderr} (84%) diff --git a/tests/ui/cast/array-field-ptr-cast-14845.rs b/tests/ui/cast/array-field-ptr-cast-14845.rs index d9b20e1f688ff..9d2da0c8932dd 100644 --- a/tests/ui/cast/array-field-ptr-cast-14845.rs +++ b/tests/ui/cast/array-field-ptr-cast-14845.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14845 + struct X { a: [u8; 1] } diff --git a/tests/ui/issues/issue-14845.stderr b/tests/ui/cast/array-field-ptr-cast-14845.stderr similarity index 80% rename from tests/ui/issues/issue-14845.stderr rename to tests/ui/cast/array-field-ptr-cast-14845.stderr index 2fa9fbaa887bc..4edde443fc391 100644 --- a/tests/ui/issues/issue-14845.stderr +++ b/tests/ui/cast/array-field-ptr-cast-14845.stderr @@ -1,11 +1,11 @@ error[E0606]: casting `&[u8; 1]` as `*mut u8` is invalid - --> $DIR/issue-14845.rs:7:14 + --> $DIR/array-field-ptr-cast-14845.rs:9:14 | LL | let _f = &x.a as *mut u8; | ^^^^^^^^^^^^^^^ error[E0606]: casting `&[u8; 1]` as `*mut u8` is invalid - --> $DIR/issue-14845.rs:10:14 + --> $DIR/array-field-ptr-cast-14845.rs:12:14 | LL | let _v = &local as *mut u8; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast/trait-object-size-error-14366.rs b/tests/ui/cast/trait-object-size-error-14366.rs index bb338860d8b77..2b66df0460013 100644 --- a/tests/ui/cast/trait-object-size-error-14366.rs +++ b/tests/ui/cast/trait-object-size-error-14366.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14366 + fn main() { let _x = "test" as &dyn (::std::any::Any); //~^ ERROR the size for values of type diff --git a/tests/ui/issues/issue-14366.stderr b/tests/ui/cast/trait-object-size-error-14366.stderr similarity index 92% rename from tests/ui/issues/issue-14366.stderr rename to tests/ui/cast/trait-object-size-error-14366.stderr index e7bf555c1b708..2451584e95151 100644 --- a/tests/ui/issues/issue-14366.stderr +++ b/tests/ui/cast/trait-object-size-error-14366.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/issue-14366.rs:2:14 + --> $DIR/trait-object-size-error-14366.rs:4:14 | LL | let _x = "test" as &dyn (::std::any::Any); | ^^^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/closures/boxed-closure-lifetime-13808.rs b/tests/ui/closures/boxed-closure-lifetime-13808.rs index d2961b35f2e76..e8324796b5f38 100644 --- a/tests/ui/closures/boxed-closure-lifetime-13808.rs +++ b/tests/ui/closures/boxed-closure-lifetime-13808.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/13808 + //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] diff --git a/tests/ui/coercion/method-return-trait-object-14399.rs b/tests/ui/coercion/method-return-trait-object-14399.rs index a539e270fb011..49eee152d889c 100644 --- a/tests/ui/coercion/method-return-trait-object-14399.rs +++ b/tests/ui/coercion/method-return-trait-object-14399.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14399 + //@ run-pass // #14399 // We'd previously ICE if we had a method call whose return diff --git a/tests/ui/issues/issue-14399.stderr b/tests/ui/coercion/method-return-trait-object-14399.stderr similarity index 80% rename from tests/ui/issues/issue-14399.stderr rename to tests/ui/coercion/method-return-trait-object-14399.stderr index 5821c3cc3899a..1aa87f53ff85e 100644 --- a/tests/ui/issues/issue-14399.stderr +++ b/tests/ui/coercion/method-return-trait-object-14399.stderr @@ -1,5 +1,5 @@ warning: method `foo` is never used - --> $DIR/issue-14399.rs:11:14 + --> $DIR/method-return-trait-object-14399.rs:13:14 | LL | trait A { fn foo(&self) {} } | - ^^^ diff --git a/tests/ui/consts/module-const-array-size-13763.rs b/tests/ui/consts/module-const-array-size-13763.rs index 67b9bdc5f038a..b1c6879ffd22d 100644 --- a/tests/ui/consts/module-const-array-size-13763.rs +++ b/tests/ui/consts/module-const-array-size-13763.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/13763 + //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/drop/panic-during-drop-14875.rs b/tests/ui/drop/panic-during-drop-14875.rs index e330c64a335fc..5a6f8f427758d 100644 --- a/tests/ui/drop/panic-during-drop-14875.rs +++ b/tests/ui/drop/panic-during-drop-14875.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14875 + //@ run-pass //@ needs-unwind //@ ignore-backends: gcc diff --git a/tests/ui/extern/macro-use-extern-std-14330.rs b/tests/ui/extern/macro-use-extern-std-14330.rs deleted file mode 100644 index 11199db5901f3..0000000000000 --- a/tests/ui/extern/macro-use-extern-std-14330.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ check-pass -#![allow(unused_imports)] - -#[macro_use] extern crate std as std2; - -fn main() {} diff --git a/tests/ui/fn_traits/closure-trait-impl-14959.rs b/tests/ui/fn_traits/closure-trait-impl-14959.rs index 57af1207ff9c7..94d43055e6474 100644 --- a/tests/ui/fn_traits/closure-trait-impl-14959.rs +++ b/tests/ui/fn_traits/closure-trait-impl-14959.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14959 + //@ check-pass #![feature(fn_traits, unboxed_closures)] diff --git a/tests/ui/generics/box-missing-generics-14092.rs b/tests/ui/generics/box-missing-generics-14092.rs index 67c2a42eafb78..3570d5f675f33 100644 --- a/tests/ui/generics/box-missing-generics-14092.rs +++ b/tests/ui/generics/box-missing-generics-14092.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14092 + fn fn1(0: Box) {} //~^ ERROR missing generics for struct `Box` diff --git a/tests/ui/issues/issue-14092.stderr b/tests/ui/generics/box-missing-generics-14092.stderr similarity index 87% rename from tests/ui/issues/issue-14092.stderr rename to tests/ui/generics/box-missing-generics-14092.stderr index 0de7b902fe05c..0822d781ac704 100644 --- a/tests/ui/issues/issue-14092.stderr +++ b/tests/ui/generics/box-missing-generics-14092.stderr @@ -1,5 +1,5 @@ error[E0107]: missing generics for struct `Box` - --> $DIR/issue-14092.rs:1:11 + --> $DIR/box-missing-generics-14092.rs:3:11 | LL | fn fn1(0: Box) {} | ^^^ expected at least 1 generic argument diff --git a/tests/ui/traits/matcher-lifetime-inference-14919.rs b/tests/ui/inference/matcher-lifetime-inference-14919.rs similarity index 94% rename from tests/ui/traits/matcher-lifetime-inference-14919.rs rename to tests/ui/inference/matcher-lifetime-inference-14919.rs index 3a834b13d07c0..742d43f3efed5 100644 --- a/tests/ui/traits/matcher-lifetime-inference-14919.rs +++ b/tests/ui/inference/matcher-lifetime-inference-14919.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14919 + //@ run-pass #![allow(unused_must_use)] #![allow(dead_code)] diff --git a/tests/ui/issues/issue-14091-2.stderr b/tests/ui/issues/issue-14091-2.stderr deleted file mode 100644 index d573a0917be5f..0000000000000 --- a/tests/ui/issues/issue-14091-2.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0600]: cannot apply unary operator `!` to type `BytePos` - --> $DIR/issue-14091-2.rs:15:5 - | -LL | assert!(x, x); - | ^^^^^^^^^^^^^ cannot apply unary operator `!` - | -note: an implementation of `Not` might be missing for `BytePos` - --> $DIR/issue-14091-2.rs:6:1 - | -LL | pub struct BytePos(pub u32); - | ^^^^^^^^^^^^^^^^^^ must implement `Not` -note: the trait `Not` must be implemented - --> $SRC_DIR/core/src/ops/bit.rs:LL:COL - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0600`. diff --git a/tests/ui/issues/issue-14091.stderr b/tests/ui/issues/issue-14091.stderr deleted file mode 100644 index 83879583b1f29..0000000000000 --- a/tests/ui/issues/issue-14091.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-14091.rs:2:5 - | -LL | assert!(1,1); - | ^^^^^^^^^^^^ expected `bool`, found integer - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/lifetimes/explicit-lifetime-required-14285.rs b/tests/ui/lifetimes/explicit-lifetime-required-14285.rs index 2ba9ff717739c..3f43dcf8366aa 100644 --- a/tests/ui/lifetimes/explicit-lifetime-required-14285.rs +++ b/tests/ui/lifetimes/explicit-lifetime-required-14285.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14285 + trait Foo { fn dummy(&self) { } } diff --git a/tests/ui/issues/issue-14285.stderr b/tests/ui/lifetimes/explicit-lifetime-required-14285.stderr similarity index 88% rename from tests/ui/issues/issue-14285.stderr rename to tests/ui/lifetimes/explicit-lifetime-required-14285.stderr index edd139eecba4d..576de45f94f7e 100644 --- a/tests/ui/issues/issue-14285.stderr +++ b/tests/ui/lifetimes/explicit-lifetime-required-14285.stderr @@ -1,5 +1,5 @@ error[E0621]: explicit lifetime required in the type of `a` - --> $DIR/issue-14285.rs:12:5 + --> $DIR/explicit-lifetime-required-14285.rs:14:5 | LL | B(a) | ^^^^ lifetime `'a` required diff --git a/tests/ui/lifetimes/lifetime-bound-whitespace-13703.rs b/tests/ui/lifetimes/lifetime-bound-whitespace-13703.rs index b385e6b9d2efd..79b85e4c13225 100644 --- a/tests/ui/lifetimes/lifetime-bound-whitespace-13703.rs +++ b/tests/ui/lifetimes/lifetime-bound-whitespace-13703.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/13703 + //@ check-pass pub struct Foo<'a, 'b: 'a> { foo: &'a &'b isize } diff --git a/tests/ui/lifetimes/missing-lifetime-specifier-13497.rs b/tests/ui/lifetimes/missing-lifetime-specifier-13497.rs index 4b2795aa841e8..6f4ef0b5620d0 100644 --- a/tests/ui/lifetimes/missing-lifetime-specifier-13497.rs +++ b/tests/ui/lifetimes/missing-lifetime-specifier-13497.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/13497 + fn read_lines_borrowed1() -> Vec< &str //~ ERROR missing lifetime specifier > { diff --git a/tests/ui/issues/issue-13497.stderr b/tests/ui/lifetimes/missing-lifetime-specifier-13497.stderr similarity index 92% rename from tests/ui/issues/issue-13497.stderr rename to tests/ui/lifetimes/missing-lifetime-specifier-13497.stderr index ee111f1d262e0..99f4fa04f12df 100644 --- a/tests/ui/issues/issue-13497.stderr +++ b/tests/ui/lifetimes/missing-lifetime-specifier-13497.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/issue-13497.rs:2:5 + --> $DIR/missing-lifetime-specifier-13497.rs:4:5 | LL | &str | ^ expected named lifetime parameter diff --git a/tests/ui/traits/reader-wrapper-trait-14901.rs b/tests/ui/lifetimes/reader-wrapper-trait-14901.rs similarity index 81% rename from tests/ui/traits/reader-wrapper-trait-14901.rs rename to tests/ui/lifetimes/reader-wrapper-trait-14901.rs index ddc12b9ef3c94..672872af03aa0 100644 --- a/tests/ui/traits/reader-wrapper-trait-14901.rs +++ b/tests/ui/lifetimes/reader-wrapper-trait-14901.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14901 + //@ check-pass pub trait Reader {} diff --git a/tests/ui/lifetimes/ref-pattern-lifetime-annotation-13665.rs b/tests/ui/lifetimes/ref-pattern-lifetime-annotation-13665.rs index e1d8be16f4500..bae2f73baa36f 100644 --- a/tests/ui/lifetimes/ref-pattern-lifetime-annotation-13665.rs +++ b/tests/ui/lifetimes/ref-pattern-lifetime-annotation-13665.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/13665 + //@ run-pass fn foo<'r>() { diff --git a/tests/ui/lifetimes/return-reference-local-variable-13497-2.rs b/tests/ui/lifetimes/return-reference-local-variable-13497.rs similarity index 62% rename from tests/ui/lifetimes/return-reference-local-variable-13497-2.rs rename to tests/ui/lifetimes/return-reference-local-variable-13497.rs index c82da0f0096ad..1ca8074164b22 100644 --- a/tests/ui/lifetimes/return-reference-local-variable-13497-2.rs +++ b/tests/ui/lifetimes/return-reference-local-variable-13497.rs @@ -1,7 +1,11 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/13497 + fn read_lines_borrowed<'a>() -> Vec<&'a str> { let rawLines: Vec = vec!["foo ".to_string(), " bar".to_string()]; rawLines //~ ERROR cannot return value referencing local variable `rawLines` - .iter().map(|l| l.trim()).collect() + .iter() + .map(|l| l.trim()) + .collect() } fn main() {} diff --git a/tests/ui/issues/issue-13497-2.stderr b/tests/ui/lifetimes/return-reference-local-variable-13497.stderr similarity index 55% rename from tests/ui/issues/issue-13497-2.stderr rename to tests/ui/lifetimes/return-reference-local-variable-13497.stderr index e2ba1150d07bd..f5419f114ca29 100644 --- a/tests/ui/issues/issue-13497-2.stderr +++ b/tests/ui/lifetimes/return-reference-local-variable-13497.stderr @@ -1,13 +1,15 @@ error[E0515]: cannot return value referencing local variable `rawLines` - --> $DIR/issue-13497-2.rs:3:5 + --> $DIR/return-reference-local-variable-13497.rs:5:5 | LL | rawLines | ^------- | | | _____`rawLines` is borrowed here | | -LL | | .iter().map(|l| l.trim()).collect() - | |___________________________________________^ returns a value referencing data owned by the current function +LL | | .iter() +LL | | .map(|l| l.trim()) +LL | | .collect() + | |__________________^ returns a value referencing data owned by the current function error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/trait-object-constructor-14821.rs b/tests/ui/lifetimes/trait-object-constructor-14821.rs index b11a885b3a03f..76f0c7514bc33 100644 --- a/tests/ui/lifetimes/trait-object-constructor-14821.rs +++ b/tests/ui/lifetimes/trait-object-constructor-14821.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14821 + //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] diff --git a/tests/ui/macros/assert-mismatched-types-14091.rs b/tests/ui/macros/assert-mismatched-types-14091.rs deleted file mode 100644 index 0ee20de9053dc..0000000000000 --- a/tests/ui/macros/assert-mismatched-types-14091.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main(){ - assert!(1,1); - //~^ ERROR mismatched types -} diff --git a/tests/ui/macros/assert-unary-operator-14091-2.rs b/tests/ui/macros/assert-unary-operator-14091-2.rs deleted file mode 100644 index e2f6b18337266..0000000000000 --- a/tests/ui/macros/assert-unary-operator-14091-2.rs +++ /dev/null @@ -1,17 +0,0 @@ -// - -// Very - -// sensitive -pub struct BytePos(pub u32); - -// to particular - -// line numberings / offsets - -fn main() { - let x = BytePos(1); - - assert!(x, x); - //~^ ERROR cannot apply unary operator `!` to type `BytePos` -} diff --git a/tests/ui/match/guard-pattern-ordering-14865.rs b/tests/ui/match/guard-pattern-ordering-14865.rs index e0f8bfe942856..a789599c56684 100644 --- a/tests/ui/match/guard-pattern-ordering-14865.rs +++ b/tests/ui/match/guard-pattern-ordering-14865.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14865 + //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/match/multiple-refutable-patterns-13867.rs b/tests/ui/match/multiple-refutable-patterns-13867.rs index ad7d6d663935e..a308219a9b2a7 100644 --- a/tests/ui/match/multiple-refutable-patterns-13867.rs +++ b/tests/ui/match/multiple-refutable-patterns-13867.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/13867 + //@ run-pass // Test that codegen works correctly when there are multiple refutable // patterns in match expression. diff --git a/tests/ui/match/tuple-usize-pattern-14393.rs b/tests/ui/match/tuple-usize-pattern-14393.rs index 69c3fc15d3141..12d58d4c059a5 100644 --- a/tests/ui/match/tuple-usize-pattern-14393.rs +++ b/tests/ui/match/tuple-usize-pattern-14393.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14393 + //@ run-pass fn main() { diff --git a/tests/ui/never_type/field-access-never-type-13847.rs b/tests/ui/never_type/field-access-never-type-13847.rs index 06a0304ae4975..ff2a1c67b8c03 100644 --- a/tests/ui/never_type/field-access-never-type-13847.rs +++ b/tests/ui/never_type/field-access-never-type-13847.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/13847 + fn main() { return.is_failure //~ ERROR no field `is_failure` on type `!` } diff --git a/tests/ui/issues/issue-13847.stderr b/tests/ui/never_type/field-access-never-type-13847.stderr similarity index 82% rename from tests/ui/issues/issue-13847.stderr rename to tests/ui/never_type/field-access-never-type-13847.stderr index 1c1855ce94ded..1db6b310f0a13 100644 --- a/tests/ui/issues/issue-13847.stderr +++ b/tests/ui/never_type/field-access-never-type-13847.stderr @@ -1,5 +1,5 @@ error[E0609]: no field `is_failure` on type `!` - --> $DIR/issue-13847.rs:2:12 + --> $DIR/field-access-never-type-13847.rs:4:12 | LL | return.is_failure | ^^^^^^^^^^ unknown field diff --git a/tests/ui/operator-recovery/box-arithmetic-14915.rs b/tests/ui/operator-recovery/box-arithmetic-14915.rs index 127b909dd63eb..0e6f076299847 100644 --- a/tests/ui/operator-recovery/box-arithmetic-14915.rs +++ b/tests/ui/operator-recovery/box-arithmetic-14915.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14915 + fn main() { let x: Box = Box::new(0); diff --git a/tests/ui/issues/issue-14915.stderr b/tests/ui/operator-recovery/box-arithmetic-14915.stderr similarity index 92% rename from tests/ui/issues/issue-14915.stderr rename to tests/ui/operator-recovery/box-arithmetic-14915.stderr index 3558bd651c62a..1dd80472bb875 100644 --- a/tests/ui/issues/issue-14915.stderr +++ b/tests/ui/operator-recovery/box-arithmetic-14915.stderr @@ -1,5 +1,5 @@ error[E0369]: cannot add `{integer}` to `Box` - --> $DIR/issue-14915.rs:4:22 + --> $DIR/box-arithmetic-14915.rs:6:22 | LL | println!("{}", x + 1); | - ^ - {integer} diff --git a/tests/ui/pattern/array-length-mismatch-13482.rs b/tests/ui/pattern/array-length-mismatch-13482.rs index 244b3237e023c..78d024e522727 100644 --- a/tests/ui/pattern/array-length-mismatch-13482.rs +++ b/tests/ui/pattern/array-length-mismatch-13482.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/13482 + fn main() { let x = [1,2]; let y = match x { diff --git a/tests/ui/issues/issue-13482.stderr b/tests/ui/pattern/array-length-mismatch-13482.stderr similarity index 83% rename from tests/ui/issues/issue-13482.stderr rename to tests/ui/pattern/array-length-mismatch-13482.stderr index 6226c580811c3..d366e0109274a 100644 --- a/tests/ui/issues/issue-13482.stderr +++ b/tests/ui/pattern/array-length-mismatch-13482.stderr @@ -1,5 +1,5 @@ error[E0527]: pattern requires 0 elements but array has 2 - --> $DIR/issue-13482.rs:4:5 + --> $DIR/array-length-mismatch-13482.rs:6:5 | LL | [] => None, | ^^ expected 2 elements diff --git a/tests/ui/pattern/array-length-mismatch-verbose-13482-2.rs b/tests/ui/pattern/array-length-mismatch-verbose-13482.rs similarity index 100% rename from tests/ui/pattern/array-length-mismatch-verbose-13482-2.rs rename to tests/ui/pattern/array-length-mismatch-verbose-13482.rs diff --git a/tests/ui/issues/issue-13482-2.stderr b/tests/ui/pattern/array-length-mismatch-verbose-13482.stderr similarity index 81% rename from tests/ui/issues/issue-13482-2.stderr rename to tests/ui/pattern/array-length-mismatch-verbose-13482.stderr index 87a6782a5e6c9..5b533b30afa37 100644 --- a/tests/ui/issues/issue-13482-2.stderr +++ b/tests/ui/pattern/array-length-mismatch-verbose-13482.stderr @@ -1,5 +1,5 @@ error[E0527]: pattern requires 0 elements but array has 2 - --> $DIR/issue-13482-2.rs:6:9 + --> $DIR/array-length-mismatch-verbose-13482.rs:6:9 | LL | [] => None, | ^^ expected 2 elements diff --git a/tests/ui/pattern/struct-mismatch-destructure-14541.rs b/tests/ui/pattern/struct-mismatch-destructure-14541.rs index 358d29419f95b..04e85237cab9e 100644 --- a/tests/ui/pattern/struct-mismatch-destructure-14541.rs +++ b/tests/ui/pattern/struct-mismatch-destructure-14541.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14541 + struct Vec2 { y: f32 } struct Vec3 { y: f32, z: f32 } diff --git a/tests/ui/issues/issue-14541.stderr b/tests/ui/pattern/struct-mismatch-destructure-14541.stderr similarity index 85% rename from tests/ui/issues/issue-14541.stderr rename to tests/ui/pattern/struct-mismatch-destructure-14541.stderr index 370e64779012f..024d77df2cba6 100644 --- a/tests/ui/issues/issue-14541.stderr +++ b/tests/ui/pattern/struct-mismatch-destructure-14541.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-14541.rs:5:9 + --> $DIR/struct-mismatch-destructure-14541.rs:7:9 | LL | let Vec3 { y: _, z: _ } = v; | ^^^^^^^^^^^^^^^^^^^ - this expression has type `Vec2` diff --git a/tests/ui/pattern/struct-wildcard-pattern-14308.rs b/tests/ui/pattern/struct-wildcard-pattern-14308.rs index 724be160d06ff..c1fdf424b8c44 100644 --- a/tests/ui/pattern/struct-wildcard-pattern-14308.rs +++ b/tests/ui/pattern/struct-wildcard-pattern-14308.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14308 + //@ run-pass struct A(isize); diff --git a/tests/ui/traits/pointer-type-impls-14254.rs b/tests/ui/resolve/pointer-type-impls-14254.rs similarity index 96% rename from tests/ui/traits/pointer-type-impls-14254.rs rename to tests/ui/resolve/pointer-type-impls-14254.rs index 90ad375c262ab..ea8fb6aa16706 100644 --- a/tests/ui/traits/pointer-type-impls-14254.rs +++ b/tests/ui/resolve/pointer-type-impls-14254.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14254 + //@ check-pass trait Foo: Sized { diff --git a/tests/ui/modules/use-shadowing-14082.rs b/tests/ui/resolve/use-shadowing-14082.rs similarity index 74% rename from tests/ui/modules/use-shadowing-14082.rs rename to tests/ui/resolve/use-shadowing-14082.rs index 16556e1d26003..9d7df5ed1c6c9 100644 --- a/tests/ui/modules/use-shadowing-14082.rs +++ b/tests/ui/resolve/use-shadowing-14082.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14082 + //@ check-pass #![allow(unused_imports, dead_code)] diff --git a/tests/ui/trait-bounds/anonymous-parameters-13775.rs b/tests/ui/trait-bounds/anonymous-parameters-13775.rs index 1477dab9e2158..297d4b5958727 100644 --- a/tests/ui/trait-bounds/anonymous-parameters-13775.rs +++ b/tests/ui/trait-bounds/anonymous-parameters-13775.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/13775 + //@ edition: 2015 //@ check-pass diff --git a/tests/ui/traits/impl-trait-chain-14229.rs b/tests/ui/traits/impl-trait-chain-14229.rs index eb6324da3b6ed..4a234f3a68114 100644 --- a/tests/ui/traits/impl-trait-chain-14229.rs +++ b/tests/ui/traits/impl-trait-chain-14229.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14229 + //@ run-pass trait Foo: Sized { fn foo(self) {} diff --git a/tests/ui/traits/trait-bound-mismatch-14853.rs b/tests/ui/traits/trait-bound-mismatch-14853.rs index 4ce6e3174d0af..3f2a1408a1360 100644 --- a/tests/ui/traits/trait-bound-mismatch-14853.rs +++ b/tests/ui/traits/trait-bound-mismatch-14853.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14853 + use std::fmt::Debug; trait Str {} diff --git a/tests/ui/issues/issue-14853.stderr b/tests/ui/traits/trait-bound-mismatch-14853.stderr similarity index 90% rename from tests/ui/issues/issue-14853.stderr rename to tests/ui/traits/trait-bound-mismatch-14853.stderr index 25dd1e3374dba..8ee8f51a13566 100644 --- a/tests/ui/issues/issue-14853.stderr +++ b/tests/ui/traits/trait-bound-mismatch-14853.stderr @@ -1,5 +1,5 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/issue-14853.rs:12:15 + --> $DIR/trait-bound-mismatch-14853.rs:14:15 | LL | fn yay(_: Option, thing: &[T]); | ----------------------------------------------- definition of `yay` from trait diff --git a/tests/ui/type-inference/float-type-inference-unification-14382.rs b/tests/ui/type-inference/float-type-inference-unification-14382.rs index 5bf497d2eabc0..a78dbe9d09c0f 100644 --- a/tests/ui/type-inference/float-type-inference-unification-14382.rs +++ b/tests/ui/type-inference/float-type-inference-unification-14382.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14382 + //@ run-pass #[derive(Debug)] struct Matrix4(#[allow(dead_code)] S); @@ -13,5 +15,3 @@ fn main() { let m : Matrix4 = translate(x); println!("m: {:?}", m); } - -// https://github.com/rust-lang/rust/issues/14382 diff --git a/tests/ui/typeck/str-no-field-desc-14721.rs b/tests/ui/typeck/str-no-field-desc-14721.rs index c015a6bab083b..605807ac04f05 100644 --- a/tests/ui/typeck/str-no-field-desc-14721.rs +++ b/tests/ui/typeck/str-no-field-desc-14721.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/14721 + fn main() { let foo = "str"; println!("{}", foo.desc); //~ ERROR no field `desc` on type `&str` diff --git a/tests/ui/issues/issue-14721.stderr b/tests/ui/typeck/str-no-field-desc-14721.stderr similarity index 84% rename from tests/ui/issues/issue-14721.stderr rename to tests/ui/typeck/str-no-field-desc-14721.stderr index c71b0363eef64..fc1ec7179d7b2 100644 --- a/tests/ui/issues/issue-14721.stderr +++ b/tests/ui/typeck/str-no-field-desc-14721.stderr @@ -1,5 +1,5 @@ error[E0609]: no field `desc` on type `&str` - --> $DIR/issue-14721.rs:3:24 + --> $DIR/str-no-field-desc-14721.rs:5:24 | LL | println!("{}", foo.desc); | ^^^^ unknown field From 202d1fd35102441753451608b8649f39f540f66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 29 Jul 2025 20:51:46 +0200 Subject: [PATCH 3/9] make no_mangle explicit on foreign items --- .../src/back/symbol_export.rs | 2 +- .../rustc_codegen_ssa/src/codegen_attrs.rs | 29 +++++++++++++++ .../src/middle/codegen_fn_attrs.rs | 7 +++- compiler/rustc_middle/src/mir/mono.rs | 2 +- .../src/cross_crate_inline.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 36 +++++++++---------- compiler/rustc_passes/src/dead.rs | 2 +- compiler/rustc_passes/src/reachable.rs | 5 +-- compiler/rustc_symbol_mangling/src/lib.rs | 29 ++------------- .../clippy/clippy_lints/src/missing_inline.rs | 2 +- src/tools/miri/src/bin/miri.rs | 2 +- src/tools/miri/src/helpers.rs | 2 +- tests/run-make/wasm-panic-small/rmake.rs | 2 +- 13 files changed, 67 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 4b4b39f535332..2857ac287e358 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -586,7 +586,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel // core/std/allocators/etc. For example symbols used to hook up allocation // are not considered for export let codegen_fn_attrs = tcx.codegen_fn_attrs(sym_def_id); - let is_extern = codegen_fn_attrs.contains_extern_indicator(); + let is_extern = codegen_fn_attrs.contains_extern_indicator(tcx, sym_def_id); let std_internal = codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 7f54a47327af8..41f7df1279243 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -443,6 +443,35 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code if tcx.should_inherit_track_caller(did) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; } + + // Foreign items by default use no mangling for their symbol name. + if tcx.is_foreign_item(did) { + // There's a few exceptions to this rule though: + if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { + // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way + // both for exports and imports through foreign items. This is handled further, + // during symbol mangling logic. + } else if codegen_fn_attrs.link_name.is_some() { + // * This can be overridden with the `#[link_name]` attribute + } else if tcx.sess.target.is_like_wasm + && tcx.wasm_import_module_map(LOCAL_CRATE).contains_key(&did.into()) + { + // * On the wasm32 targets there is a bug (or feature) in LLD [1] where the + // same-named symbol when imported from different wasm modules will get + // hooked up incorrectly. As a result foreign symbols, on the wasm target, + // with a wasm import module, get mangled. Additionally our codegen will + // deduplicate symbols based purely on the symbol name, but for wasm this + // isn't quite right because the same-named symbol on wasm can come from + // different modules. For these reasons if `#[link(wasm_import_module)]` + // is present we mangle everything on wasm because the demangled form will + // show up in the `wasm-import-name` custom attribute in LLVM IR. + // + // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316 + } else { + // if none of the exceptions apply; apply no_mangle + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; + } + } } fn check_result( diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 94384e64afd15..52341df074085 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -3,6 +3,7 @@ use std::borrow::Cow; use rustc_abi::Align; use rustc_ast::expand::autodiff_attrs::AutoDiffAttrs; use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::Symbol; use rustc_target::spec::SanitizerSet; @@ -193,7 +194,11 @@ impl CodegenFnAttrs { /// * `#[linkage]` is present /// /// Keep this in sync with the logic for the unused_attributes for `#[inline]` lint. - pub fn contains_extern_indicator(&self) -> bool { + pub fn contains_extern_indicator(&self, tcx: TyCtxt<'_>, did: DefId) -> bool { + if tcx.is_foreign_item(did) { + return false; + } + self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) || self.export_name.is_some() diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index e5864660575c5..3afd946b30a2a 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -151,7 +151,7 @@ impl<'tcx> MonoItem<'tcx> { // instantiation: // We emit an unused_attributes lint for this case, which should be kept in sync if possible. let codegen_fn_attrs = tcx.codegen_instance_attrs(instance.def); - if codegen_fn_attrs.contains_extern_indicator() + if codegen_fn_attrs.contains_extern_indicator(tcx, instance.def.def_id()) || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) { return InstantiationMode::GloballyShared { may_conflict: false }; diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index b186c2bd7758f..03fdf9fbac538 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -18,7 +18,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id); // If this has an extern indicator, then this function is globally shared and thus will not // generate cgu-internal copies which would make it cross-crate inlinable. - if codegen_fn_attrs.contains_extern_indicator() { + if codegen_fn_attrs.contains_extern_indicator(tcx, def_id.into()) { return false; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2663d5fe99c7a..dcaac8953f0ee 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -562,7 +562,24 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match target { Target::Fn | Target::Closure - | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {} + | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => { + // `#[inline]` is ignored if the symbol must be codegened upstream because it's exported. + if let Some(did) = hir_id.as_owner() + && self.tcx.def_kind(did).has_codegen_attrs() + && kind != &InlineAttr::Never + { + let attrs = self.tcx.codegen_fn_attrs(did); + // Not checking naked as `#[inline]` is forbidden for naked functions anyways. + if attrs.contains_extern_indicator(self.tcx, did.into()) { + self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr_span, + errors::InlineIgnoredForExported {}, + ); + } + } + } Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, @@ -589,23 +606,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.dcx().emit_err(errors::InlineNotFnOrClosure { attr_span, defn_span }); } } - - // `#[inline]` is ignored if the symbol must be codegened upstream because it's exported. - if let Some(did) = hir_id.as_owner() - && self.tcx.def_kind(did).has_codegen_attrs() - && kind != &InlineAttr::Never - { - let attrs = self.tcx.codegen_fn_attrs(did); - // Not checking naked as `#[inline]` is forbidden for naked functions anyways. - if attrs.contains_extern_indicator() { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr_span, - errors::InlineIgnoredForExported {}, - ); - } - } } /// Checks that `#[coverage(..)]` is applied to a function/closure/method, diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index fa9d0c7b1b7d4..1c76e4e7166d7 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -701,7 +701,7 @@ fn has_allow_dead_code_or_lang_attr( // #[used], #[no_mangle], #[export_name], etc also keeps the item alive // forcefully, e.g., for placing it in a specific section. - cg_attrs.contains_extern_indicator() + cg_attrs.contains_extern_indicator(tcx, def_id.into()) || cg_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) || cg_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 2f78c22c7483b..6cd8a54ecf434 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -183,7 +183,7 @@ impl<'tcx> ReachableContext<'tcx> { } else { CodegenFnAttrs::EMPTY }; - let is_extern = codegen_attrs.contains_extern_indicator(); + let is_extern = codegen_attrs.contains_extern_indicator(self.tcx, search_item.into()); if is_extern { self.reachable_symbols.insert(search_item); } @@ -423,8 +423,9 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { if !tcx.def_kind(def_id).has_codegen_attrs() { return false; } + let codegen_attrs = tcx.codegen_fn_attrs(def_id); - codegen_attrs.contains_extern_indicator() + codegen_attrs.contains_extern_indicator(tcx, def_id.into()) // FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by // `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their // `SymbolExportLevel::Rust` export level but may end up being exported in dylibs. diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 6bcb7f6e093c4..d0549b91680a1 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -218,32 +218,9 @@ fn compute_symbol_name<'tcx>( } } - // Foreign items by default use no mangling for their symbol name. There's a - // few exceptions to this rule though: - // - // * This can be overridden with the `#[link_name]` attribute - // - // * On the wasm32 targets there is a bug (or feature) in LLD [1] where the - // same-named symbol when imported from different wasm modules will get - // hooked up incorrectly. As a result foreign symbols, on the wasm target, - // with a wasm import module, get mangled. Additionally our codegen will - // deduplicate symbols based purely on the symbol name, but for wasm this - // isn't quite right because the same-named symbol on wasm can come from - // different modules. For these reasons if `#[link(wasm_import_module)]` - // is present we mangle everything on wasm because the demangled form will - // show up in the `wasm-import-name` custom attribute in LLVM IR. - // - // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way - // both for exports and imports through foreign items. This is handled above. - // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316 - if tcx.is_foreign_item(def_id) - && (!tcx.sess.target.is_like_wasm - || !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id)) - { - if let Some(name) = attrs.link_name { - return name.to_string(); - } - return tcx.item_name(def_id).to_string(); + if let Some(name) = attrs.link_name { + // Use provided name + return name.to_string(); } if let Some(name) = attrs.export_name { diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index c637fb247ff2b..77be5bbc20b19 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -191,5 +191,5 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { /// and a rustc warning would be triggered, see #15301 fn fn_is_externally_exported(cx: &LateContext<'_>, def_id: DefId) -> bool { let attrs = cx.tcx.codegen_fn_attrs(def_id); - attrs.contains_extern_indicator() + attrs.contains_extern_indicator(cx.tcx, def_id) } diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index ae1b25f8857a0..d9e374c414cad 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -279,7 +279,7 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { return None; } let codegen_fn_attrs = tcx.codegen_fn_attrs(local_def_id); - if codegen_fn_attrs.contains_extern_indicator() + if codegen_fn_attrs.contains_extern_indicator(tcx, local_def_id.into()) || codegen_fn_attrs .flags .contains(CodegenFnAttrFlags::USED_COMPILER) diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 43cb1c9ae053c..a8e2151afe610 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -132,7 +132,7 @@ pub fn iter_exported_symbols<'tcx>( for def_id in crate_items.definitions() { let exported = tcx.def_kind(def_id).has_codegen_attrs() && { let codegen_attrs = tcx.codegen_fn_attrs(def_id); - codegen_attrs.contains_extern_indicator() + codegen_attrs.contains_extern_indicator(tcx, def_id.into()) || codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) diff --git a/tests/run-make/wasm-panic-small/rmake.rs b/tests/run-make/wasm-panic-small/rmake.rs index e69fbac96356a..ea0b6faf037c5 100644 --- a/tests/run-make/wasm-panic-small/rmake.rs +++ b/tests/run-make/wasm-panic-small/rmake.rs @@ -24,5 +24,5 @@ fn test(cfg: &str) { let bytes = rfs::read("foo.wasm"); println!("{}", bytes.len()); - assert!(bytes.len() < 40_000); + assert!(bytes.len() < 40_000, "bytes len was: {}", bytes.len()); } From c65102e745c5637d0da3e9649aaba7afdce7aa08 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 7 Aug 2025 13:20:09 +0200 Subject: [PATCH 4/9] doc(library): Fix Markdown in `Iterator::by_ref`. This patch fixes the Markdown formatting in `std::core::iter::Iterator::by_ref`. Code is used inside a link without the backticks around the code. --- library/core/src/iter/traits/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 29313867ff266..7fb162a653fb9 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -1875,7 +1875,7 @@ pub trait Iterator { /// without giving up ownership of the original iterator, /// so you can use the original iterator afterwards. /// - /// Uses [impl Iterator for &mut I { type Item = I::Item; ...}](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#impl-Iterator-for-%26mut+I). + /// Uses [`impl Iterator for &mut I { type Item = I::Item; ...}`](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#impl-Iterator-for-%26mut+I). /// /// # Examples /// From 1c428ec987eb60fe1fcf031bc0ae7758de942653 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 7 Aug 2025 14:04:59 +0200 Subject: [PATCH 5/9] move `type_check` out of `compute_regions` --- compiler/rustc_borrowck/src/lib.rs | 45 ++++++++++++++++++++++++++--- compiler/rustc_borrowck/src/nll.rs | 46 ++++++++---------------------- 2 files changed, 53 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 321b18c9b78b2..752ff8e6f586b 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -19,6 +19,7 @@ use std::borrow::Cow; use std::cell::{OnceCell, RefCell}; use std::marker::PhantomData; use std::ops::{ControlFlow, Deref}; +use std::rc::Rc; use borrow_set::LocalsStateAtExit; use root_cx::BorrowCheckRootCtxt; @@ -44,6 +45,7 @@ use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces} use rustc_mir_dataflow::move_paths::{ InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex, }; +use rustc_mir_dataflow::points::DenseLocationMap; use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor, visit_results}; use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT}; use rustc_span::{ErrorGuaranteed, Span, Symbol}; @@ -60,11 +62,14 @@ use crate::path_utils::*; use crate::place_ext::PlaceExt; use crate::places_conflict::{PlaceConflictBias, places_conflict}; use crate::polonius::PoloniusDiagnosticsContext; -use crate::polonius::legacy::{PoloniusLocationTable, PoloniusOutput}; +use crate::polonius::legacy::{ + PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput, +}; use crate::prefixes::PrefixSet; use crate::region_infer::RegionInferenceContext; use crate::renumber::RegionCtxt; use crate::session_diagnostics::VarNeedNotMut; +use crate::type_check::MirTypeckResults; mod borrow_set; mod borrowck_errors; @@ -321,7 +326,34 @@ fn do_mir_borrowck<'tcx>( let locals_are_invalidated_at_exit = tcx.hir_body_owner_kind(def).is_fn_or_closure(); let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data); - // Compute non-lexical lifetimes. + let location_map = Rc::new(DenseLocationMap::new(body)); + + let polonius_input = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_input()) + || infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled(); + let mut polonius_facts = + (polonius_input || PoloniusFacts::enabled(infcx.tcx)).then_some(PoloniusFacts::default()); + + // Run the MIR type-checker. + let MirTypeckResults { + constraints, + universal_region_relations, + opaque_type_values, + polonius_context, + } = type_check::type_check( + root_cx, + &infcx, + body, + &promoted, + universal_regions, + &location_table, + &borrow_set, + &mut polonius_facts, + &move_data, + Rc::clone(&location_map), + ); + + // Compute non-lexical lifetimes using the constraints computed + // by typechecking the MIR body. let nll::NllOutput { regioncx, polonius_input, @@ -332,14 +364,19 @@ fn do_mir_borrowck<'tcx>( } = nll::compute_regions( root_cx, &infcx, - universal_regions, body, - &promoted, &location_table, &move_data, &borrow_set, + location_map, + universal_region_relations, + constraints, + polonius_facts, + polonius_context, ); + regioncx.infer_opaque_types(root_cx, &infcx, opaque_type_values); + // Dump MIR results into a file, if that is enabled. This lets us // write unit-tests, as well as helping with debugging. nll::dump_nll_mir(&infcx, body, ®ioncx, &opt_closure_req, &borrow_set); diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 41f67e78930f0..ca6092e70d253 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -5,7 +5,8 @@ use std::path::PathBuf; use std::rc::Rc; use std::str::FromStr; -use polonius_engine::{Algorithm, Output}; +use polonius_engine::{Algorithm, AllFacts, Output}; +use rustc_data_structures::frozen::Frozen; use rustc_index::IndexSlice; use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options}; use rustc_middle::mir::{Body, PassWhere, Promoted, create_dump_file, dump_enabled, dump_mir}; @@ -18,14 +19,16 @@ use rustc_span::sym; use tracing::{debug, instrument}; use crate::borrow_set::BorrowSet; +use crate::consumers::RustcFacts; use crate::diagnostics::RegionErrors; use crate::handle_placeholders::compute_sccs_applying_placeholder_outlives_constraints; -use crate::polonius::PoloniusDiagnosticsContext; use crate::polonius::legacy::{ PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput, }; +use crate::polonius::{PoloniusContext, PoloniusDiagnosticsContext}; use crate::region_infer::RegionInferenceContext; -use crate::type_check::{self, MirTypeckResults}; +use crate::type_check::MirTypeckRegionConstraints; +use crate::type_check::free_region_relations::UniversalRegionRelations; use crate::universal_regions::UniversalRegions; use crate::{ BorrowCheckRootCtxt, BorrowckInferCtxt, ClosureOutlivesSubject, ClosureRegionRequirements, @@ -76,41 +79,18 @@ pub(crate) fn replace_regions_in_mir<'tcx>( pub(crate) fn compute_regions<'tcx>( root_cx: &mut BorrowCheckRootCtxt<'tcx>, infcx: &BorrowckInferCtxt<'tcx>, - universal_regions: UniversalRegions<'tcx>, body: &Body<'tcx>, - promoted: &IndexSlice>, location_table: &PoloniusLocationTable, move_data: &MoveData<'tcx>, borrow_set: &BorrowSet<'tcx>, + location_map: Rc, + universal_region_relations: Frozen>, + constraints: MirTypeckRegionConstraints<'tcx>, + mut polonius_facts: Option>, + polonius_context: Option, ) -> NllOutput<'tcx> { - let is_polonius_legacy_enabled = infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled(); - let polonius_input = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_input()) - || is_polonius_legacy_enabled; let polonius_output = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_output()) - || is_polonius_legacy_enabled; - let mut polonius_facts = - (polonius_input || PoloniusFacts::enabled(infcx.tcx)).then_some(PoloniusFacts::default()); - - let location_map = Rc::new(DenseLocationMap::new(body)); - - // Run the MIR type-checker. - let MirTypeckResults { - constraints, - universal_region_relations, - opaque_type_values, - polonius_context, - } = type_check::type_check( - root_cx, - infcx, - body, - promoted, - universal_regions, - location_table, - borrow_set, - &mut polonius_facts, - move_data, - Rc::clone(&location_map), - ); + || infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled(); let lowered_constraints = compute_sccs_applying_placeholder_outlives_constraints( constraints, @@ -173,8 +153,6 @@ pub(crate) fn compute_regions<'tcx>( infcx.set_tainted_by_errors(guar); } - regioncx.infer_opaque_types(root_cx, infcx, opaque_type_values); - NllOutput { regioncx, polonius_input: polonius_facts.map(Box::new), From 488876281660590f08083578084163be5266b854 Mon Sep 17 00:00:00 2001 From: Ulrich Stark Date: Thu, 7 Aug 2025 14:04:12 +0200 Subject: [PATCH 6/9] Fix doc comment of File::try_lock and File::try_lock_shared --- library/std/src/fs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index b3ca118a45295..a220a3f56e9a8 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -814,7 +814,7 @@ impl File { /// /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior /// is unspecified and platform dependent, including the possibility that it will deadlock. - /// However, if this method returns `Ok(true)`, then it has acquired an exclusive lock. + /// However, if this method returns `Ok(())`, then it has acquired an exclusive lock. /// /// If the file is not open for writing, it is unspecified whether this function returns an error. /// @@ -879,7 +879,7 @@ impl File { /// /// If this file handle, or a clone of it, already holds a lock, the exact behavior is /// unspecified and platform dependent, including the possibility that it will deadlock. - /// However, if this method returns `Ok(true)`, then it has acquired a shared lock. + /// However, if this method returns `Ok(())`, then it has acquired a shared lock. /// /// The lock will be released when this file (along with any other file descriptors/handles /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. From d6dc3634dbd3ccfaf13bce4422afa5449b1ce2c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Thu, 7 Aug 2025 13:04:39 +0000 Subject: [PATCH 7/9] add multiple known-bugs for NLL problem case 3 these are fixed by polonius=next and polonius=legacy --- ...nll-problem-case-3-issue-112087.nll.stderr | 17 +++ .../nll-problem-case-3-issue-112087.rs | 25 ++++ ...nll-problem-case-3-issue-123839.nll.stderr | 16 +++ .../nll-problem-case-3-issue-123839.rs | 40 +++++++ ...nll-problem-case-3-issue-124070.nll.stderr | 17 +++ .../nll-problem-case-3-issue-124070.rs | 30 +++++ ...nll-problem-case-3-issue-124254.nll.stderr | 34 ++++++ .../nll-problem-case-3-issue-124254.rs | 45 +++++++ .../nll-problem-case-3-issue-21906.nll.stderr | 96 +++++++++++++++ .../nll-problem-case-3-issue-21906.rs | 85 +++++++++++++ .../nll-problem-case-3-issue-51526.nll.stderr | 18 +++ .../nll-problem-case-3-issue-51526.rs | 30 +++++ .../nll-problem-case-3-issue-51545.nll.stderr | 15 +++ .../nll-problem-case-3-issue-51545.rs | 28 +++++ .../nll-problem-case-3-issue-54663.nll.stderr | 16 +++ .../nll-problem-case-3-issue-54663.rs | 25 ++++ .../nll-problem-case-3-issue-58787.nll.stderr | 112 ++++++++++++++++++ .../nll-problem-case-3-issue-58787.rs | 74 ++++++++++++ .../nll-problem-case-3-issue-68934.nll.stderr | 17 +++ .../nll-problem-case-3-issue-68934.rs | 38 ++++++ 20 files changed, 778 insertions(+) create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-112087.nll.stderr create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-112087.rs create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-123839.nll.stderr create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-123839.rs create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-124070.nll.stderr create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-124070.rs create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-124254.nll.stderr create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-124254.rs create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-51526.nll.stderr create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-51526.rs create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-51545.nll.stderr create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-51545.rs create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-54663.nll.stderr create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-54663.rs create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-58787.nll.stderr create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-58787.rs create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-68934.nll.stderr create mode 100644 tests/ui/nll/polonius/nll-problem-case-3-issue-68934.rs diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.nll.stderr new file mode 100644 index 0000000000000..16b5d8f714847 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.nll.stderr @@ -0,0 +1,17 @@ +error[E0506]: cannot assign to `*opt` because it is borrowed + --> $DIR/nll-problem-case-3-issue-112087.rs:23:5 + | +LL | fn issue_112087<'a>(opt: &'a mut Option, b: bool) -> Result<&'a mut Option, &'a mut i32> { + | -- lifetime `'a` defined here +LL | if let Some(v) = opt { + | - `*opt` is borrowed here +LL | if b { +LL | return Err(v); + | ------ returning this value requires that `opt.0` is borrowed for `'a` +... +LL | *opt = None; + | ^^^^^^^^^^^ `*opt` is assigned to here but it was already borrowed + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0506`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.rs new file mode 100644 index 0000000000000..d7270f6bfa7a3 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-112087.rs @@ -0,0 +1,25 @@ +#![crate_type = "lib"] + +// This is part of a collection of regression tests related to the NLL problem case 3 that was +// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are +// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does +// handle them, as does the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #112087 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +fn issue_112087<'a>(opt: &'a mut Option, b: bool) -> Result<&'a mut Option, &'a mut i32> { + if let Some(v) = opt { + if b { + return Err(v); + } + } + + *opt = None; + return Ok(opt); +} diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.nll.stderr new file mode 100644 index 0000000000000..541789b7f17e4 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.nll.stderr @@ -0,0 +1,16 @@ +error[E0506]: cannot assign to `self.status` because it is borrowed + --> $DIR/nll-problem-case-3-issue-123839.rs:37:9 + | +LL | fn foo(self: &mut Self) -> Result<(), &str> { + | - let's call the lifetime of this reference `'1` +LL | self.bar()?; // rust reports this line conflicts with the next line + | ----------- + | | + | `self.status` is borrowed here + | returning this value requires that `*self` is borrowed for `'1` +LL | self.status = 1; // and this line is the victim + | ^^^^^^^^^^^^^^^ `self.status` is assigned to here but it was already borrowed + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0506`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.rs new file mode 100644 index 0000000000000..a738dace73d70 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-123839.rs @@ -0,0 +1,40 @@ +#![crate_type = "lib"] + +// This is part of a collection of regression tests related to the NLL problem case 3 that was +// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are +// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does +// handle them, as does the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #123839 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +struct Foo { + val: i32, + status: i32, + err_str: String, +} + +impl Foo { + fn bar(self: &mut Self) -> Result<(), &str> { + if self.val == 0 { + self.status = -1; + Err("val is zero") + } else if self.val < 0 { + self.status = -2; + self.err_str = format!("unexpected negative val {}", self.val); + Err(&self.err_str) + } else { + Ok(()) + } + } + fn foo(self: &mut Self) -> Result<(), &str> { + self.bar()?; // rust reports this line conflicts with the next line + self.status = 1; // and this line is the victim + Ok(()) + } +} diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.nll.stderr new file mode 100644 index 0000000000000..7c2a383e89c6a --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.nll.stderr @@ -0,0 +1,17 @@ +error[E0502]: cannot borrow `self.field` as immutable because it is also borrowed as mutable + --> $DIR/nll-problem-case-3-issue-124070.rs:28:16 + | +LL | fn f(&mut self) -> &str { + | - let's call the lifetime of this reference `'1` +LL | let a = &mut self.field; + | --------------- mutable borrow occurs here +... +LL | return a; + | - returning this value requires that `self.field` is borrowed for `'1` +... +LL | return &self.field; + | ^^^^^^^^^^^ immutable borrow occurs here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.rs new file mode 100644 index 0000000000000..ddf331db8bbbf --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-124070.rs @@ -0,0 +1,30 @@ +#![crate_type = "lib"] + +// This is part of a collection of regression tests related to the NLL problem case 3 that was +// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are +// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does +// handle them, as does the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #124070 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +struct S { + field: String, +} + +impl S { + fn f(&mut self) -> &str { + let a = &mut self.field; + + if false { + return a; + } + + return &self.field; + } +} diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.nll.stderr new file mode 100644 index 0000000000000..bd5f1203f313f --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.nll.stderr @@ -0,0 +1,34 @@ +error[E0499]: cannot borrow `list[_]` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-124254.rs:30:5 + | +LL | fn find_lowest_or_first_empty_pos(list: &mut [Option]) -> &mut Option { + | - let's call the lifetime of this reference `'1` +LL | let mut low_pos_val: Option<(usize, u8)> = None; +LL | for (idx, i) in list.iter_mut().enumerate() { + | ---- first mutable borrow occurs here +LL | let Some(s) = i else { +LL | return i; + | - returning this value requires that `*list` is borrowed for `'1` +... +LL | &mut list[lowest_idx] + | ^^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + +error[E0503]: cannot use `*list` because it was mutably borrowed + --> $DIR/nll-problem-case-3-issue-124254.rs:30:10 + | +LL | fn find_lowest_or_first_empty_pos(list: &mut [Option]) -> &mut Option { + | - let's call the lifetime of this reference `'1` +LL | let mut low_pos_val: Option<(usize, u8)> = None; +LL | for (idx, i) in list.iter_mut().enumerate() { + | ---- `*list` is borrowed here +LL | let Some(s) = i else { +LL | return i; + | - returning this value requires that `*list` is borrowed for `'1` +... +LL | &mut list[lowest_idx] + | ^^^^^^^^^^^^^^^^ use of borrowed `*list` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0499, E0503. +For more information about an error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.rs new file mode 100644 index 0000000000000..e3bc2c2febc55 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-124254.rs @@ -0,0 +1,45 @@ +// This is part of a collection of regression tests related to the NLL problem case 3 that was +// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are +// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does +// handle them, as does the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #124254 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +fn find_lowest_or_first_empty_pos(list: &mut [Option]) -> &mut Option { + let mut low_pos_val: Option<(usize, u8)> = None; + for (idx, i) in list.iter_mut().enumerate() { + let Some(s) = i else { + return i; + }; + + low_pos_val = match low_pos_val { + Some((_oidx, oval)) if oval > *s => Some((idx, *s)), + Some(old) => Some(old), + None => Some((idx, *s)), + }; + } + let Some((lowest_idx, _)) = low_pos_val else { + unreachable!("Can't have zero length list!"); + }; + &mut list[lowest_idx] +} + +fn main() { + let mut list = [Some(1), Some(2), None, Some(3)]; + let v = find_lowest_or_first_empty_pos(&mut list); + assert!(v.is_none()); + assert_eq!(v as *mut _ as usize, list.as_ptr().wrapping_add(2) as usize); + + let mut list = [Some(1), Some(2), Some(3), Some(0)]; + let v = find_lowest_or_first_empty_pos(&mut list); + assert_eq!(v, &mut Some(0)); + assert_eq!(v as *mut _ as usize, list.as_ptr().wrapping_add(3) as usize); + + println!("pass"); +} diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr new file mode 100644 index 0000000000000..dc38b8c127e54 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr @@ -0,0 +1,96 @@ +error[E0499]: cannot borrow `*map` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-21906.rs:26:13 + | +LL | fn from_the_rfc<'r, K: Hash + Eq + Copy, V: Default>( + | -- lifetime `'r` defined here +... +LL | match map.get_mut(&key) { + | - --- first mutable borrow occurs here + | _____| + | | +LL | | Some(value) => value, +LL | | None => { +LL | | map.insert(key, V::default()); + | | ^^^ second mutable borrow occurs here +... | +LL | | } + | |_____- returning this value requires that `*map` is borrowed for `'r` + +error[E0499]: cannot borrow `*map` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-21906.rs:27:13 + | +LL | fn from_the_rfc<'r, K: Hash + Eq + Copy, V: Default>( + | -- lifetime `'r` defined here +... +LL | match map.get_mut(&key) { + | - --- first mutable borrow occurs here + | _____| + | | +LL | | Some(value) => value, +LL | | None => { +LL | | map.insert(key, V::default()); +LL | | map.get_mut(&key).unwrap() + | | ^^^ second mutable borrow occurs here +LL | | } +LL | | } + | |_____- returning this value requires that `*map` is borrowed for `'r` + +error[E0499]: cannot borrow `*self` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-21906.rs:44:21 + | +LL | fn two(&mut self) -> &i32 { + | - let's call the lifetime of this reference `'1` +LL | loop { +LL | let k = self.one(); + | ^^^^ `*self` was mutably borrowed here in the previous iteration of the loop +LL | if *k > 10i32 { +LL | return k; + | - returning this value requires that `*self` is borrowed for `'1` + +error[E0502]: cannot borrow `x.data` as immutable because it is also borrowed as mutable + --> $DIR/nll-problem-case-3-issue-21906.rs:62:22 + | +LL | fn foo(x: &mut Foo) -> Option<&mut i32> { + | - let's call the lifetime of this reference `'1` +LL | if let Some(y) = x.data.as_mut() { + | ------ mutable borrow occurs here +LL | return Some(y); + | ------- returning this value requires that `x.data` is borrowed for `'1` +... +LL | println!("{:?}", x.data); + | ^^^^^^ immutable borrow occurs here + | + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0499]: cannot borrow `*vec` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-21906.rs:77:9 + | +LL | fn f(vec: &mut Vec) -> &u8 { + | - let's call the lifetime of this reference `'1` +LL | if let Some(n) = vec.iter_mut().find(|n| **n == 1) { + | --- first mutable borrow occurs here +LL | *n = 10; +LL | n + | - returning this value requires that `*vec` is borrowed for `'1` +LL | } else { +LL | vec.push(10); + | ^^^ second mutable borrow occurs here + +error[E0502]: cannot borrow `*vec` as immutable because it is also borrowed as mutable + --> $DIR/nll-problem-case-3-issue-21906.rs:78:9 + | +LL | fn f(vec: &mut Vec) -> &u8 { + | - let's call the lifetime of this reference `'1` +LL | if let Some(n) = vec.iter_mut().find(|n| **n == 1) { + | --- mutable borrow occurs here +LL | *n = 10; +LL | n + | - returning this value requires that `*vec` is borrowed for `'1` +... +LL | vec.last().unwrap() + | ^^^ immutable borrow occurs here + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0499, E0502. +For more information about an error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs new file mode 100644 index 0000000000000..b025ea78f8b49 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs @@ -0,0 +1,85 @@ +#![crate_type = "lib"] + +// This is part of a collection of regression tests related to the NLL problem case 3 that was +// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are +// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does +// handle them, as does the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #21906 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +use std::collections::HashMap; +use std::hash::Hash; + +fn from_the_rfc<'r, K: Hash + Eq + Copy, V: Default>( + map: &'r mut HashMap, + key: K, +) -> &'r mut V { + match map.get_mut(&key) { + Some(value) => value, + None => { + map.insert(key, V::default()); + map.get_mut(&key).unwrap() + } + } +} + +// MCVE 1 from issue #21906 +struct A { + a: i32, +} + +impl A { + fn one(&mut self) -> &i32 { + self.a = 10; + &self.a + } + fn two(&mut self) -> &i32 { + loop { + let k = self.one(); + if *k > 10i32 { + return k; + } + } + } +} + +// MCVE 2 +struct Foo { + data: Option, +} + +fn foo(x: &mut Foo) -> Option<&mut i32> { + if let Some(y) = x.data.as_mut() { + return Some(y); + } + + println!("{:?}", x.data); + None +} + +fn mcve2() { + let mut x = Foo { data: Some(1) }; + foo(&mut x); +} + +// MCVE 3 +fn f(vec: &mut Vec) -> &u8 { + if let Some(n) = vec.iter_mut().find(|n| **n == 1) { + *n = 10; + n + } else { + vec.push(10); + vec.last().unwrap() + } +} + +fn mcve3() { + let mut vec = vec![1, 2, 3]; + f(&mut vec); +} diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.nll.stderr new file mode 100644 index 0000000000000..9a740a0edc741 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.nll.stderr @@ -0,0 +1,18 @@ +error[E0502]: cannot borrow `*queue` as mutable because it is also borrowed as immutable + --> $DIR/nll-problem-case-3-issue-51526.rs:26:9 + | +LL | fn next(queue: &mut VecDeque, above: u32) -> Option<&u32> { + | - let's call the lifetime of this reference `'1` +... +LL | let next = queue.front()?; + | ----- immutable borrow occurs here +... +LL | queue.pop_front(); + | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here +... +LL | Some(result) + | ------------ returning this value requires that `*queue` is borrowed for `'1` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.rs new file mode 100644 index 0000000000000..3cf211586b23b --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-51526.rs @@ -0,0 +1,30 @@ +#![crate_type = "lib"] + +// This is part of a collection of regression tests related to the NLL problem case 3 that was +// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are +// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does +// handle them, as does the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #51526 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +use std::collections::VecDeque; + +fn next(queue: &mut VecDeque, above: u32) -> Option<&u32> { + let result = loop { + { + let next = queue.front()?; + if *next > above { + break next; + } + } + queue.pop_front(); + }; + + Some(result) +} diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.nll.stderr new file mode 100644 index 0000000000000..c6a0e1b282f99 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.nll.stderr @@ -0,0 +1,15 @@ +error[E0499]: cannot borrow `*o` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-51545.rs:17:17 + | +LL | fn borrow(o: &mut Option) -> Option<&mut i32> { + | - let's call the lifetime of this reference `'1` +LL | match o.as_mut() { + | - first mutable borrow occurs here +LL | Some(i) => Some(i), + | ------- returning this value requires that `*o` is borrowed for `'1` +LL | None => o.as_mut(), + | ^ second mutable borrow occurs here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.rs new file mode 100644 index 0000000000000..786a8b564b9f8 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-51545.rs @@ -0,0 +1,28 @@ +// This is part of a collection of regression tests related to the NLL problem case 3 that was +// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are +// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does +// handle them, as does the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #51545 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +fn borrow(o: &mut Option) -> Option<&mut i32> { + match o.as_mut() { + Some(i) => Some(i), + None => o.as_mut(), + } +} + +fn main() { + let mut o: Option = Some(1i32); + + let x = match o.as_mut() { + Some(i) => Some(i), + None => o.as_mut(), + }; +} diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.nll.stderr new file mode 100644 index 0000000000000..fd6fa7632d5d4 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.nll.stderr @@ -0,0 +1,16 @@ +error[E0499]: cannot borrow `*x` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-54663.rs:20:9 + | +LL | fn foo(x: &mut u8) -> Option<&u8> { + | - let's call the lifetime of this reference `'1` +LL | if let Some(y) = bar(x) { + | - first mutable borrow occurs here +LL | return Some(y); + | ------- returning this value requires that `*x` is borrowed for `'1` +LL | } +LL | bar(x) + | ^ second mutable borrow occurs here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.rs new file mode 100644 index 0000000000000..b4d571fb9c795 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-54663.rs @@ -0,0 +1,25 @@ +#![crate_type = "lib"] + +// This is part of a collection of regression tests related to the NLL problem case 3 that was +// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are +// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does +// handle them, as does the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #54663 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +fn foo(x: &mut u8) -> Option<&u8> { + if let Some(y) = bar(x) { + return Some(y); + } + bar(x) +} + +fn bar(x: &mut u8) -> Option<&u8> { + Some(x) +} diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.nll.stderr new file mode 100644 index 0000000000000..53002892df1c0 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.nll.stderr @@ -0,0 +1,112 @@ +error[E0503]: cannot use `list.0` because it was mutably borrowed + --> $DIR/nll-problem-case-3-issue-58787.rs:34:11 + | +LL | Some(ref mut d) => { + | --------- `list.0.0` is borrowed here +... +LL | match list.0 { + | ^^^^^^ + | | + | use of borrowed `list.0.0` + | borrow later used here + +error[E0499]: cannot borrow `list.0.0` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-58787.rs:35:14 + | +LL | Some(ref mut d) => { + | --------- first mutable borrow occurs here +... +LL | Some(ref mut d) => { + | ^^^^^^^^^ + | | + | second mutable borrow occurs here + | first borrow later used here + +error[E0503]: cannot use `list.0` because it was mutably borrowed + --> $DIR/nll-problem-case-3-issue-58787.rs:41:11 + | +LL | Some(ref mut d) => { + | --------- `list.0.0` is borrowed here +... +LL | match list { + | ^^^^ + | | + | use of borrowed `list.0.0` + | borrow later used here + +error[E0499]: cannot borrow `list.0.0` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-58787.rs:42:19 + | +LL | Some(ref mut d) => { + | --------- first mutable borrow occurs here +... +LL | List(Some(d)) => { + | ^ + | | + | second mutable borrow occurs here + | first borrow later used here + +error[E0503]: cannot use `list.0` because it was mutably borrowed + --> $DIR/nll-problem-case-3-issue-58787.rs:50:11 + | +LL | List(Some(d)) => { + | - `list.0.0` is borrowed here +... +LL | match list { + | ^^^^ + | | + | use of borrowed `list.0.0` + | borrow later used here + +error[E0499]: cannot borrow `list.0.0` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-58787.rs:51:19 + | +LL | List(Some(d)) => { + | - first mutable borrow occurs here +... +LL | List(Some(d)) => { + | ^ + | | + | second mutable borrow occurs here + | first borrow later used here + +error[E0499]: cannot borrow `list.0` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-58787.rs:57:11 + | +LL | List(Some(d)) => { + | - first mutable borrow occurs here +... +LL | match &mut list.0 { + | ^^^^^^^^^^^ + | | + | second mutable borrow occurs here + | first borrow later used here + +error[E0499]: cannot borrow `list.0` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-58787.rs:66:11 + | +LL | match &mut list.0 { + | ----------- first mutable borrow occurs here +... +LL | match &mut list.0 { + | ^^^^^^^^^^^ + | | + | second mutable borrow occurs here + | first borrow later used here + +error[E0506]: cannot assign to `list.0` because it is borrowed + --> $DIR/nll-problem-case-3-issue-58787.rs:73:5 + | +LL | match &mut list.0 { + | ----------- `list.0` is borrowed here +... +LL | list.0 = None; + | ^^^^^^ + | | + | `list.0` is assigned to here but it was already borrowed + | borrow later used here + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0499, E0503, E0506. +For more information about an error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.rs new file mode 100644 index 0000000000000..75552e24219a0 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-58787.rs @@ -0,0 +1,74 @@ +#![crate_type = "lib"] + +// This is part of a collection of regression tests related to the NLL problem case 3 that was +// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are +// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does +// handle them, as does the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #58787 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +struct Node { + rest: List, +} + +struct List(Option>); + +fn issue_58787(arg: &mut List) { + let mut list = arg; + + match list.0 { + Some(ref mut d) => { + if true { + list = &mut d.rest; + } + } + None => (), + } + + match list.0 { + Some(ref mut d) => { + list = &mut d.rest; + } + None => (), + } + + match list { + List(Some(d)) => { + if true { + list = &mut d.rest; + } + } + List(None) => (), + } + + match list { + List(Some(d)) => { + list = &mut d.rest; + } + List(None) => (), + } + + match &mut list.0 { + Some(d) => { + if true { + list = &mut d.rest; + } + } + None => (), + } + + match &mut list.0 { + Some(d) => { + list = &mut d.rest; + } + None => (), + } + + list.0 = None; +} diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.nll.stderr new file mode 100644 index 0000000000000..212355790bf96 --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.nll.stderr @@ -0,0 +1,17 @@ +error[E0505]: cannot move out of value because it is borrowed + --> $DIR/nll-problem-case-3-issue-68934.rs:35:14 + | +LL | fn deep_fetch(&mut self, value: Either) -> Result<&mut Self, (&mut Self, Either)> { + | - let's call the lifetime of this reference `'1` +LL | match (self, value) { +LL | (Tree::ABranch(ref mut a, ref v), Either::Left(vv)) if v > &vv => { + | --------- borrow of value occurs here +LL | a.deep_fetch(Either::Left(vv)) + | ------------------------------ returning this value requires that borrow lasts for `'1` +... +LL | (this, _v) => Err((this, _v)), + | ^^^^ move out of value occurs here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0505`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.rs new file mode 100644 index 0000000000000..ba9415101169b --- /dev/null +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-68934.rs @@ -0,0 +1,38 @@ +#![crate_type = "lib"] + +// This is part of a collection of regression tests related to the NLL problem case 3 that was +// deferred from the implementation of the NLL RFC, and left to be implemented by polonius. They are +// from open issues, e.g. tagged fixed-by-polonius, to ensure that the polonius alpha analysis does +// handle them, as does the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #68934 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +enum Either { + Left(A), + Right(B), +} + +enum Tree<'a, A, B> { + ALeaf(A), + BLeaf(B), + ABranch(&'a mut Tree<'a, A, B>, A), + BBranch(&'a mut Tree<'a, A, B>, B), +} + +impl<'a, A: PartialOrd, B> Tree<'a, A, B> { + fn deep_fetch(&mut self, value: Either) -> Result<&mut Self, (&mut Self, Either)> { + match (self, value) { + (Tree::ABranch(ref mut a, ref v), Either::Left(vv)) if v > &vv => { + a.deep_fetch(Either::Left(vv)) + } + + (this, _v) => Err((this, _v)), + } + } +} From e3aae6162e7f0bdacb8b41c7b2f1d92100a0c476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Thu, 7 Aug 2025 13:06:35 +0000 Subject: [PATCH 8/9] add filtering lending iterator known-bug --- ...ng-lending-iterator-issue-92985.nll.stderr | 14 +++++ .../filtering-lending-iterator-issue-92985.rs | 56 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr create mode 100644 tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs diff --git a/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr new file mode 100644 index 0000000000000..d5c85a2af239a --- /dev/null +++ b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr @@ -0,0 +1,14 @@ +error[E0499]: cannot borrow `self.iter` as mutable more than once at a time + --> $DIR/filtering-lending-iterator-issue-92985.rs:49:32 + | +LL | fn next(&mut self) -> Option> { + | - let's call the lifetime of this reference `'1` +LL | while let Some(item) = self.iter.next() { + | ^^^^^^^^^ `self.iter` was mutably borrowed here in the previous iteration of the loop +LL | if (self.predicate)(&item) { +LL | return Some(item); + | ---------- returning this value requires that `self.iter` is borrowed for `'1` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs new file mode 100644 index 0000000000000..27da62ef00b49 --- /dev/null +++ b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs @@ -0,0 +1,56 @@ +#![crate_type = "lib"] + +// This test is an example of a filtering lending iterator with GATs from #92985 (that is similar to +// NLL problem case #3) to ensure it "works" with the polonius alpha analysis as with the datalog +// implementation. +// +// The polonius analysis only changes how the `Filter::next` function is borrowcked, not the bounds +// on the predicate from using the GAT. So even if the #92985 limitation is removed, the unrelated +// 'static limitation on the predicate argument is still there, and the pattern is still impractical +// to use in the real world. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #92985 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +trait LendingIterator { + type Item<'a> + where + Self: 'a; + fn next(&mut self) -> Option>; + + fn filter

(self, predicate: P) -> Filter + where + Self: Sized, + P: FnMut(&Self::Item<'_>) -> bool, + { + Filter { iter: self, predicate } + } +} + +pub struct Filter { + iter: I, + predicate: P, +} +impl LendingIterator for Filter +where + P: FnMut(&I::Item<'_>) -> bool, +{ + type Item<'a> + = I::Item<'a> + where + Self: 'a; + + fn next(&mut self) -> Option> { + while let Some(item) = self.iter.next() { + if (self.predicate)(&item) { + return Some(item); + } + } + return None; + } +} From 202963f2215245180fa985f3640a582554656253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Thu, 7 Aug 2025 13:33:35 +0000 Subject: [PATCH 9/9] add multiple known-bugs for the linked-list cursor-like pattern of 46859/48001 these are fixed by polonius=legacy, are currently accepted by polonius=next but won't be by the alpha analysis --- ...ng-updating-cursor-issue-108704.nll.stderr | 12 +++++ .../iterating-updating-cursor-issue-108704.rs | 47 +++++++++++++++++++ ...ing-updating-cursor-issue-57165.nll.stderr | 22 +++++++++ .../iterating-updating-cursor-issue-57165.rs | 44 +++++++++++++++++ ...ing-updating-cursor-issue-63908.nll.stderr | 18 +++++++ .../iterating-updating-cursor-issue-63908.rs | 43 +++++++++++++++++ 6 files changed, 186 insertions(+) create mode 100644 tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr create mode 100644 tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs create mode 100644 tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr create mode 100644 tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs create mode 100644 tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr create mode 100644 tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr new file mode 100644 index 0000000000000..7ac4e5de28384 --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr @@ -0,0 +1,12 @@ +error[E0499]: cannot borrow `*elements` as mutable more than once at a time + --> $DIR/iterating-updating-cursor-issue-108704.rs:40:26 + | +LL | for (idx, el) in elements.iter_mut().enumerate() { + | ^^^^^^^^ + | | + | `*elements` was mutably borrowed here in the previous iteration of the loop + | first borrow used here, in later iteration of loop + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs new file mode 100644 index 0000000000000..420cb73bed283 --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs @@ -0,0 +1,47 @@ +#![crate_type = "lib"] + +// An example from #108704 of the linked-list cursor-like pattern of #46859/#48001. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #108704 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +struct Root { + children: Vec, +} + +struct Node { + name: String, + children: Vec, +} + +fn merge_tree_ok(root: &mut Root, path: Vec) { + let mut elements = &mut root.children; + + for p in path.iter() { + for (idx, el) in elements.iter_mut().enumerate() { + if el.name == *p { + elements = &mut elements[idx].children; + break; + } + } + } +} + +// NLLs fail here +fn merge_tree_ko(root: &mut Root, path: Vec) { + let mut elements = &mut root.children; + + for p in path.iter() { + for (idx, el) in elements.iter_mut().enumerate() { + if el.name == *p { + elements = &mut el.children; + break; + } + } + } +} diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr new file mode 100644 index 0000000000000..14e1726e158f4 --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr @@ -0,0 +1,22 @@ +error[E0499]: cannot borrow `p.0` as mutable more than once at a time + --> $DIR/iterating-updating-cursor-issue-57165.rs:29:20 + | +LL | while let Some(now) = p { + | ^^^ - first borrow used here, in later iteration of loop + | | + | `p.0` was mutably borrowed here in the previous iteration of the loop + +error[E0503]: cannot use `*p` because it was mutably borrowed + --> $DIR/iterating-updating-cursor-issue-57165.rs:29:27 + | +LL | while let Some(now) = p { + | --- ^ + | | | + | | use of borrowed `p.0` + | | borrow later used here + | `p.0` is borrowed here + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0499, E0503. +For more information about an error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs new file mode 100644 index 0000000000000..63ec89146d4a7 --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs @@ -0,0 +1,44 @@ +#![crate_type = "lib"] + +// An example from #57165 of the linked-list cursor-like pattern of #46859/#48001. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #57165 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +struct X { + next: Option>, +} + +fn no_control_flow() { + let mut b = Some(Box::new(X { next: None })); + let mut p = &mut b; + while let Some(now) = p { + p = &mut now.next; + } +} + +// NLLs fail here +fn conditional() { + let mut b = Some(Box::new(X { next: None })); + let mut p = &mut b; + while let Some(now) = p { + if true { + p = &mut now.next; + } + } +} + +fn conditional_with_indirection() { + let mut b = Some(Box::new(X { next: None })); + let mut p = &mut b; + while let Some(now) = p { + if true { + p = &mut p.as_mut().unwrap().next; + } + } +} diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr new file mode 100644 index 0000000000000..bf38da566c694 --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr @@ -0,0 +1,18 @@ +error[E0506]: cannot assign to `*node_ref` because it is borrowed + --> $DIR/iterating-updating-cursor-issue-63908.rs:42:5 + | +LL | fn remove_last_node_iterative(mut node_ref: &mut List) { + | - let's call the lifetime of this reference `'1` +LL | loop { +LL | let next_ref = &mut node_ref.as_mut().unwrap().next; + | -------- `*node_ref` is borrowed here +... +LL | node_ref = next_ref; + | ------------------- assignment requires that `*node_ref` is borrowed for `'1` +... +LL | *node_ref = None; + | ^^^^^^^^^ `*node_ref` is assigned to here but it was already borrowed + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0506`. diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs new file mode 100644 index 0000000000000..00e48b65fed15 --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs @@ -0,0 +1,43 @@ +#![crate_type = "lib"] + +// An example from #63908 of the linked-list cursor-like pattern of #46859/#48001. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #63908 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +struct Node { + value: T, + next: Option>, +} + +type List = Option>>; + +fn remove_last_node_recursive(node_ref: &mut List) { + let next_ref = &mut node_ref.as_mut().unwrap().next; + + if next_ref.is_some() { + remove_last_node_recursive(next_ref); + } else { + *node_ref = None; + } +} + +// NLLs fail here +fn remove_last_node_iterative(mut node_ref: &mut List) { + loop { + let next_ref = &mut node_ref.as_mut().unwrap().next; + + if next_ref.is_some() { + node_ref = next_ref; + } else { + break; + } + } + + *node_ref = None; +}