diff options
| author | bors <bors@rust-lang.org> | 2023-12-19 05:07:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-12-19 05:07:32 +0000 |
| commit | f36251f689c470aaa81c31710b96fc3e51029852 (patch) | |
| tree | 5abaccd88ccb2f5852113cbbb76418387134d508 /tests | |
| parent | 1929606c3e31385719253c21be0360a51c787161 (diff) | |
| parent | 0f70ced1280124e2078ec5838ac173c13f400e2e (diff) | |
| download | rust-f36251f689c470aaa81c31710b96fc3e51029852.tar.gz rust-f36251f689c470aaa81c31710b96fc3e51029852.zip | |
Auto merge of #3232 - rust-lang:rustup-2023-12-19, r=saethlin
Automatic Rustup
Diffstat (limited to 'tests')
97 files changed, 2013 insertions, 629 deletions
diff --git a/tests/codegen/debug-accessibility/crate-enum.rs b/tests/codegen/debug-accessibility/crate-enum.rs new file mode 100644 index 00000000000..eeea18dd815 --- /dev/null +++ b/tests/codegen/debug-accessibility/crate-enum.rs @@ -0,0 +1,26 @@ +// compile-flags: -C debuginfo=2 +// ignore-tidy-linelength + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for crate-visibility enums. + +mod module { + use std::hint::black_box; + + pub(crate) enum CrateFooEnum { + A, + B(u32), + C { x: u32 }, + } + + // NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "CrateFooEnum"{{.*}}flags: DIFlagProtected{{.*}}) + // MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<crate_enum::module::CrateFooEnum>"{{.*}}flags: DIFlagProtected{{.*}}) + pub fn use_everything() { + black_box(CrateFooEnum::A); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/debug-accessibility/crate-struct.rs b/tests/codegen/debug-accessibility/crate-struct.rs new file mode 100644 index 00000000000..68d126a3478 --- /dev/null +++ b/tests/codegen/debug-accessibility/crate-struct.rs @@ -0,0 +1,23 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for crate-visibility structs. + +mod module { + use std::hint::black_box; + + pub(crate) struct CrateFooStruct { + x: u32, + } + + // CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "CrateFooStruct"{{.*}}flags: DIFlagProtected{{.*}}) + + pub fn use_everything() { + black_box(CrateFooStruct { x: 2 }); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/debug-accessibility/private-enum.rs b/tests/codegen/debug-accessibility/private-enum.rs new file mode 100644 index 00000000000..7f81026ddec --- /dev/null +++ b/tests/codegen/debug-accessibility/private-enum.rs @@ -0,0 +1,21 @@ +// compile-flags: -C debuginfo=2 +// ignore-tidy-linelength + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for private enums. + +use std::hint::black_box; + +enum PrivateFooEnum { + A, + B(u32), + C { x: u32 }, +} + +// NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PrivateFooEnum"{{.*}}flags: DIFlagPrivate{{.*}}) +// MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<private_enum::PrivateFooEnum>"{{.*}}flags: DIFlagPrivate{{.*}}) + +fn main() { + black_box(PrivateFooEnum::A); +} diff --git a/tests/codegen/debug-accessibility/private-struct.rs b/tests/codegen/debug-accessibility/private-struct.rs new file mode 100644 index 00000000000..43b260f9024 --- /dev/null +++ b/tests/codegen/debug-accessibility/private-struct.rs @@ -0,0 +1,17 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for private structs. + +use std::hint::black_box; + +struct PrivateFooStruct { + x: u32, +} + +// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PrivateFooStruct"{{.*}}flags: DIFlagPrivate{{.*}}) + +fn main() { + black_box(PrivateFooStruct { x: 1 }); +} diff --git a/tests/codegen/debug-accessibility/public-enum.rs b/tests/codegen/debug-accessibility/public-enum.rs new file mode 100644 index 00000000000..29ae5fd6421 --- /dev/null +++ b/tests/codegen/debug-accessibility/public-enum.rs @@ -0,0 +1,21 @@ +// compile-flags: -C debuginfo=2 +// ignore-tidy-linelength + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for types and their fields. + +use std::hint::black_box; + +pub enum PublicFooEnum { + A, + B(u32), + C { x: u32 }, +} + +// NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PublicFooEnum"{{.*}}flags: DIFlagPublic{{.*}}) +// MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<public_enum::PublicFooEnum>"{{.*}}flags: DIFlagPublic{{.*}}) + +fn main() { + black_box(PublicFooEnum::A); +} diff --git a/tests/codegen/debug-accessibility/public-struct.rs b/tests/codegen/debug-accessibility/public-struct.rs new file mode 100644 index 00000000000..e7cd9b40d09 --- /dev/null +++ b/tests/codegen/debug-accessibility/public-struct.rs @@ -0,0 +1,17 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for public structs. + +use std::hint::black_box; + +pub struct PublicFooStruct { + x: u32, +} + +// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PublicFooStruct"{{.*}}flags: DIFlagPublic{{.*}}) + +fn main() { + black_box(PublicFooStruct { x: 4 }); +} diff --git a/tests/codegen/debug-accessibility/struct-fields.rs b/tests/codegen/debug-accessibility/struct-fields.rs new file mode 100644 index 00000000000..76831bdc6c6 --- /dev/null +++ b/tests/codegen/debug-accessibility/struct-fields.rs @@ -0,0 +1,30 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for struct fields. + +mod module { + use std::hint::black_box; + + struct StructFields { + a: u32, + pub(crate) b: u32, + pub(super) c: u32, + pub d: u32, + } + + // CHECK: [[StructFields:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "StructFields"{{.*}}flags: DIFlagPrivate{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: [[StructFields]]{{.*}}flags: DIFlagPrivate{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: [[StructFields]]{{.*}}flags: DIFlagProtected{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: [[StructFields]]{{.*}}flags: DIFlagProtected{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: [[StructFields]]{{.*}}flags: DIFlagPublic{{.*}}) + + pub fn use_everything() { + black_box(StructFields { a: 1, b: 2, c: 3, d: 4 }); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/debug-accessibility/super-enum.rs b/tests/codegen/debug-accessibility/super-enum.rs new file mode 100644 index 00000000000..9d83fb45bd0 --- /dev/null +++ b/tests/codegen/debug-accessibility/super-enum.rs @@ -0,0 +1,27 @@ +// compile-flags: -C debuginfo=2 +// ignore-tidy-linelength + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for super-visibility enums. + +mod module { + use std::hint::black_box; + + pub(super) enum SuperFooEnum { + A, + B(u32), + C { x: u32 }, + } + + // NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "SuperFooEnum"{{.*}}flags: DIFlagProtected{{.*}}) + // MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<super_enum::module::SuperFooEnum>"{{.*}}flags: DIFlagProtected{{.*}}) + + pub fn use_everything() { + black_box(SuperFooEnum::A); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/debug-accessibility/super-struct.rs b/tests/codegen/debug-accessibility/super-struct.rs new file mode 100644 index 00000000000..481006c3965 --- /dev/null +++ b/tests/codegen/debug-accessibility/super-struct.rs @@ -0,0 +1,23 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for super-visibility structs. + +mod module { + use std::hint::black_box; + + pub(super) struct SuperFooStruct { + x: u32, + } + + // CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "SuperFooStruct"{{.*}}flags: DIFlagProtected{{.*}}) + + pub fn use_everything() { + black_box(SuperFooStruct { x: 3 }); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/debug-accessibility/tuple-fields.rs b/tests/codegen/debug-accessibility/tuple-fields.rs new file mode 100644 index 00000000000..1163ba2c7c3 --- /dev/null +++ b/tests/codegen/debug-accessibility/tuple-fields.rs @@ -0,0 +1,24 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for tuple struct fields. + +mod module { + use std::hint::black_box; + + struct TupleFields(u32, pub(crate) u32, pub(super) u32, pub u32); + + // CHECK: [[TupleFields:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "TupleFields"{{.*}}flags: DIFlagPrivate{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: [[TupleFields]]{{.*}}flags: DIFlagPrivate{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__1", scope: [[TupleFields]]{{.*}}flags: DIFlagProtected{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__2", scope: [[TupleFields]]{{.*}}flags: DIFlagProtected{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__3", scope: [[TupleFields]]{{.*}}flags: DIFlagPublic{{.*}}) + pub fn use_everything() { + black_box(TupleFields(1, 2, 3, 4)); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/coverage/assert_not.cov-map b/tests/coverage/assert_not.cov-map new file mode 100644 index 00000000000..788bc5dbf58 --- /dev/null +++ b/tests/coverage/assert_not.cov-map @@ -0,0 +1,16 @@ +Function name: assert_not::main +Raw bytes (33): 0x[01, 01, 02, 05, 00, 0d, 00, 05, 01, 06, 01, 01, 12, 05, 02, 05, 00, 14, 02, 01, 05, 00, 14, 0d, 01, 05, 00, 16, 06, 01, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 2 +- expression 0 operands: lhs = Counter(1), rhs = Zero +- expression 1 operands: lhs = Counter(3), rhs = Zero +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 18) +- Code(Counter(1)) at (prev + 2, 5) to (start + 0, 20) +- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 20) + = (c1 - Zero) +- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 22) +- Code(Expression(1, Sub)) at (prev + 1, 1) to (start + 0, 2) + = (c3 - Zero) + diff --git a/tests/coverage/assert_not.coverage b/tests/coverage/assert_not.coverage new file mode 100644 index 00000000000..4cfdab974ed --- /dev/null +++ b/tests/coverage/assert_not.coverage @@ -0,0 +1,12 @@ + LL| |// edition: 2021 + LL| | + LL| |// Regression test for <https://github.com/rust-lang/rust/issues/118904>. + LL| |// `assert!(true)` and `assert!(!false)` should have similar coverage spans. + LL| | + LL| 1|fn main() { + LL| 1| assert!(true); + LL| 1| assert!(!false); + LL| 1| assert!(!!true); + LL| 1| assert!(!!!false); + LL| 1|} + diff --git a/tests/coverage/assert_not.rs b/tests/coverage/assert_not.rs new file mode 100644 index 00000000000..95204fcadd1 --- /dev/null +++ b/tests/coverage/assert_not.rs @@ -0,0 +1,11 @@ +// edition: 2021 + +// Regression test for <https://github.com/rust-lang/rust/issues/118904>. +// `assert!(true)` and `assert!(!false)` should have similar coverage spans. + +fn main() { + assert!(true); + assert!(!false); + assert!(!!true); + assert!(!!!false); +} diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map index e4354a1af87..6bdcca40ed6 100644 --- a/tests/coverage/async.cov-map +++ b/tests/coverage/async.cov-map @@ -1,20 +1,20 @@ Function name: async::c -Raw bytes (9): 0x[01, 01, 00, 01, 01, 05, 01, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 25) +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 25) Function name: async::c::{closure#0} -Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 05, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 07, 02, 01, 00, 02] +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 07, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 07, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 5, 25) to (start + 1, 14) +- Code(Counter(0)) at (prev + 7, 25) to (start + 1, 14) - Code(Counter(1)) at (prev + 2, 9) to (start + 0, 10) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c0 - c1) @@ -22,136 +22,84 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: async::d -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0d, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 20) Function name: async::d::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0d, 14, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 13, 20) to (start + 0, 25) +- Code(Counter(0)) at (prev + 15, 20) to (start + 0, 25) Function name: async::e (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 15, 1) to (start + 0, 20) +- Code(Zero) at (prev + 17, 1) to (start + 0, 20) Function name: async::e::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 14, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 15, 20) to (start + 0, 25) - -Function name: async::executor::block_on::<core::pin::Pin<&mut async::i::{closure#0}>> -Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 6e, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 3 -- expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Counter(1) -- expression 2 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 110, 5) to (start + 10, 54) -- Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35) - = ((c0 + c1) - c1) -- Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73) - = (c0 + c1) -- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26) - = ((c0 + c1) - c1) -- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) - = ((c0 + c1) - c1) - -Function name: async::executor::block_on::VTABLE::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 72, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 114, 17) to (start + 0, 49) - -Function name: async::executor::block_on::VTABLE::{closure#1} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 73, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 115, 17) to (start + 0, 49) - -Function name: async::executor::block_on::VTABLE::{closure#2} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 74, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 116, 17) to (start + 0, 49) - -Function name: async::executor::block_on::VTABLE::{closure#3} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 75, 11, 00, 13] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 117, 17) to (start + 0, 19) +- Code(Zero) at (prev + 17, 20) to (start + 0, 25) Function name: async::f -Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 20) Function name: async::f::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 14, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 17, 20) to (start + 0, 25) +- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 25) Function name: async::foo (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 01, 00, 1e] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 1e] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 19, 1) to (start + 0, 30) +- Code(Zero) at (prev + 21, 1) to (start + 0, 30) Function name: async::foo::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 1e, 00, 2d] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 1e, 00, 2d] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 19, 30) to (start + 0, 45) +- Code(Zero) at (prev + 21, 30) to (start + 0, 45) Function name: async::g -Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 01, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 23) +- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 23) Function name: async::g::{closure#0} (unused) -Raw bytes (69): 0x[01, 01, 00, 0d, 00, 15, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (69): 0x[01, 01, 00, 0d, 00, 17, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 13 -- Code(Zero) at (prev + 21, 23) to (start + 1, 12) +- Code(Zero) at (prev + 23, 23) to (start + 1, 12) - Code(Zero) at (prev + 2, 9) to (start + 0, 10) - Code(Zero) at (prev + 0, 14) to (start + 0, 17) - Code(Zero) at (prev + 0, 18) to (start + 0, 23) @@ -166,20 +114,20 @@ Number of file 0 mappings: 13 - Code(Zero) at (prev + 2, 1) to (start + 0, 2) Function name: async::h -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 00, 16] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 1f, 01, 00, 16] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 22) +- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 22) Function name: async::h::{closure#0} (unused) -Raw bytes (44): 0x[01, 01, 00, 08, 00, 1d, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (44): 0x[01, 01, 00, 08, 00, 1f, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 8 -- Code(Zero) at (prev + 29, 22) to (start + 3, 12) +- Code(Zero) at (prev + 31, 22) to (start + 3, 12) - Code(Zero) at (prev + 4, 9) to (start + 0, 10) - Code(Zero) at (prev + 0, 14) to (start + 0, 19) - Code(Zero) at (prev + 0, 20) to (start + 0, 25) @@ -189,22 +137,22 @@ Number of file 0 mappings: 8 - Code(Zero) at (prev + 2, 1) to (start + 0, 2) Function name: async::i -Raw bytes (9): 0x[01, 01, 00, 01, 01, 26, 01, 00, 13] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 28, 01, 00, 13] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 38, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 19) Function name: async::i::{closure#0} -Raw bytes (78): 0x[01, 01, 02, 07, 21, 19, 1d, 0e, 01, 26, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02] +Raw bytes (78): 0x[01, 01, 02, 07, 21, 19, 1d, 0e, 01, 28, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(8) - expression 1 operands: lhs = Counter(6), rhs = Counter(7) Number of file 0 mappings: 14 -- Code(Counter(0)) at (prev + 38, 19) to (start + 4, 12) +- Code(Counter(0)) at (prev + 40, 19) to (start + 4, 12) - Code(Counter(3)) at (prev + 5, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18) - Code(Counter(1)) at (prev + 0, 19) to (start + 0, 24) @@ -221,14 +169,14 @@ Number of file 0 mappings: 14 = ((c6 + c7) + c8) Function name: async::j -Raw bytes (53): 0x[01, 01, 02, 07, 0d, 05, 09, 09, 01, 31, 01, 13, 0c, 05, 14, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02] +Raw bytes (53): 0x[01, 01, 02, 07, 0d, 05, 09, 09, 01, 33, 01, 13, 0c, 05, 14, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 49, 1) to (start + 19, 12) +- Code(Counter(0)) at (prev + 51, 1) to (start + 19, 12) - Code(Counter(1)) at (prev + 20, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 27) - Code(Counter(1)) at (prev + 0, 31) to (start + 0, 39) @@ -240,14 +188,14 @@ Number of file 0 mappings: 9 = ((c1 + c2) + c3) Function name: async::j::c -Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 33, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 0a, 0d, 00, 0e, 07, 02, 05, 00, 06] +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 35, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 0a, 0d, 00, 0e, 07, 02, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 51, 5) to (start + 1, 18) +- Code(Counter(0)) at (prev + 53, 5) to (start + 1, 18) - Code(Counter(1)) at (prev + 2, 13) to (start + 0, 14) - Code(Expression(0, Sub)) at (prev + 10, 13) to (start + 0, 14) = (c0 - c1) @@ -255,35 +203,35 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: async::j::d -Raw bytes (9): 0x[01, 01, 00, 01, 01, 42, 05, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 44, 05, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 66, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 68, 5) to (start + 0, 23) Function name: async::j::f -Raw bytes (9): 0x[01, 01, 00, 01, 01, 43, 05, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 45, 05, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 67, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 69, 5) to (start + 0, 23) Function name: async::k (unused) -Raw bytes (29): 0x[01, 01, 00, 05, 00, 4b, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 00, 4d, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 5 -- Code(Zero) at (prev + 75, 1) to (start + 1, 12) +- Code(Zero) at (prev + 77, 1) to (start + 1, 12) - Code(Zero) at (prev + 2, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 2, 1) to (start + 0, 2) Function name: async::l -Raw bytes (37): 0x[01, 01, 04, 01, 07, 05, 09, 0f, 02, 09, 05, 05, 01, 53, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02] +Raw bytes (37): 0x[01, 01, 04, 01, 07, 05, 09, 0f, 02, 09, 05, 05, 01, 55, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 @@ -292,7 +240,7 @@ Number of expressions: 4 - expression 2 operands: lhs = Expression(3, Add), rhs = Expression(0, Sub) - expression 3 operands: lhs = Counter(2), rhs = Counter(1) Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 83, 1) to (start + 1, 12) +- Code(Counter(0)) at (prev + 85, 1) to (start + 1, 12) - Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16) = (c0 - (c1 + c2)) - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16) @@ -301,26 +249,26 @@ Number of file 0 mappings: 5 = ((c2 + c1) + (c0 - (c1 + c2))) Function name: async::m -Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 01, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 5d, 01, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 91, 1) to (start + 0, 25) +- Code(Counter(0)) at (prev + 93, 1) to (start + 0, 25) Function name: async::m::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 5b, 19, 00, 22] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 5d, 19, 00, 22] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 91, 25) to (start + 0, 34) +- Code(Zero) at (prev + 93, 25) to (start + 0, 34) Function name: async::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 5d, 01, 08, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 5f, 01, 08, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 93, 1) to (start + 8, 2) +- Code(Counter(0)) at (prev + 95, 1) to (start + 8, 2) diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage index 07bc16c2d92..015e03d5165 100644 --- a/tests/coverage/async.coverage +++ b/tests/coverage/async.coverage @@ -1,6 +1,8 @@ + LL| |#![feature(coverage_attribute)] + LL| |#![feature(noop_waker)] LL| |#![allow(unused_assignments, dead_code)] - LL| | - LL| |// compile-flags: --edition=2018 -C opt-level=1 + LL| |// edition: 2018 + LL| |// compile-flags: -Copt-level=1 LL| | LL| 1|async fn c(x: u8) -> u8 { LL| 1| if x == 8 { @@ -108,32 +110,21 @@ LL| 1|} LL| | LL| |mod executor { - LL| | use core::{ - LL| | future::Future, - LL| | pin::Pin, - LL| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - LL| | }; - LL| | - LL| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output { - LL| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; - LL| 1| use std::hint::unreachable_unchecked; - LL| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( - LL| 1| |_| unsafe { unreachable_unchecked() }, // clone - ^0 - LL| 1| |_| unsafe { unreachable_unchecked() }, // wake - ^0 - LL| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref - ^0 - LL| 1| |_| (), - LL| 1| ); - LL| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - LL| 1| let mut context = Context::from_waker(&waker); + LL| | use core::future::Future; + LL| | use core::pin::pin; + LL| | use core::task::{Context, Poll, Waker}; + LL| | + LL| | #[coverage(off)] + LL| | pub fn block_on<F: Future>(mut future: F) -> F::Output { + LL| | let mut future = pin!(future); + LL| | let waker = Waker::noop(); + LL| | let mut context = Context::from_waker(&waker); LL| | LL| | loop { - LL| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { - LL| 1| break val; - LL| 0| } + LL| | if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + LL| | break val; + LL| | } LL| | } - LL| 1| } + LL| | } LL| |} diff --git a/tests/coverage/async.rs b/tests/coverage/async.rs index efd9e62d64e..abc9e5f7f64 100644 --- a/tests/coverage/async.rs +++ b/tests/coverage/async.rs @@ -1,6 +1,8 @@ +#![feature(coverage_attribute)] +#![feature(noop_waker)] #![allow(unused_assignments, dead_code)] - -// compile-flags: --edition=2018 -C opt-level=1 +// edition: 2018 +// compile-flags: -Copt-level=1 async fn c(x: u8) -> u8 { if x == 8 { @@ -101,22 +103,14 @@ fn main() { } mod executor { - use core::{ - future::Future, - pin::Pin, - task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - }; + use core::future::Future; + use core::pin::pin; + use core::task::{Context, Poll, Waker}; + #[coverage(off)] pub fn block_on<F: Future>(mut future: F) -> F::Output { - let mut future = unsafe { Pin::new_unchecked(&mut future) }; - use std::hint::unreachable_unchecked; - static VTABLE: RawWakerVTable = RawWakerVTable::new( - |_| unsafe { unreachable_unchecked() }, // clone - |_| unsafe { unreachable_unchecked() }, // wake - |_| unsafe { unreachable_unchecked() }, // wake_by_ref - |_| (), - ); - let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut future = pin!(future); + let waker = Waker::noop(); let mut context = Context::from_waker(&waker); loop { diff --git a/tests/coverage/async2.cov-map b/tests/coverage/async2.cov-map index 23f26ee4e5f..b120e28c464 100644 --- a/tests/coverage/async2.cov-map +++ b/tests/coverage/async2.cov-map @@ -1,20 +1,20 @@ Function name: async2::async_func -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0d, 01, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 23) +- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 23) Function name: async2::async_func::{closure#0} -Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 0b, 17, 03, 09, 05, 03, 0a, 02, 06, 02, 02, 06, 00, 07, 07, 01, 01, 00, 02] +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 0d, 17, 03, 09, 05, 03, 0a, 02, 06, 02, 02, 06, 00, 07, 07, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 11, 23) to (start + 3, 9) +- Code(Counter(0)) at (prev + 13, 23) to (start + 3, 9) - Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7) = (c0 - c1) @@ -22,109 +22,37 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: async2::async_func_just_println -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 24] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 01, 00, 24] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 36) +- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 36) Function name: async2::async_func_just_println::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 24, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 24, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 36) to (start + 2, 2) - -Function name: async2::executor::block_on::<async2::async_func::{closure#0}> -Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 3 -- expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Counter(1) -- expression 2 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 39, 5) to (start + 10, 54) -- Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35) - = ((c0 + c1) - c1) -- Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73) - = (c0 + c1) -- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26) - = ((c0 + c1) - c1) -- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) - = ((c0 + c1) - c1) - -Function name: async2::executor::block_on::<async2::async_func_just_println::{closure#0}> -Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 3 -- expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Counter(1) -- expression 2 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 39, 5) to (start + 10, 54) -- Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35) - = ((c0 + c1) - c1) -- Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73) - = (c0 + c1) -- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26) - = ((c0 + c1) - c1) -- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) - = ((c0 + c1) - c1) - -Function name: async2::executor::block_on::VTABLE::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2b, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 43, 17) to (start + 0, 49) - -Function name: async2::executor::block_on::VTABLE::{closure#1} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 44, 17) to (start + 0, 49) - -Function name: async2::executor::block_on::VTABLE::{closure#2} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2d, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 45, 17) to (start + 0, 49) - -Function name: async2::executor::block_on::VTABLE::{closure#3} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2e, 11, 00, 13] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 46, 17) to (start + 0, 19) +- Code(Counter(0)) at (prev + 21, 36) to (start + 2, 2) Function name: async2::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 07, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 19, 01, 07, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 23, 1) to (start + 7, 2) +- Code(Counter(0)) at (prev + 25, 1) to (start + 7, 2) Function name: async2::non_async_func -Raw bytes (26): 0x[01, 01, 01, 05, 00, 04, 01, 03, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 03, 01, 01, 00, 02] +Raw bytes (26): 0x[01, 01, 01, 05, 00, 04, 01, 05, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 03, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Zero Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 3, 1) to (start + 3, 9) +- Code(Counter(0)) at (prev + 5, 1) to (start + 3, 9) - Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) - Code(Expression(0, Add)) at (prev + 1, 1) to (start + 0, 2) diff --git a/tests/coverage/async2.coverage b/tests/coverage/async2.coverage index fcb0a3aed64..acd83de9493 100644 --- a/tests/coverage/async2.coverage +++ b/tests/coverage/async2.coverage @@ -1,4 +1,6 @@ - LL| |// compile-flags: --edition=2018 + LL| |#![feature(coverage_attribute)] + LL| |#![feature(noop_waker)] + LL| |// edition: 2018 LL| | LL| 1|fn non_async_func() { LL| 1| println!("non_async_func was covered"); @@ -32,73 +34,21 @@ LL| 1|} LL| | LL| |mod executor { - LL| | use core::{ - LL| | future::Future, - LL| | pin::Pin, - LL| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - LL| | }; + LL| | use core::future::Future; + LL| | use core::pin::pin; + LL| | use core::task::{Context, Poll, Waker}; LL| | - LL| 2| pub fn block_on<F: Future>(mut future: F) -> F::Output { - LL| 2| let mut future = unsafe { Pin::new_unchecked(&mut future) }; - LL| 2| use std::hint::unreachable_unchecked; - LL| 2| static VTABLE: RawWakerVTable = RawWakerVTable::new( - LL| 2| |_| unsafe { unreachable_unchecked() }, // clone - ^0 - LL| 2| |_| unsafe { unreachable_unchecked() }, // wake - ^0 - LL| 2| |_| unsafe { unreachable_unchecked() }, // wake_by_ref - ^0 - LL| 2| |_| (), - LL| 2| ); - LL| 2| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - LL| 2| let mut context = Context::from_waker(&waker); + LL| | #[coverage(off)] + LL| | pub fn block_on<F: Future>(mut future: F) -> F::Output { + LL| | let mut future = pin!(future); + LL| | let waker = Waker::noop(); + LL| | let mut context = Context::from_waker(&waker); LL| | LL| | loop { - LL| 2| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { - LL| 2| break val; - LL| 0| } + LL| | if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + LL| | break val; + LL| | } LL| | } - LL| 2| } - ------------------ - | async2::executor::block_on::<async2::async_func::{closure#0}>: - | LL| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output { - | LL| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; - | LL| 1| use std::hint::unreachable_unchecked; - | LL| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( - | LL| 1| |_| unsafe { unreachable_unchecked() }, // clone - | LL| 1| |_| unsafe { unreachable_unchecked() }, // wake - | LL| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref - | LL| 1| |_| (), - | LL| 1| ); - | LL| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - | LL| 1| let mut context = Context::from_waker(&waker); - | LL| | - | LL| | loop { - | LL| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { - | LL| 1| break val; - | LL| 0| } - | LL| | } - | LL| 1| } - ------------------ - | async2::executor::block_on::<async2::async_func_just_println::{closure#0}>: - | LL| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output { - | LL| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; - | LL| 1| use std::hint::unreachable_unchecked; - | LL| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( - | LL| 1| |_| unsafe { unreachable_unchecked() }, // clone - | LL| 1| |_| unsafe { unreachable_unchecked() }, // wake - | LL| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref - | LL| 1| |_| (), - | LL| 1| ); - | LL| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - | LL| 1| let mut context = Context::from_waker(&waker); - | LL| | - | LL| | loop { - | LL| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { - | LL| 1| break val; - | LL| 0| } - | LL| | } - | LL| 1| } - ------------------ + LL| | } LL| |} diff --git a/tests/coverage/async2.rs b/tests/coverage/async2.rs index 2884ff297af..393573f7dc9 100644 --- a/tests/coverage/async2.rs +++ b/tests/coverage/async2.rs @@ -1,4 +1,6 @@ -// compile-flags: --edition=2018 +#![feature(coverage_attribute)] +#![feature(noop_waker)] +// edition: 2018 fn non_async_func() { println!("non_async_func was covered"); @@ -30,22 +32,14 @@ fn main() { } mod executor { - use core::{ - future::Future, - pin::Pin, - task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - }; + use core::future::Future; + use core::pin::pin; + use core::task::{Context, Poll, Waker}; + #[coverage(off)] pub fn block_on<F: Future>(mut future: F) -> F::Output { - let mut future = unsafe { Pin::new_unchecked(&mut future) }; - use std::hint::unreachable_unchecked; - static VTABLE: RawWakerVTable = RawWakerVTable::new( - |_| unsafe { unreachable_unchecked() }, // clone - |_| unsafe { unreachable_unchecked() }, // wake - |_| unsafe { unreachable_unchecked() }, // wake_by_ref - |_| (), - ); - let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut future = pin!(future); + let waker = Waker::noop(); let mut context = Context::from_waker(&waker); loop { diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map index 7f8666948d9..14b1525ca0e 100644 --- a/tests/coverage/closure_macro_async.cov-map +++ b/tests/coverage/closure_macro_async.cov-map @@ -1,28 +1,28 @@ Function name: closure_macro_async::load_configuration_files -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2) +- Code(Counter(0)) at (prev + 30, 1) to (start + 2, 2) Function name: closure_macro_async::test -Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 00, 2b] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 22, 01, 00, 2b] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 43) +- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 43) Function name: closure_macro_async::test::{closure#0} -Raw bytes (43): 0x[01, 01, 02, 01, 05, 05, 02, 07, 01, 21, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 02, 00, 12, 00, 13, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 07, 03, 01, 00, 02] +Raw bytes (43): 0x[01, 01, 02, 01, 05, 05, 02, 07, 01, 22, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 02, 00, 12, 00, 13, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 07, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 33, 43) to (start + 1, 33) +- Code(Counter(0)) at (prev + 34, 43) to (start + 1, 33) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15) = (c0 - c1) - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) @@ -35,10 +35,10 @@ Number of file 0 mappings: 7 = (c1 + (c0 - c1)) Function name: closure_macro_async::test::{closure#0}::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 12, 00, 54] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 24, 12, 00, 54] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 35, 18) to (start + 0, 84) +- Code(Counter(0)) at (prev + 36, 18) to (start + 0, 84) diff --git a/tests/coverage/closure_macro_async.coverage b/tests/coverage/closure_macro_async.coverage index 74247f1bc6f..2c9bd4ac97a 100644 --- a/tests/coverage/closure_macro_async.coverage +++ b/tests/coverage/closure_macro_async.coverage @@ -1,5 +1,6 @@ - LL| |// compile-flags: --edition=2018 LL| |#![feature(coverage_attribute)] + LL| |#![feature(noop_waker)] + LL| |// edition: 2018 LL| | LL| |macro_rules! bail { LL| | ($msg:literal $(,)?) => { @@ -46,27 +47,14 @@ LL| |} LL| | LL| |mod executor { - LL| | use core::{ - LL| | future::Future, - LL| | pin::Pin, - LL| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - LL| | }; + LL| | use core::future::Future; + LL| | use core::pin::pin; + LL| | use core::task::{Context, Poll, Waker}; LL| | LL| | #[coverage(off)] LL| | pub fn block_on<F: Future>(mut future: F) -> F::Output { - LL| | let mut future = unsafe { Pin::new_unchecked(&mut future) }; - LL| | use std::hint::unreachable_unchecked; - LL| | static VTABLE: RawWakerVTable = RawWakerVTable::new( - LL| | #[coverage(off)] - LL| | |_| unsafe { unreachable_unchecked() }, // clone - LL| | #[coverage(off)] - LL| | |_| unsafe { unreachable_unchecked() }, // wake - LL| | #[coverage(off)] - LL| | |_| unsafe { unreachable_unchecked() }, // wake_by_ref - LL| | #[coverage(off)] - LL| | |_| (), - LL| | ); - LL| | let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + LL| | let mut future = pin!(future); + LL| | let waker = Waker::noop(); LL| | let mut context = Context::from_waker(&waker); LL| | LL| | loop { diff --git a/tests/coverage/closure_macro_async.rs b/tests/coverage/closure_macro_async.rs index b4275599e59..a7f0cabb4c2 100644 --- a/tests/coverage/closure_macro_async.rs +++ b/tests/coverage/closure_macro_async.rs @@ -1,5 +1,6 @@ -// compile-flags: --edition=2018 #![feature(coverage_attribute)] +#![feature(noop_waker)] +// edition: 2018 macro_rules! bail { ($msg:literal $(,)?) => { @@ -45,27 +46,14 @@ fn main() { } mod executor { - use core::{ - future::Future, - pin::Pin, - task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - }; + use core::future::Future; + use core::pin::pin; + use core::task::{Context, Poll, Waker}; #[coverage(off)] pub fn block_on<F: Future>(mut future: F) -> F::Output { - let mut future = unsafe { Pin::new_unchecked(&mut future) }; - use std::hint::unreachable_unchecked; - static VTABLE: RawWakerVTable = RawWakerVTable::new( - #[coverage(off)] - |_| unsafe { unreachable_unchecked() }, // clone - #[coverage(off)] - |_| unsafe { unreachable_unchecked() }, // wake - #[coverage(off)] - |_| unsafe { unreachable_unchecked() }, // wake_by_ref - #[coverage(off)] - |_| (), - ); - let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut future = pin!(future); + let waker = Waker::noop(); let mut context = Context::from_waker(&waker); loop { diff --git a/tests/coverage/no_spans_if_not.cov-map b/tests/coverage/no_spans_if_not.cov-map new file mode 100644 index 00000000000..5277267ec1b --- /dev/null +++ b/tests/coverage/no_spans_if_not.cov-map @@ -0,0 +1,8 @@ +Function name: no_spans_if_not::main +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2) + diff --git a/tests/coverage/no_spans_if_not.coverage b/tests/coverage/no_spans_if_not.coverage new file mode 100644 index 00000000000..1b6bbc75a04 --- /dev/null +++ b/tests/coverage/no_spans_if_not.coverage @@ -0,0 +1,30 @@ + LL| |// edition: 2021 + LL| | + LL| |// If the span extractor can't find any relevant spans for a function, + LL| |// but the function contains coverage span-marker statements (e.g. inserted + LL| |// for `if !`), coverage codegen may think that it is instrumented and + LL| |// consequently complain that it has no spans. + LL| |// + LL| |// Regression test for <https://github.com/rust-lang/rust/issues/118850>, + LL| |// "A used function should have had coverage mapping data but did not". + LL| | + LL| 1|fn main() { + LL| 1| affected_function(); + LL| 1|} + LL| | + LL| |macro_rules! macro_that_defines_a_function { + LL| | (fn $name:ident () $body:tt) => { + LL| | fn $name () $body + LL| | } + LL| |} + LL| | + LL| |macro_that_defines_a_function! { + LL| | fn affected_function() { + LL| | if !false { + LL| | () + LL| | } else { + LL| | () + LL| | } + LL| | } + LL| |} + diff --git a/tests/coverage/no_spans_if_not.rs b/tests/coverage/no_spans_if_not.rs new file mode 100644 index 00000000000..2bbdc11cd5e --- /dev/null +++ b/tests/coverage/no_spans_if_not.rs @@ -0,0 +1,29 @@ +// edition: 2021 + +// If the span extractor can't find any relevant spans for a function, +// but the function contains coverage span-marker statements (e.g. inserted +// for `if !`), coverage codegen may think that it is instrumented and +// consequently complain that it has no spans. +// +// Regression test for <https://github.com/rust-lang/rust/issues/118850>, +// "A used function should have had coverage mapping data but did not". + +fn main() { + affected_function(); +} + +macro_rules! macro_that_defines_a_function { + (fn $name:ident () $body:tt) => { + fn $name () $body + } +} + +macro_that_defines_a_function! { + fn affected_function() { + if !false { + () + } else { + () + } + } +} diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff new file mode 100644 index 00000000000..4b1e3379114 --- /dev/null +++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff @@ -0,0 +1,104 @@ +- // MIR for `constant_index_overflow` before GVN ++ // MIR for `constant_index_overflow` after GVN + + fn constant_index_overflow(_1: &[T]) -> () { + debug x => _1; + let mut _0: (); + let _2: usize; + let mut _4: bool; + let mut _5: usize; + let mut _6: usize; + let mut _7: &[T]; + let _8: usize; + let mut _9: usize; + let mut _10: bool; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: T; + scope 1 { + debug a => _2; + let _3: T; + scope 2 { + debug b => _3; + } + } + + bb0: { +- StorageLive(_2); +- _2 = const _ as usize (IntToInt); ++ nop; ++ _2 = const usize::MAX; + StorageLive(_3); + StorageLive(_4); + StorageLive(_5); +- _5 = _2; ++ _5 = const usize::MAX; + StorageLive(_6); + StorageLive(_7); + _7 = &(*_1); + _6 = core::slice::<impl [T]>::len(move _7) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_7); +- _4 = Lt(move _5, move _6); ++ _4 = Lt(const usize::MAX, move _6); + switchInt(move _4) -> [0: bb4, otherwise: bb2]; + } + + bb2: { + StorageDead(_6); + StorageDead(_5); + StorageLive(_8); +- _8 = _2; ++ _8 = const usize::MAX; + _9 = Len((*_1)); +- _10 = Lt(_8, _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable]; ++ _10 = Lt(const usize::MAX, _9); ++ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const usize::MAX) -> [success: bb3, unwind unreachable]; + } + + bb3: { +- _3 = (*_1)[_8]; ++ _3 = (*_1)[_2]; + StorageDead(_8); + goto -> bb6; + } + + bb4: { + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); + _11 = const 0_usize; + _12 = Len((*_1)); +- _13 = Lt(_11, _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind unreachable]; ++ _13 = Lt(const 0_usize, _12); ++ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> [success: bb5, unwind unreachable]; + } + + bb5: { +- _3 = (*_1)[_11]; ++ _3 = (*_1)[0 of 1]; + StorageDead(_11); + goto -> bb6; + } + + bb6: { + StorageDead(_4); + StorageLive(_14); + _14 = _3; + _0 = opaque::<T>(move _14) -> [return: bb7, unwind unreachable]; + } + + bb7: { + StorageDead(_14); + StorageDead(_3); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff new file mode 100644 index 00000000000..8abcd7e9387 --- /dev/null +++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff @@ -0,0 +1,104 @@ +- // MIR for `constant_index_overflow` before GVN ++ // MIR for `constant_index_overflow` after GVN + + fn constant_index_overflow(_1: &[T]) -> () { + debug x => _1; + let mut _0: (); + let _2: usize; + let mut _4: bool; + let mut _5: usize; + let mut _6: usize; + let mut _7: &[T]; + let _8: usize; + let mut _9: usize; + let mut _10: bool; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: T; + scope 1 { + debug a => _2; + let _3: T; + scope 2 { + debug b => _3; + } + } + + bb0: { +- StorageLive(_2); +- _2 = const _ as usize (IntToInt); ++ nop; ++ _2 = const usize::MAX; + StorageLive(_3); + StorageLive(_4); + StorageLive(_5); +- _5 = _2; ++ _5 = const usize::MAX; + StorageLive(_6); + StorageLive(_7); + _7 = &(*_1); + _6 = core::slice::<impl [T]>::len(move _7) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_7); +- _4 = Lt(move _5, move _6); ++ _4 = Lt(const usize::MAX, move _6); + switchInt(move _4) -> [0: bb4, otherwise: bb2]; + } + + bb2: { + StorageDead(_6); + StorageDead(_5); + StorageLive(_8); +- _8 = _2; ++ _8 = const usize::MAX; + _9 = Len((*_1)); +- _10 = Lt(_8, _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue]; ++ _10 = Lt(const usize::MAX, _9); ++ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const usize::MAX) -> [success: bb3, unwind continue]; + } + + bb3: { +- _3 = (*_1)[_8]; ++ _3 = (*_1)[_2]; + StorageDead(_8); + goto -> bb6; + } + + bb4: { + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); + _11 = const 0_usize; + _12 = Len((*_1)); +- _13 = Lt(_11, _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind continue]; ++ _13 = Lt(const 0_usize, _12); ++ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> [success: bb5, unwind continue]; + } + + bb5: { +- _3 = (*_1)[_11]; ++ _3 = (*_1)[0 of 1]; + StorageDead(_11); + goto -> bb6; + } + + bb6: { + StorageDead(_4); + StorageLive(_14); + _14 = _3; + _0 = opaque::<T>(move _14) -> [return: bb7, unwind continue]; + } + + bb7: { + StorageDead(_14); + StorageDead(_3); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 6e082acdbd3..db131f7f97d 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -609,6 +609,22 @@ fn indirect_static() { }) } +/// Verify that having constant index `u64::MAX` does not yield to an overflow in rustc. +fn constant_index_overflow<T: Copy>(x: &[T]) { + // CHECK-LABEL: fn constant_index_overflow( + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + // CHECK: [[a]] = const usize::MAX; + // CHECK-NOT: = (*_1)[{{.*}} of 0]; + // CHECK: [[b]] = (*_1)[[[a]]]; + // CHECK-NOT: = (*_1)[{{.*}} of 0]; + // CHECK: [[b]] = (*_1)[0 of 1]; + // CHECK-NOT: = (*_1)[{{.*}} of 0]; + let a = u64::MAX as usize; + let b = if a < x.len() { x[a] } else { x[0] }; + opaque(b) +} + fn main() { subexpression_elimination(2, 4, 5); wrap_unwrap(5); @@ -627,6 +643,7 @@ fn main() { repeat(); fn_pointers(); indirect_static(); + constant_index_overflow(&[5, 3]); } #[inline(never)] @@ -653,3 +670,4 @@ fn identity<T>(x: T) -> T { // EMIT_MIR gvn.repeat.GVN.diff // EMIT_MIR gvn.fn_pointers.GVN.diff // EMIT_MIR gvn.indirect_static.GVN.diff +// EMIT_MIR gvn.constant_index_overflow.GVN.diff diff --git a/tests/rustdoc-gui/globals.goml b/tests/rustdoc-gui/globals.goml new file mode 100644 index 00000000000..53f96ff086e --- /dev/null +++ b/tests/rustdoc-gui/globals.goml @@ -0,0 +1,24 @@ +// Make sure search stores its data in `window` +// It needs to use a global to avoid racing on search-index.js and search.js +// https://github.com/rust-lang/rust/pull/118961 + +// URL query +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=sa'%3Bda'%3Bds" +wait-for: "#search-tabs" +assert-window-property-false: {"searchIndex": null} +assert-window-property: {"srcIndex": null} + +// Form input +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +write: (".search-input", "Foo") +press-key: 'Enter' +wait-for: "#search-tabs" +assert-window-property-false: {"searchIndex": null} +assert-window-property: {"srcIndex": null} + +// source sidebar +go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" +click: "#src-sidebar-toggle" +wait-for: "#src-sidebar details" +assert-window-property-false: {"srcIndex": null} +assert-window-property: {"searchIndex": null} diff --git a/tests/rustdoc-gui/hide-mobile-topbar.goml b/tests/rustdoc-gui/hide-mobile-topbar.goml new file mode 100644 index 00000000000..46eb8acfe8c --- /dev/null +++ b/tests/rustdoc-gui/hide-mobile-topbar.goml @@ -0,0 +1,20 @@ +// Checks sidebar resizing stays synced with the setting +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +set-window-size: (400, 600) + +// Verify that the "hide" option is unchecked +click: "#settings-menu" +wait-for: "#settings" +assert-css: ("#settings", {"display": "block"}) +assert-property: ("#hide-sidebar", {"checked": "false"}) +assert-css: (".mobile-topbar", {"display": "flex"}) + +// Toggle it +click: "#hide-sidebar" +assert-property: ("#hide-sidebar", {"checked": "true"}) +assert-css: (".mobile-topbar", {"display": "none"}) + +// Toggle it again +click: "#hide-sidebar" +assert-property: ("#hide-sidebar", {"checked": "false"}) +assert-css: (".mobile-topbar", {"display": "flex"}) diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml index 0789d785f58..d88ebfb40d7 100644 --- a/tests/rustdoc-gui/links-color.goml +++ b/tests/rustdoc-gui/links-color.goml @@ -26,12 +26,12 @@ define-function: ( assert-css: (".item-table .keyword", {"color": |keyword|}, ALL) // Checking sidebar elements. assert-css: ( - ".sidebar-elems a:not(.current)", + ".sidebar-elems li:not(.current) a", {"color": |sidebar|, "background-color": "rgba(0, 0, 0, 0)", "font-weight": "400"}, ALL, ) assert-css: ( - ".sidebar-elems a.current", + ".sidebar-elems li.current a", { "color": |sidebar_current|, "background-color": |sidebar_current_background|, diff --git a/tests/rustdoc-gui/sidebar-links-color.goml b/tests/rustdoc-gui/sidebar-links-color.goml index 079d582a567..774fbcac1e2 100644 --- a/tests/rustdoc-gui/sidebar-links-color.goml +++ b/tests/rustdoc-gui/sidebar-links-color.goml @@ -17,10 +17,10 @@ define-function: ( reload: // Struct assert-css: ( - ".sidebar .block.struct a:not(.current)", + ".sidebar .block.struct li:not(.current) a", {"color": |struct|, "background-color": "rgba(0, 0, 0, 0)"}, ) - move-cursor-to: ".sidebar .block.struct a:not(.current)" + move-cursor-to: ".sidebar .block.struct li:not(.current) a" assert-css: ( ".sidebar .block.struct a:hover", {"color": |struct_hover|, "background-color": |struct_hover_background|}, diff --git a/tests/rustdoc-gui/sidebar-resize-setting.goml b/tests/rustdoc-gui/sidebar-resize-setting.goml new file mode 100644 index 00000000000..2fdb2faa864 --- /dev/null +++ b/tests/rustdoc-gui/sidebar-resize-setting.goml @@ -0,0 +1,23 @@ +// Checks sidebar resizing stays synced with the setting +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +assert-property: (".sidebar", {"clientWidth": "200"}) +show-text: true + +// Verify that the "hide" option is unchecked +click: "#settings-menu" +wait-for: "#settings" +assert-css: ("#settings", {"display": "block"}) +assert-property: ("#hide-sidebar", {"checked": "false"}) +press-key: "Escape" +wait-for-css: ("#settings", {"display": "none"}) + +drag-and-drop: ((205, 100), (5, 100)) +assert-css: (".sidebar", {"display": "none"}) + +// Verify that the "hide" option is checked +focus: "#settings-menu a" +press-key: "Enter" +wait-for-css: ("#settings", {"display": "block"}) +assert-property: ("#hide-sidebar", {"checked": "true"}) +click: "#hide-sidebar" +wait-for-css: (".sidebar", {"display": "block"}) diff --git a/tests/rustdoc-gui/sidebar-resize-window.goml b/tests/rustdoc-gui/sidebar-resize-window.goml new file mode 100644 index 00000000000..fb6baafda71 --- /dev/null +++ b/tests/rustdoc-gui/sidebar-resize-window.goml @@ -0,0 +1,37 @@ +// Checks sidebar resizing +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +set-window-size: (1280, 600) +wait-for-property: (".sidebar", {"clientWidth": 200}, [NEAR]) + +// resize past maximum (don't grow past 500) +drag-and-drop: ((205, 100), (600, 100)) +wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR]) + +// make the window small enough that the sidebar has to shrink +set-window-size: (750, 600) +wait-for-property: (".sidebar", {"clientWidth": 350}, [NEAR]) + +// grow the window again to make the sidebar bigger +set-window-size: (1280, 600) +wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR]) + +// make the window small enough that the sidebar has to shrink +set-window-size: (750, 600) +wait-for-property: (".sidebar", {"clientWidth": 350}, [NEAR]) +assert-local-storage: {"rustdoc-desktop-sidebar-width": "350"} +set-window-size: (400, 600) +wait-for-css: (".sidebar", {"display": "block", "left": "-1000px"}) +assert-local-storage: {"rustdoc-desktop-sidebar-width": "350"} + +// grow the window again to make the sidebar bigger +set-window-size: (1280, 600) +wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR]) + +// shrink back down again, then reload the page +// the "desired size" is a bit of remembered implicit state, +// and rustdoc tries to minimize things like this +set-window-size: (800, 600) +wait-for-property: (".sidebar", {"clientWidth": 400}, [NEAR]) +reload: +set-window-size: (1280, 600) +wait-for-property: (".sidebar", {"clientWidth": 400}, [NEAR]) diff --git a/tests/rustdoc-gui/sidebar-resize.goml b/tests/rustdoc-gui/sidebar-resize.goml new file mode 100644 index 00000000000..543d5d390c7 --- /dev/null +++ b/tests/rustdoc-gui/sidebar-resize.goml @@ -0,0 +1,28 @@ +// Checks sidebar resizing +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +assert-property: (".sidebar", {"clientWidth": "200"}) +show-text: true +// normal resizing +drag-and-drop: ((205, 100), (185, 100)) +assert-property: (".sidebar", {"clientWidth": "182"}) +// resize past maximum (don't grow past 500) +drag-and-drop: ((185, 100), (600, 100)) +assert-property: (".sidebar", {"clientWidth": "500"}) +// resize past minimum (hide sidebar) +drag-and-drop: ((501, 100), (5, 100)) +assert-property: (".sidebar", {"clientWidth": "0"}) +assert-css: (".sidebar", {"display": "none"}) +assert-local-storage: {"rustdoc-hide-sidebar": "true"} +set-local-storage: {"rustdoc-hide-sidebar": "false"} + +// Now same thing, but for source code +go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" +assert-property: (".sidebar", {"clientWidth": "49"}) +drag-and-drop: ((52, 100), (185, 100)) +assert-property: (".sidebar", {"clientWidth": "181"}) +drag-and-drop: ((185, 100), (600, 100)) +assert-property: (".sidebar", {"clientWidth": "499"}) +drag-and-drop: ((500, 100), (5, 100)) +// instead of hiding the sidebar entirely, this +// will switch to the toggle mode +assert-property: (".sidebar", {"clientWidth": "49"}) diff --git a/tests/rustdoc-gui/sidebar-source-code.goml b/tests/rustdoc-gui/sidebar-source-code.goml index 0d72e670cf4..9fc1409e86f 100644 --- a/tests/rustdoc-gui/sidebar-source-code.goml +++ b/tests/rustdoc-gui/sidebar-source-code.goml @@ -48,6 +48,7 @@ call-function: ( // Next, desktop mode layout. set-window-size: (1100, 800) +wait-for: "#src-sidebar-toggle" // We check that the sidebar isn't expanded and has the expected width. assert-css: ("nav.sidebar", {"width": "50px"}) // We now click on the button to expand the sidebar. @@ -58,7 +59,7 @@ assert-css: (".src-sidebar-expanded nav.sidebar a", {"font-size": "14px"}) // We collapse the sidebar. click: (10, 10) // We ensure that the class has been removed. -wait-for: "html:not(.expanded)" +wait-for: "html:not(.src-sidebar-expanded)" assert: "nav.sidebar" // Checking that only the path to the current file is "open". diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml index eff66d803d2..82b4f2e9429 100644 --- a/tests/rustdoc-gui/sidebar.goml +++ b/tests/rustdoc-gui/sidebar.goml @@ -57,7 +57,7 @@ assert-count: (".sidebar h2", 1) assert-text: ("#all-types", "All Items") assert-css: ("#all-types", {"color": "#356da4"}) // We check that we have the crates list and that the "current" on is "test_docs". -assert-text: (".sidebar-elems ul.crate > li > a.current", "test_docs") +assert-text: (".sidebar-elems ul.crate > li.current > a", "test_docs") // And we're also supposed to have the list of items in the current module. assert-text: (".sidebar-elems section ul > li:nth-child(1)", "Re-exports") assert-text: (".sidebar-elems section ul > li:nth-child(2)", "Modules") @@ -98,7 +98,7 @@ assert-property: (".sidebar", {"clientWidth": "200"}) assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2") assert-count: (".sidebar .location", 0) // We check that we have the crates list and that the "current" on is now "lib2". -assert-text: (".sidebar-elems ul.crate > li > a.current", "lib2") +assert-text: (".sidebar-elems ul.crate > li.current > a", "lib2") // We now go to the "foobar" function page. assert-text: (".sidebar-elems > section ul.block > li:nth-child(1)", "Modules") assert-text: (".sidebar-elems > section ul.block > li:nth-child(2)", "Structs") diff --git a/tests/rustdoc-gui/src/theme_css/custom-theme.css b/tests/rustdoc-gui/src/theme_css/custom-theme.css index 260ef87f6ea..49227d9ea11 100644 --- a/tests/rustdoc-gui/src/theme_css/custom-theme.css +++ b/tests/rustdoc-gui/src/theme_css/custom-theme.css @@ -96,4 +96,6 @@ --scrape-example-help-hover-color: #000; --scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1); --scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0); + --sidebar-resizer-hover: hsl(207, 90%, 66%); + --sidebar-resizer-active: hsl(207, 90%, 54%); } diff --git a/tests/rustdoc-js/substring.js b/tests/rustdoc-js/substring.js index 96efa992bb6..b791ac4bfd1 100644 --- a/tests/rustdoc-js/substring.js +++ b/tests/rustdoc-js/substring.js @@ -1,7 +1,15 @@ -const EXPECTED = { - 'query': 'waker_from', - 'others': [ - { 'path': 'substring::SuperWaker', 'name': 'local_waker_from_nonlocal' }, - { 'path': 'substring::SuperWakerTask', 'name': 'local_waker_from_nonlocal' }, - ], -}; +const EXPECTED = [ + { + 'query': 'waker_from', + 'others': [ + { 'path': 'substring::SuperWaker', 'name': 'local_waker_from_nonlocal' }, + { 'path': 'substring::SuperWakerTask', 'name': 'local_waker_from_nonlocal' }, + ], + }, + { + 'query': 'my', + 'others': [ + { 'path': 'substring', 'name': 'm_y_substringmatching' }, + ], + }, +]; diff --git a/tests/rustdoc-js/substring.rs b/tests/rustdoc-js/substring.rs index e729c722c79..ea88894d03d 100644 --- a/tests/rustdoc-js/substring.rs +++ b/tests/rustdoc-js/substring.rs @@ -19,3 +19,5 @@ impl SuperWakerTask { pub fn waker_non_local() {} pub fn from_non_local() {} } + +pub fn m_y_substringmatching() {} diff --git a/tests/rustdoc/reexport-cfg.rs b/tests/rustdoc/reexport-cfg.rs new file mode 100644 index 00000000000..a6179fad873 --- /dev/null +++ b/tests/rustdoc/reexport-cfg.rs @@ -0,0 +1,30 @@ +// This test ensures that only the re-export `cfg` will be displayed and that it won't +// include `cfg`s from the previous chained items. + +#![crate_name = "foo"] +#![feature(doc_auto_cfg, doc_cfg)] + +mod foo { + #[cfg(not(feature = "foo"))] + pub struct Bar; + + #[doc(cfg(not(feature = "bar")))] + pub struct Bar2; +} + +// @has 'foo/index.html' +// @has - '//*[@class="item-name"]' 'BabarNon-lie' +#[cfg(not(feature = "lie"))] +pub use crate::foo::Bar as Babar; + +// @has - '//*[@class="item-name"]' 'Babar2Non-cake' +#[doc(cfg(not(feature = "cake")))] +pub use crate::foo::Bar2 as Babar2; + +// @has - '//*[@class="item-table"]/li' 'pub use crate::Babar as Elephant;Non-robot' +#[cfg(not(feature = "robot"))] +pub use crate::Babar as Elephant; + +// @has - '//*[@class="item-table"]/li' 'pub use crate::Babar2 as Elephant2;Non-cat' +#[doc(cfg(not(feature = "cat")))] +pub use crate::Babar2 as Elephant2; diff --git a/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs b/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs index a79d05904e3..c81c654a20e 100644 --- a/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs +++ b/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs @@ -27,7 +27,7 @@ pub mod mod1 { pub mod mod2 { // @has - '//code' 'pub use tag::Portability;' // @!has - '//span' 'Deprecated' - // @has - '//span' 'sync' + // @!has - '//span' 'sync' pub use tag::Portability; } @@ -35,7 +35,7 @@ pub mod mod2 { pub mod mod3 { // @has - '//code' 'pub use tag::Both;' // @has - '//span' 'Deprecated' - // @has - '//span' 'sync' + // @!has - '//span' 'sync' pub use tag::Both; } diff --git a/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs b/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs index ff8a910f59f..423838e251b 100644 --- a/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs +++ b/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs @@ -35,7 +35,7 @@ pub mod mod1 { pub mod mod2 { // @has - '//code' 'pub use tag::Portability;' // @!has - '//span' 'Experimental' - // @has - '//span' 'sync' + // @!has - '//span' 'sync' #[stable(feature = "rust1", since = "1.0.0")] pub use tag::Portability; } @@ -45,7 +45,7 @@ pub mod mod2 { pub mod mod3 { // @has - '//code' 'pub use tag::Both;' // @has - '//span' 'Experimental' - // @has - '//span' 'sync' + // @!has - '//span' 'sync' #[stable(feature = "rust1", since = "1.0.0")] pub use tag::Both; } diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs index 7f545ead152..4b006151c64 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.rs +++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs @@ -13,7 +13,7 @@ extern crate rustc_session; extern crate rustc_span; use rustc_errors::{ - AddToDiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, Handler, + AddToDiagnostic, DiagCtxt, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic, SubdiagnosticMessage, }; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -38,8 +38,8 @@ struct Note { pub struct UntranslatableInIntoDiagnostic; impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for UntranslatableInIntoDiagnostic { - fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - handler.struct_err("untranslatable diagnostic") + fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + dcx.struct_err("untranslatable diagnostic") //~^ ERROR diagnostics should be created using translatable messages } } @@ -47,8 +47,8 @@ impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for UntranslatableInIntoDiagnostic pub struct TranslatableInIntoDiagnostic; impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for TranslatableInIntoDiagnostic { - fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - handler.struct_err(crate::fluent_generated::no_crate_example) + fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + dcx.struct_err(crate::fluent_generated::no_crate_example) } } @@ -75,11 +75,11 @@ impl AddToDiagnostic for TranslatableInAddToDiagnostic { } } -pub fn make_diagnostics<'a>(handler: &'a Handler) { - let _diag = handler.struct_err(crate::fluent_generated::no_crate_example); +pub fn make_diagnostics<'a>(dcx: &'a DiagCtxt) { + let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example); //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - let _diag = handler.struct_err("untranslatable diagnostic"); + let _diag = dcx.struct_err("untranslatable diagnostic"); //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls //~^^ ERROR diagnostics should be created using translatable messages } @@ -87,6 +87,6 @@ pub fn make_diagnostics<'a>(handler: &'a Handler) { // Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted. #[rustc_lint_diagnostics] -pub fn skipped_because_of_annotation<'a>(handler: &'a Handler) { - let _diag = handler.struct_err("untranslatable diagnostic"); // okay! +pub fn skipped_because_of_annotation<'a>(dcx: &'a DiagCtxt) { + let _diag = dcx.struct_err("untranslatable diagnostic"); // okay! } diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr index 8e0535e021b..d18db3cbbd3 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr @@ -1,8 +1,8 @@ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:42:17 + --> $DIR/diagnostics.rs:42:13 | -LL | handler.struct_err("untranslatable diagnostic") - | ^^^^^^^^^^ +LL | dcx.struct_err("untranslatable diagnostic") + | ^^^^^^^^^^ | note: the lint level is defined here --> $DIR/diagnostics.rs:6:9 @@ -17,10 +17,10 @@ LL | diag.note("untranslatable diagnostic"); | ^^^^ error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - --> $DIR/diagnostics.rs:79:25 + --> $DIR/diagnostics.rs:79:21 | -LL | let _diag = handler.struct_err(crate::fluent_generated::no_crate_example); - | ^^^^^^^^^^ +LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example); + | ^^^^^^^^^^ | note: the lint level is defined here --> $DIR/diagnostics.rs:7:9 @@ -29,16 +29,16 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - --> $DIR/diagnostics.rs:82:25 + --> $DIR/diagnostics.rs:82:21 | -LL | let _diag = handler.struct_err("untranslatable diagnostic"); - | ^^^^^^^^^^ +LL | let _diag = dcx.struct_err("untranslatable diagnostic"); + | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:82:25 + --> $DIR/diagnostics.rs:82:21 | -LL | let _diag = handler.struct_err("untranslatable diagnostic"); - | ^^^^^^^^^^ +LL | let _diag = dcx.struct_err("untranslatable diagnostic"); + | ^^^^^^^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui-fulldeps/stable-mir/check_allocation.rs b/tests/ui-fulldeps/stable-mir/check_allocation.rs index 88c41537d9f..8554630e9c9 100644 --- a/tests/ui-fulldeps/stable-mir/check_allocation.rs +++ b/tests/ui-fulldeps/stable-mir/check_allocation.rs @@ -33,6 +33,7 @@ use std::ascii::Char; use std::assert_matches::assert_matches; use std::cmp::{max, min}; use std::collections::HashMap; +use std::ffi::CStr; use std::io::Write; use std::ops::ControlFlow; @@ -45,6 +46,7 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { check_foo(*get_item(&items, (ItemKind::Static, "FOO")).unwrap()); check_bar(*get_item(&items, (ItemKind::Static, "BAR")).unwrap()); check_len(*get_item(&items, (ItemKind::Static, "LEN")).unwrap()); + check_cstr(*get_item(&items, (ItemKind::Static, "C_STR")).unwrap()); check_other_consts(*get_item(&items, (ItemKind::Fn, "other_consts")).unwrap()); check_type_id(*get_item(&items, (ItemKind::Fn, "check_type_id")).unwrap()); ControlFlow::Continue(()) @@ -86,6 +88,24 @@ fn check_bar(item: CrateItem) { assert_eq!(std::str::from_utf8(&allocation.raw_bytes().unwrap()), Ok("Bar")); } +/// Check the allocation data for static `C_STR`. +/// +/// ```no_run +/// static C_STR: &core::ffi::cstr = c"cstr"; +/// ``` +fn check_cstr(item: CrateItem) { + let def = StaticDef::try_from(item).unwrap(); + let alloc = def.eval_initializer().unwrap(); + assert_eq!(alloc.provenance.ptrs.len(), 1); + let deref = item.ty().kind().builtin_deref(true).unwrap(); + assert!(deref.ty.kind().is_cstr(), "Expected CStr, but got: {:?}", item.ty()); + + let alloc_id_0 = alloc.provenance.ptrs[0].1.0; + let GlobalAlloc::Memory(allocation) = GlobalAlloc::from(alloc_id_0) else { unreachable!() }; + assert_eq!(allocation.bytes.len(), 5); + assert_eq!(CStr::from_bytes_until_nul(&allocation.raw_bytes().unwrap()), Ok(c"cstr")); +} + /// Check the allocation data for constants used in `other_consts` function. fn check_other_consts(item: CrateItem) { // Instance body will force constant evaluation. @@ -206,6 +226,7 @@ fn main() { generate_input(&path).unwrap(); let args = vec![ "rustc".to_string(), + "--edition=2021".to_string(), "--crate-name".to_string(), CRATE_NAME.to_string(), path.to_string(), @@ -224,6 +245,7 @@ fn generate_input(path: &str) -> std::io::Result<()> { static LEN: usize = 2; static FOO: [&str; 2] = ["hi", "there"]; static BAR: &str = "Bar"; + static C_STR: &std::ffi::CStr = c"cstr"; const NULL: *const u8 = std::ptr::null(); const TUPLE: (u32, u32) = (10, u32::MAX); diff --git a/tests/ui-fulldeps/stable-mir/check_defs.rs b/tests/ui-fulldeps/stable-mir/check_defs.rs index d311be5982d..ad667511332 100644 --- a/tests/ui-fulldeps/stable-mir/check_defs.rs +++ b/tests/ui-fulldeps/stable-mir/check_defs.rs @@ -69,7 +69,7 @@ fn extract_elem_ty(ty: Ty) -> Ty { /// Check signature and type of `Vec::<u8>::new` and its generic version. fn test_vec_new(instance: mir::mono::Instance) { - let sig = instance.fn_sig(); + let sig = instance.ty().kind().fn_sig().unwrap().skip_binder(); assert_matches!(sig.inputs(), &[]); let elem_ty = extract_elem_ty(sig.output()); assert_matches!(elem_ty.kind(), TyKind::RigidTy(RigidTy::Uint(UintTy::U8))); diff --git a/tests/ui/closures/2229_closure_analysis/issue-118144.rs b/tests/ui/closures/2229_closure_analysis/issue-118144.rs new file mode 100644 index 00000000000..3e5d9f9739a --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/issue-118144.rs @@ -0,0 +1,16 @@ +// Regression test for ICE #118144 + +struct V(i32); + +fn func(func_arg: &mut V) { + || { + // Declaring `x` separately instead of using + // a destructuring binding like `let V(x) = ...` + // becaue only `V(x) = ...` triggers the ICE + let x; + V(x) = func_arg; //~ ERROR: mismatched types + func_arg.0 = 0; + }; +} + +fn main() {} diff --git a/tests/ui/closures/2229_closure_analysis/issue-118144.stderr b/tests/ui/closures/2229_closure_analysis/issue-118144.stderr new file mode 100644 index 00000000000..85cb5adc07e --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/issue-118144.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/issue-118144.rs:11:9 + | +LL | V(x) = func_arg; + | ^^^^ -------- this expression has type `&mut V` + | | + | expected `&mut V`, found `V` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index 69f541cba05..f64e8b39798 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr @@ -1,11 +1,11 @@ -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:31:1 | diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index c2c951af0db..8e852ec796e 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr @@ -1,11 +1,11 @@ -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` --> $DIR/associated-type.rs:31:1 | diff --git a/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs b/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs new file mode 100644 index 00000000000..aac74d3eacb --- /dev/null +++ b/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs @@ -0,0 +1,17 @@ +// compile-flags: --edition 2024 -Zunstable-options +// check-pass + +#![feature(async_iterator, gen_blocks, noop_waker)] + +use std::{async_iter::AsyncIterator, pin::pin, task::{Context, Waker}}; + +async gen fn gen_fn() -> &'static str { + yield "hello" +} + +pub fn main() { + let async_iterator = pin!(gen_fn()); + let waker = Waker::noop(); + let ctx = &mut Context::from_waker(&waker); + async_iterator.poll_next(ctx); +} diff --git a/tests/ui/coroutine/return-types-diverge.rs b/tests/ui/coroutine/return-types-diverge.rs new file mode 100644 index 00000000000..5f21c8cbf34 --- /dev/null +++ b/tests/ui/coroutine/return-types-diverge.rs @@ -0,0 +1,20 @@ +// compile-flags: --edition 2024 -Zunstable-options +// check-pass + +#![feature(gen_blocks)] + +fn diverge() -> ! { loop {} } + +async gen fn async_gen_fn() -> i32 { diverge() } + +gen fn gen_fn() -> i32 { diverge() } + +fn async_gen_block() { + async gen { yield (); diverge() }; +} + +fn gen_block() { + gen { yield (); diverge() }; +} + +fn main() {} diff --git a/tests/ui/coroutine/return-types.rs b/tests/ui/coroutine/return-types.rs new file mode 100644 index 00000000000..3543d6293f7 --- /dev/null +++ b/tests/ui/coroutine/return-types.rs @@ -0,0 +1,21 @@ +// compile-flags: --edition 2024 -Zunstable-options + +#![feature(gen_blocks)] + +async gen fn async_gen_fn() -> i32 { 0 } +//~^ ERROR mismatched types + +gen fn gen_fn() -> i32 { 0 } +//~^ ERROR mismatched types + +fn async_gen_block() { + async gen { yield (); 1 }; + //~^ ERROR mismatched types +} + +fn gen_block() { + gen { yield (); 1 }; + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/coroutine/return-types.stderr b/tests/ui/coroutine/return-types.stderr new file mode 100644 index 00000000000..7be96e538d9 --- /dev/null +++ b/tests/ui/coroutine/return-types.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/return-types.rs:5:38 + | +LL | async gen fn async_gen_fn() -> i32 { 0 } + | --- ^ expected `()`, found integer + | | + | expected `()` because of return type + +error[E0308]: mismatched types + --> $DIR/return-types.rs:8:26 + | +LL | gen fn gen_fn() -> i32 { 0 } + | --- ^ expected `()`, found integer + | | + | expected `()` because of return type + +error[E0308]: mismatched types + --> $DIR/return-types.rs:12:27 + | +LL | async gen { yield (); 1 }; + | ^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/return-types.rs:17:21 + | +LL | gen { yield (); 1 }; + | ^ expected `()`, found integer + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/duplicate_entry_error.stderr b/tests/ui/duplicate_entry_error.stderr index 592640a884c..3b5998df353 100644 --- a/tests/ui/duplicate_entry_error.stderr +++ b/tests/ui/duplicate_entry_error.stderr @@ -1,8 +1,11 @@ error[E0152]: found duplicate lang item `panic_impl` --> $DIR/duplicate_entry_error.rs:11:1 | -LL | fn panic_impl(info: &PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic_impl(info: &PanicInfo) -> ! { +LL | | +LL | | loop {} +LL | | } + | |_^ | = note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on) = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib diff --git a/tests/ui/entry-point/issue-118772.rs b/tests/ui/entry-point/issue-118772.rs new file mode 100644 index 00000000000..1a4173e1252 --- /dev/null +++ b/tests/ui/entry-point/issue-118772.rs @@ -0,0 +1,3 @@ +fn main(_: &i32) { //~ ERROR `main` function has wrong type + println!("Hello, world!"); +} diff --git a/tests/ui/entry-point/issue-118772.stderr b/tests/ui/entry-point/issue-118772.stderr new file mode 100644 index 00000000000..cc33427f59d --- /dev/null +++ b/tests/ui/entry-point/issue-118772.stderr @@ -0,0 +1,12 @@ +error[E0580]: `main` function has wrong type + --> $DIR/issue-118772.rs:1:1 + | +LL | fn main(_: &i32) { + | ^^^^^^^^^^^^^^^^ incorrect number of function parameters + | + = note: expected signature `fn()` + found signature `for<'a> fn(&'a i32)` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0580`. diff --git a/tests/ui/error-codes/E0152.stderr b/tests/ui/error-codes/E0152.stderr index 816ba2d569b..dbea7e6d27f 100644 --- a/tests/ui/error-codes/E0152.stderr +++ b/tests/ui/error-codes/E0152.stderr @@ -2,7 +2,7 @@ error[E0152]: found duplicate lang item `owned_box` --> $DIR/E0152.rs:5:1 | LL | struct Foo<T>(T); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `alloc` (which `std` depends on) = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib diff --git a/tests/ui/error-codes/E0264.stderr b/tests/ui/error-codes/E0264.stderr index 14a4ffbe316..3503fb229e4 100644 --- a/tests/ui/error-codes/E0264.stderr +++ b/tests/ui/error-codes/E0264.stderr @@ -2,7 +2,7 @@ error[E0264]: unknown external lang item: `cake` --> $DIR/E0264.rs:5:5 | LL | fn cake(); - | ^^^^^^^^^ + | ^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/hygiene/cross-crate-define-and-use.rs b/tests/ui/hygiene/cross-crate-define-and-use.rs index 94f1adff626..62b1820235c 100644 --- a/tests/ui/hygiene/cross-crate-define-and-use.rs +++ b/tests/ui/hygiene/cross-crate-define-and-use.rs @@ -6,7 +6,6 @@ // check-pass // aux-build:use_by_macro.rs -#![feature(type_name_of_val)] extern crate use_by_macro; use use_by_macro::*; diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs index 6ccbb5bb266..280856805e5 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs @@ -1,5 +1,3 @@ -#![deny(implied_bounds_entailment)] - trait Project { type Ty; } @@ -11,8 +9,7 @@ trait Trait { } impl Trait for () { fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { - //~^ ERROR impl method assumes more implied bounds than the corresponding trait method - //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements s } } diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr index 86b12cf8fa2..c8d1614a7f3 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr @@ -1,31 +1,28 @@ -error: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31 +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5 | LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> -note: the lint level is defined here - --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9 - | -LL | #![deny(implied_bounds_entailment)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -Future incompatibility report: Future breakage diagnostic: -error: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31 +note: first, the lifetime cannot outlive the lifetime `'s` as defined here... + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:12 | LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()` + | ^^ +note: ...so that the method type is compatible with trait + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> -note: the lint level is defined here - --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9 +LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `fn(&'s _, ()) -> &'static _` + found `fn(&_, ()) -> &'static _` + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that the reference type `&'static &()` does not outlive the data it points at + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5 | -LL | #![deny(implied_bounds_entailment)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0495`. diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs index d097bc16a22..7f3817b326a 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs @@ -1,5 +1,3 @@ -#![deny(implied_bounds_entailment)] - use std::cell::RefCell; pub struct MessageListeners<'a> { @@ -12,8 +10,7 @@ pub trait MessageListenersInterface { impl<'a> MessageListenersInterface for MessageListeners<'a> { fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { - //~^ ERROR impl method assumes more implied bounds than the corresponding trait method - //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements self } } diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr index a89645c128b..6a412eb5e4b 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr @@ -1,31 +1,32 @@ -error: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/impl-implied-bounds-compatibility.rs:14:35 +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements + --> $DIR/impl-implied-bounds-compatibility.rs:12:5 | LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> -note: the lint level is defined here - --> $DIR/impl-implied-bounds-compatibility.rs:1:9 +note: first, the lifetime cannot outlive the lifetime `'c` as defined here... + --> $DIR/impl-implied-bounds-compatibility.rs:12:5 | -LL | #![deny(implied_bounds_entailment)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -Future incompatibility report: Future breakage diagnostic: -error: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/impl-implied-bounds-compatibility.rs:14:35 +LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...so that the method type is compatible with trait + --> $DIR/impl-implied-bounds-compatibility.rs:12:5 | LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `fn(&'c MessageListeners<'_>) -> &'c MessageListeners<'c>` + found `fn(&MessageListeners<'_>) -> &'a MessageListeners<'_>` +note: but, the lifetime must be valid for the lifetime `'a` as defined here... + --> $DIR/impl-implied-bounds-compatibility.rs:11:6 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> -note: the lint level is defined here - --> $DIR/impl-implied-bounds-compatibility.rs:1:9 +LL | impl<'a> MessageListenersInterface for MessageListeners<'a> { + | ^^ +note: ...so that the reference type `&'a MessageListeners<'_>` does not outlive the data it points at + --> $DIR/impl-implied-bounds-compatibility.rs:12:5 | -LL | #![deny(implied_bounds_entailment)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0495`. diff --git a/tests/ui/intrinsics/const-eval-select-bad.stderr b/tests/ui/intrinsics/const-eval-select-bad.stderr index bf91dc72cc1..85e22178c4a 100644 --- a/tests/ui/intrinsics/const-eval-select-bad.stderr +++ b/tests/ui/intrinsics/const-eval-select-bad.stderr @@ -16,20 +16,24 @@ LL | const_eval_select((), || {}, || {}); = note: expected a function item, found {closure@$DIR/const-eval-select-bad.rs:7:34: 7:36} = help: consult the documentation on `const_eval_select` for more information -error: this argument must be a function item +error[E0277]: expected a `FnOnce()` closure, found `{integer}` --> $DIR/const-eval-select-bad.rs:10:27 | LL | const_eval_select((), 42, 0xDEADBEEF); - | ^^ + | ----------------- ^^ expected an `FnOnce()` closure, found `{integer}` + | | + | required by a bound introduced by this call | - = note: expected a function item, found {integer} - = help: consult the documentation on `const_eval_select` for more information + = help: the trait `FnOnce<()>` is not implemented for `{integer}` + = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `const_eval_select` + --> $SRC_DIR/core/src/intrinsics.rs:LL:COL error[E0277]: expected a `FnOnce()` closure, found `{integer}` - --> $DIR/const-eval-select-bad.rs:10:27 + --> $DIR/const-eval-select-bad.rs:10:31 | LL | const_eval_select((), 42, 0xDEADBEEF); - | ----------------- ^^ expected an `FnOnce()` closure, found `{integer}` + | ----------------- ^^^^^^^^^^ expected an `FnOnce()` closure, found `{integer}` | | | required by a bound introduced by this call | @@ -39,26 +43,22 @@ note: required by a bound in `const_eval_select` --> $SRC_DIR/core/src/intrinsics.rs:LL:COL error: this argument must be a function item - --> $DIR/const-eval-select-bad.rs:10:31 + --> $DIR/const-eval-select-bad.rs:10:27 | LL | const_eval_select((), 42, 0xDEADBEEF); - | ^^^^^^^^^^ + | ^^ | = note: expected a function item, found {integer} = help: consult the documentation on `const_eval_select` for more information -error[E0277]: expected a `FnOnce()` closure, found `{integer}` +error: this argument must be a function item --> $DIR/const-eval-select-bad.rs:10:31 | LL | const_eval_select((), 42, 0xDEADBEEF); - | ----------------- ^^^^^^^^^^ expected an `FnOnce()` closure, found `{integer}` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^ | - = help: the trait `FnOnce<()>` is not implemented for `{integer}` - = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }` -note: required by a bound in `const_eval_select` - --> $SRC_DIR/core/src/intrinsics.rs:LL:COL + = note: expected a function item, found {integer} + = help: consult the documentation on `const_eval_select` for more information error[E0271]: expected `bar` to be a fn item that returns `i32`, but it returns `bool` --> $DIR/const-eval-select-bad.rs:32:34 diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs index 3d33adf6831..21bd7187e15 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.rs +++ b/tests/ui/lang-items/lang-item-generic-requirements.rs @@ -22,6 +22,8 @@ trait MyIndex<'a, T> {} #[lang = "phantom_data"] //~^ ERROR `phantom_data` language item must be applied to a struct with 1 generic argument struct MyPhantomData<T, U>; +//~^ ERROR parameter `T` is never used +//~| ERROR parameter `U` is never used #[lang = "owned_box"] //~^ ERROR `owned_box` language item must be applied to a struct with at least 1 generic argument @@ -40,6 +42,7 @@ fn ice() { let r = 5; let a = 6; r + a; + //~^ ERROR cannot add `{integer}` to `{integer}` // Use drop in place my_ptr_drop(); diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr index 4d349a25f9c..8072e6797e4 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.stderr +++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr @@ -33,7 +33,7 @@ LL | struct MyPhantomData<T, U>; | ------ this struct has 2 generic arguments error[E0718]: `owned_box` language item must be applied to a struct with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:26:1 + --> $DIR/lang-item-generic-requirements.rs:28:1 | LL | #[lang = "owned_box"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | struct Foo; | - this struct has 0 generic arguments error[E0718]: `start` language item must be applied to a function with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:32:1 + --> $DIR/lang-item-generic-requirements.rs:34:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ @@ -50,6 +50,35 @@ LL | LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize { | - this function has 0 generic arguments -error: aborting due to 6 previous errors +error[E0392]: parameter `T` is never used + --> $DIR/lang-item-generic-requirements.rs:24:22 + | +LL | struct MyPhantomData<T, U>; + | ^ unused parameter + | + = help: consider removing `T` or referring to it in a field + = help: if you intended `T` to be a const parameter, use `const T: usize` instead + +error[E0392]: parameter `U` is never used + --> $DIR/lang-item-generic-requirements.rs:24:25 + | +LL | struct MyPhantomData<T, U>; + | ^ unused parameter + | + = help: consider removing `U` or referring to it in a field + = help: if you intended `U` to be a const parameter, use `const U: usize` instead + +error[E0369]: cannot add `{integer}` to `{integer}` + --> $DIR/lang-item-generic-requirements.rs:44:7 + | +LL | r + a; + | - ^ - {integer} + | | + | {integer} + +error: requires `copy` lang_item + +error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0718`. +Some errors have detailed explanations: E0369, E0392, E0718. +For more information about an error, try `rustc --explain E0369`. diff --git a/tests/ui/lint/ptr_null_checks.rs b/tests/ui/lint/ptr_null_checks.rs index 3028084e962..4925019be1e 100644 --- a/tests/ui/lint/ptr_null_checks.rs +++ b/tests/ui/lint/ptr_null_checks.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(ptr_from_ref)] - use std::ptr; extern "C" fn c_fn() {} diff --git a/tests/ui/lint/ptr_null_checks.stderr b/tests/ui/lint/ptr_null_checks.stderr index 0edc1b86536..70a27790c5b 100644 --- a/tests/ui/lint/ptr_null_checks.stderr +++ b/tests/ui/lint/ptr_null_checks.stderr @@ -1,5 +1,5 @@ warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:14:8 + --> $DIR/ptr_null_checks.rs:12:8 | LL | if (fn_ptr as *mut ()).is_null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | if (fn_ptr as *mut ()).is_null() {} = note: `#[warn(useless_ptr_null_checks)]` on by default warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:16:8 + --> $DIR/ptr_null_checks.rs:14:8 | LL | if (fn_ptr as *const u8).is_null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | if (fn_ptr as *const u8).is_null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:18:8 + --> $DIR/ptr_null_checks.rs:16:8 | LL | if (fn_ptr as *const ()) == std::ptr::null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | if (fn_ptr as *const ()) == std::ptr::null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:20:8 + --> $DIR/ptr_null_checks.rs:18:8 | LL | if (fn_ptr as *mut ()) == std::ptr::null_mut() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | if (fn_ptr as *mut ()) == std::ptr::null_mut() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:22:8 + --> $DIR/ptr_null_checks.rs:20:8 | LL | if (fn_ptr as *const ()) == (0 as *const ()) {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | if (fn_ptr as *const ()) == (0 as *const ()) {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:24:8 + --> $DIR/ptr_null_checks.rs:22:8 | LL | if <*const _>::is_null(fn_ptr as *const ()) {} | ^^^^^^^^^^^^^^^^^^^^------^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | if <*const _>::is_null(fn_ptr as *const ()) {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:26:8 + --> $DIR/ptr_null_checks.rs:24:8 | LL | if (fn_ptr as *mut fn() as *const fn() as *const ()).is_null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | if (fn_ptr as *mut fn() as *const fn() as *const ()).is_null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:28:8 + --> $DIR/ptr_null_checks.rs:26:8 | LL | if (fn_ptr as *mut fn() as *const fn()).cast_mut().is_null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | if (fn_ptr as *mut fn() as *const fn()).cast_mut().is_null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:30:8 + --> $DIR/ptr_null_checks.rs:28:8 | LL | if ((fn_ptr as *mut fn()).cast() as *const fn()).cast_mut().is_null() {} | ^^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | if ((fn_ptr as *mut fn()).cast() as *const fn()).cast_mut().is_null() { = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:32:8 + --> $DIR/ptr_null_checks.rs:30:8 | LL | if (fn_ptr as fn() as *const ()).is_null() {} | ^--------------^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | if (fn_ptr as fn() as *const ()).is_null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:34:8 + --> $DIR/ptr_null_checks.rs:32:8 | LL | if (c_fn as *const fn()).is_null() {} | ^----^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -110,7 +110,7 @@ LL | if (c_fn as *const fn()).is_null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:38:8 + --> $DIR/ptr_null_checks.rs:36:8 | LL | if (&mut 8 as *mut i32).is_null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,13 +118,13 @@ LL | if (&mut 8 as *mut i32).is_null() {} | expression has type `&mut i32` warning: returned pointer of `from_mut` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:40:8 + --> $DIR/ptr_null_checks.rs:38:8 | LL | if ptr::from_mut(&mut 8).is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:42:8 + --> $DIR/ptr_null_checks.rs:40:8 | LL | if (&8 as *const i32).is_null() {} | ^--^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,25 +132,25 @@ LL | if (&8 as *const i32).is_null() {} | expression has type `&i32` warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:44:8 + --> $DIR/ptr_null_checks.rs:42:8 | LL | if ptr::from_ref(&8).is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:46:8 + --> $DIR/ptr_null_checks.rs:44:8 | LL | if ptr::from_ref(&8).cast_mut().is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:48:8 + --> $DIR/ptr_null_checks.rs:46:8 | LL | if (ptr::from_ref(&8).cast_mut() as *mut i32).is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:50:8 + --> $DIR/ptr_null_checks.rs:48:8 | LL | if (&8 as *const i32) == std::ptr::null() {} | ^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -158,7 +158,7 @@ LL | if (&8 as *const i32) == std::ptr::null() {} | expression has type `&i32` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:53:8 + --> $DIR/ptr_null_checks.rs:51:8 | LL | if (ref_num as *const i32) == std::ptr::null() {} | ^-------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | if (ref_num as *const i32) == std::ptr::null() {} | expression has type `&i32` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:55:8 + --> $DIR/ptr_null_checks.rs:53:8 | LL | if (b"\0" as *const u8).is_null() {} | ^-----^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +174,7 @@ LL | if (b"\0" as *const u8).is_null() {} | expression has type `&[u8; 1]` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:57:8 + --> $DIR/ptr_null_checks.rs:55:8 | LL | if ("aa" as *const str).is_null() {} | ^----^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ LL | if ("aa" as *const str).is_null() {} | expression has type `&str` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:59:8 + --> $DIR/ptr_null_checks.rs:57:8 | LL | if (&[1, 2] as *const i32).is_null() {} | ^-------^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -190,7 +190,7 @@ LL | if (&[1, 2] as *const i32).is_null() {} | expression has type `&[i32; 2]` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:61:8 + --> $DIR/ptr_null_checks.rs:59:8 | LL | if (&mut [1, 2] as *mut i32) == std::ptr::null_mut() {} | ^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +198,7 @@ LL | if (&mut [1, 2] as *mut i32) == std::ptr::null_mut() {} | expression has type `&mut [i32; 2]` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:63:8 + --> $DIR/ptr_null_checks.rs:61:8 | LL | if (static_i32() as *const i32).is_null() {} | ^------------^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,7 +206,7 @@ LL | if (static_i32() as *const i32).is_null() {} | expression has type `&i32` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:65:8 + --> $DIR/ptr_null_checks.rs:63:8 | LL | if (&*{ static_i32() } as *const i32).is_null() {} | ^------------------^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -214,13 +214,13 @@ LL | if (&*{ static_i32() } as *const i32).is_null() {} | expression has type `&i32` warning: returned pointer of `as_ptr` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:69:8 + --> $DIR/ptr_null_checks.rs:67:8 | LL | if ptr::NonNull::new(&mut 8).unwrap().as_ptr().is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: returned pointer of `as_ptr` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:71:8 + --> $DIR/ptr_null_checks.rs:69:8 | LL | if ptr::NonNull::<u8>::dangling().as_ptr().is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 25e0c75f70d..84267c0af03 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -1,7 +1,5 @@ // check-fail -#![feature(ptr_from_ref)] - extern "C" { // N.B., mutability can be easily incorrect in FFI calls -- as // in C, the default is mutable pointers. @@ -116,6 +114,13 @@ unsafe fn assign_to_ref() { let value = num as *const i32 as *mut i32; *value = 1; //~^ ERROR assigning to `&T` is undefined behavior + let value = num as *const i32; + let value = value as *mut i32; + *value = 1; + //~^ ERROR assigning to `&T` is undefined behavior + let value = num as *const i32 as *mut i32; + *value = 1; + //~^ ERROR assigning to `&T` is undefined behavior let value_rebind = value; *value_rebind = 1; //~^ ERROR assigning to `&T` is undefined behavior diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr index 8d5f8da6852..374a58d7b7b 100644 --- a/tests/ui/lint/reference_casting.stderr +++ b/tests/ui/lint/reference_casting.stderr @@ -1,5 +1,5 @@ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:19:16 + --> $DIR/reference_casting.rs:17:16 | LL | let _num = &mut *(num as *const i32 as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _num = &mut *(num as *const i32 as *mut i32); = note: `#[deny(invalid_reference_casting)]` on by default error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:21:16 + --> $DIR/reference_casting.rs:19:16 | LL | let _num = &mut *(num as *const i32).cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let _num = &mut *(num as *const i32).cast_mut(); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:23:16 + --> $DIR/reference_casting.rs:21:16 | LL | let _num = &mut *std::ptr::from_ref(num).cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | let _num = &mut *std::ptr::from_ref(num).cast_mut(); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:25:16 + --> $DIR/reference_casting.rs:23:16 | LL | let _num = &mut *std::ptr::from_ref({ num }).cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | let _num = &mut *std::ptr::from_ref({ num }).cast_mut(); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:27:16 + --> $DIR/reference_casting.rs:25:16 | LL | let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut(); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:29:16 + --> $DIR/reference_casting.rs:27:16 | LL | let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:31:16 + --> $DIR/reference_casting.rs:29:16 | LL | let _num = &mut *(num as *const i32).cast::<i32>().cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _num = &mut *(num as *const i32).cast::<i32>().cast_mut(); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:33:16 + --> $DIR/reference_casting.rs:31:16 | LL | let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_const().cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_cons = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:35:16 + --> $DIR/reference_casting.rs:33:16 | LL | let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:37:16 + --> $DIR/reference_casting.rs:35:16 | LL | let _num = &mut *std::mem::transmute::<_, *mut i32>(num); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | let _num = &mut *std::mem::transmute::<_, *mut i32>(num); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:39:16 + --> $DIR/reference_casting.rs:37:16 | LL | let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:41:16 + --> $DIR/reference_casting.rs:39:16 | LL | let _num = &mut *std::cell::UnsafeCell::raw_get( | ________________^ @@ -100,7 +100,7 @@ LL | | ); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:47:16 + --> $DIR/reference_casting.rs:45:16 | LL | let deferred = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -110,7 +110,7 @@ LL | let _num = &mut *deferred; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:50:16 + --> $DIR/reference_casting.rs:48:16 | LL | let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32; | ---------------------------------------------------------------------------- casting happend here @@ -120,7 +120,7 @@ LL | let _num = &mut *deferred; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:53:16 + --> $DIR/reference_casting.rs:51:16 | LL | let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32; | ---------------------------------------------------------------------------- casting happend here @@ -131,7 +131,7 @@ LL | let _num = &mut *deferred_rebind; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:55:16 + --> $DIR/reference_casting.rs:53:16 | LL | let _num = &mut *(num as *const _ as usize as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL | let _num = &mut *(num as *const _ as usize as *mut i32); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:57:16 + --> $DIR/reference_casting.rs:55:16 | LL | let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -147,7 +147,7 @@ LL | let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) a = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:64:16 + --> $DIR/reference_casting.rs:62:16 | LL | let num = NUM as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -158,7 +158,7 @@ LL | let _num = &mut *num; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:68:16 + --> $DIR/reference_casting.rs:66:16 | LL | let _num = &mut *(cell as *const _ as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | let _num = &mut *(cell as *const _ as *mut i32); = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get` error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:72:9 + --> $DIR/reference_casting.rs:70:9 | LL | &mut *((this as *const _) as *mut _) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -175,7 +175,7 @@ LL | &mut *((this as *const _) as *mut _) = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:77:18 + --> $DIR/reference_casting.rs:75:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -183,7 +183,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:82:18 + --> $DIR/reference_casting.rs:80:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -191,7 +191,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:92:5 + --> $DIR/reference_casting.rs:90:5 | LL | *(a as *const _ as *mut _) = String::from("Replaced"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | *(a as *const _ as *mut _) = String::from("Replaced"); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:94:5 + --> $DIR/reference_casting.rs:92:5 | LL | *(a as *const _ as *mut String) += " world"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -207,7 +207,7 @@ LL | *(a as *const _ as *mut String) += " world"; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:96:5 + --> $DIR/reference_casting.rs:94:5 | LL | *std::ptr::from_ref(num).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -215,7 +215,7 @@ LL | *std::ptr::from_ref(num).cast_mut() += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:98:5 + --> $DIR/reference_casting.rs:96:5 | LL | *std::ptr::from_ref({ num }).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -223,7 +223,7 @@ LL | *std::ptr::from_ref({ num }).cast_mut() += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:100:5 + --> $DIR/reference_casting.rs:98:5 | LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +231,7 @@ LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:102:5 + --> $DIR/reference_casting.rs:100:5 | LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -239,7 +239,7 @@ LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:104:5 + --> $DIR/reference_casting.rs:102:5 | LL | *std::mem::transmute::<_, *mut i32>(num) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -247,7 +247,7 @@ LL | *std::mem::transmute::<_, *mut i32>(num) += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:106:5 + --> $DIR/reference_casting.rs:104:5 | LL | *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -255,7 +255,7 @@ LL | *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:108:5 + --> $DIR/reference_casting.rs:106:5 | LL | / std::ptr::write( LL | | @@ -267,7 +267,7 @@ LL | | ); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:113:5 + --> $DIR/reference_casting.rs:111:5 | LL | *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -276,7 +276,27 @@ LL | *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5; = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get` error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:117:5 + --> $DIR/reference_casting.rs:115:5 + | +LL | let value = num as *const i32 as *mut i32; + | ----------------------------- casting happend here +LL | *value = 1; + | ^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:119:5 + | +LL | let value = value as *mut i32; + | ----------------- casting happend here +LL | *value = 1; + | ^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:122:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -286,7 +306,7 @@ LL | *value = 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:120:5 + --> $DIR/reference_casting.rs:125:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -297,7 +317,7 @@ LL | *value_rebind = 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:122:5 + --> $DIR/reference_casting.rs:127:5 | LL | *(num as *const i32).cast::<i32>().cast_mut() = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -305,7 +325,7 @@ LL | *(num as *const i32).cast::<i32>().cast_mut() = 2; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:124:5 + --> $DIR/reference_casting.rs:129:5 | LL | *(num as *const _ as usize as *mut i32) = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -313,7 +333,7 @@ LL | *(num as *const _ as usize as *mut i32) = 2; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:126:5 + --> $DIR/reference_casting.rs:131:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -324,7 +344,7 @@ LL | std::ptr::write(value, 2); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:128:5 + --> $DIR/reference_casting.rs:133:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -335,7 +355,7 @@ LL | std::ptr::write_unaligned(value, 2); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:130:5 + --> $DIR/reference_casting.rs:135:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -346,12 +366,12 @@ LL | std::ptr::write_volatile(value, 2); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:134:9 + --> $DIR/reference_casting.rs:139:9 | LL | *(this as *const _ as *mut _) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> -error: aborting due to 40 previous errors +error: aborting due to 42 previous errors diff --git a/tests/ui/macros/issue-118786.rs b/tests/ui/macros/issue-118786.rs new file mode 100644 index 00000000000..84af3a65113 --- /dev/null +++ b/tests/ui/macros/issue-118786.rs @@ -0,0 +1,16 @@ +// compile-flags: --crate-type lib -O -C debug-assertions=yes + +// Regression test for issue 118786 + +macro_rules! make_macro { + ($macro_name:tt) => { + macro_rules! $macro_name { + //~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon + //~| ERROR macro expansion ignores token `{` and any following + //~| ERROR cannot find macro `macro_rules` in this scope + () => {} + } + } +} + +make_macro!((meow)); diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr new file mode 100644 index 00000000000..ca3a40f31c1 --- /dev/null +++ b/tests/ui/macros/issue-118786.stderr @@ -0,0 +1,47 @@ +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/issue-118786.rs:7:22 + | +LL | macro_rules! $macro_name { + | ^^^^^^^^^^^ + | +help: change the delimiters to curly braces + | +LL | macro_rules! {} { + | ~ + +help: add a semicolon + | +LL | macro_rules! $macro_name; { + | + + +error: macro expansion ignores token `{` and any following + --> $DIR/issue-118786.rs:7:34 + | +LL | macro_rules! $macro_name { + | ^ +... +LL | make_macro!((meow)); + | ------------------- caused by the macro expansion here + | + = note: the usage of `make_macro!` is likely invalid in item context + +error: cannot find macro `macro_rules` in this scope + --> $DIR/issue-118786.rs:7:9 + | +LL | macro_rules! $macro_name { + | ^^^^^^^^^^^ +... +LL | make_macro!((meow)); + | ------------------- in this macro invocation + | +note: maybe you have forgotten to define a name for this `macro_rules!` + --> $DIR/issue-118786.rs:7:9 + | +LL | macro_rules! $macro_name { + | ^^^^^^^^^^^ +... +LL | make_macro!((meow)); + | ------------------- in this macro invocation + = note: this error originates in the macro `make_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + diff --git a/tests/ui/panic-handler/panic-handler-duplicate.stderr b/tests/ui/panic-handler/panic-handler-duplicate.stderr index 5c50b7016b2..299847474cd 100644 --- a/tests/ui/panic-handler/panic-handler-duplicate.stderr +++ b/tests/ui/panic-handler/panic-handler-duplicate.stderr @@ -1,14 +1,18 @@ error[E0152]: found duplicate lang item `panic_impl` --> $DIR/panic-handler-duplicate.rs:15:1 | -LL | fn panic2(info: &PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic2(info: &PanicInfo) -> ! { +LL | | loop {} +LL | | } + | |_^ | note: the lang item is first defined here --> $DIR/panic-handler-duplicate.rs:10:1 | -LL | fn panic(info: &PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic(info: &PanicInfo) -> ! { +LL | | loop {} +LL | | } + | |_^ error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr index ad9addec8eb..48c216ce27e 100644 --- a/tests/ui/panic-handler/panic-handler-std.stderr +++ b/tests/ui/panic-handler/panic-handler-std.stderr @@ -1,8 +1,10 @@ error[E0152]: found duplicate lang item `panic_impl` --> $DIR/panic-handler-std.rs:8:1 | -LL | fn panic(info: PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic(info: PanicInfo) -> ! { +LL | | loop {} +LL | | } + | |_^ | = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on) = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib diff --git a/tests/ui/parser/bad-let-else-statement.rs b/tests/ui/parser/bad-let-else-statement.rs new file mode 100644 index 00000000000..7b927c89ba0 --- /dev/null +++ b/tests/ui/parser/bad-let-else-statement.rs @@ -0,0 +1,164 @@ +#![feature(inline_const)] +#![feature(yeet_expr)] +#![allow(incomplete_features)] // Necessary for now, while explicit_tail_calls is incomplete +#![feature(explicit_tail_calls)] + +fn a() { + let foo = { + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn b() { + let foo = for i in 1..2 { + break; + } else { + //~^ ERROR `for...else` loops are not supported + return; + }; +} + +fn c() { + let foo = if true { + 1 + } else { + 0 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn d() { + let foo = loop { + break; + } else { + //~^ ERROR loop...else` loops are not supported + return; + }; +} + +fn e() { + let foo = match true { + true => 1, + false => 0 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +struct X {a: i32} +fn f() { + let foo = X { + a: 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn g() { + let foo = while false { + break; + } else { + //~^ ERROR `while...else` loops are not supported + return; + }; +} + +fn h() { + let foo = const { + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn i() { + let foo = &{ + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn j() { + let bar = 0; + let foo = bar = { + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn k() { + let foo = 1 + { + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn l() { + let foo = 1..{ + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn m() { + let foo = return { + () + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn n() { + let foo = -{ + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn o() -> Result<(), ()> { + let foo = do yeet { + () + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return Ok(()); + }; +} + +fn p() { + let foo = become { + () + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn q() { + let foo = |x: i32| { + x + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn main() {} diff --git a/tests/ui/parser/bad-let-else-statement.stderr b/tests/ui/parser/bad-let-else-statement.stderr new file mode 100644 index 00000000000..7cbda25e417 --- /dev/null +++ b/tests/ui/parser/bad-let-else-statement.stderr @@ -0,0 +1,232 @@ +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:9:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = ({ +LL | 1 +LL ~ }) else { + | + +error: `for...else` loops are not supported + --> $DIR/bad-let-else-statement.rs:18:7 + | +LL | let foo = for i in 1..2 { + | --- `else` is attached to this loop +LL | break; +LL | } else { + | _______^ +LL | | +LL | | return; +LL | | }; + | |_____^ + | + = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:29:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = (if true { +LL | 1 +LL | } else { +LL | 0 +LL ~ }) else { + | + +error: `loop...else` loops are not supported + --> $DIR/bad-let-else-statement.rs:38:7 + | +LL | let foo = loop { + | ---- `else` is attached to this loop +LL | break; +LL | } else { + | _______^ +LL | | +LL | | return; +LL | | }; + | |_____^ + | + = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:48:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = (match true { +LL | true => 1, +LL | false => 0 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:58:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = (X { +LL | a: 1 +LL ~ }) else { + | + +error: `while...else` loops are not supported + --> $DIR/bad-let-else-statement.rs:67:7 + | +LL | let foo = while false { + | ----- `else` is attached to this loop +LL | break; +LL | } else { + | _______^ +LL | | +LL | | return; +LL | | }; + | |_____^ + | + = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:76:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = (const { +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:85:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = &({ +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:95:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = bar = ({ +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:104:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = 1 + ({ +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:113:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = 1..({ +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:122:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = return ({ +LL | () +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:131:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = -({ +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:140:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = do yeet ({ +LL | () +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:149:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = become ({ +LL | () +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:158:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = |x: i32| ({ +LL | x +LL ~ }) else { + | + +error: aborting due to 17 previous errors + diff --git a/tests/ui/parser/trait-item-with-defaultness-fail-semantic.rs b/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs index f2d97b7bac3..bff53f66e19 100644 --- a/tests/ui/parser/trait-item-with-defaultness-fail-semantic.rs +++ b/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs @@ -10,3 +10,7 @@ trait X { default fn f1(); //~ ERROR `default` is only allowed on items in trait impls default fn f2() {} //~ ERROR `default` is only allowed on items in trait impls } + +default const E: u8 = 0; //~ ERROR `default` is only allowed on items in trait impls +default type F = (); //~ ERROR `default` is only allowed on items in trait impls +default fn h() {} //~ ERROR `default` is only allowed on items in trait impls diff --git a/tests/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr index be858cd651d..41fad3a5de3 100644 --- a/tests/ui/parser/trait-item-with-defaultness-fail-semantic.stderr +++ b/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr @@ -1,5 +1,5 @@ error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:6:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:6:5 | LL | default const A: u8; | -------^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | default const A: u8; | `default` because of this error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:7:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:7:5 | LL | default const B: u8 = 0; | -------^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | default const B: u8 = 0; | `default` because of this error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:8:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:8:5 | LL | default type D; | -------^^^^^^^^ @@ -23,7 +23,7 @@ LL | default type D; | `default` because of this error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:9:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:9:5 | LL | default type C: Ord; | -------^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | default type C: Ord; | `default` because of this error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:10:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:10:5 | LL | default fn f1(); | -------^^^^^^^^^ @@ -39,15 +39,39 @@ LL | default fn f1(); | `default` because of this error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:11:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:11:5 | LL | default fn f2() {} | -------^^^^^^^^ | | | `default` because of this +error: `default` is only allowed on items in trait impls + --> $DIR/defaultness-invalid-places-fail-semantic.rs:14:1 + | +LL | default const E: u8 = 0; + | -------^^^^^^^^^^^^^^^^^ + | | + | `default` because of this + +error: `default` is only allowed on items in trait impls + --> $DIR/defaultness-invalid-places-fail-semantic.rs:15:1 + | +LL | default type F = (); + | -------^^^^^^^^^^^^^ + | | + | `default` because of this + +error: `default` is only allowed on items in trait impls + --> $DIR/defaultness-invalid-places-fail-semantic.rs:16:1 + | +LL | default fn h() {} + | -------^^^^^^^ + | | + | `default` because of this + warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:1:12 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:1:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -56,5 +80,5 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete = note: `#[warn(incomplete_features)]` on by default -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 9 previous errors; 1 warning emitted diff --git a/tests/ui/proc-macro/auxiliary/env.rs b/tests/ui/proc-macro/auxiliary/env.rs new file mode 100644 index 00000000000..58bcb08bf06 --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/env.rs @@ -0,0 +1,28 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_tracked_env)] + +extern crate proc_macro; + +use proc_macro::TokenStream; +use proc_macro::tracked_env::var; + +#[proc_macro] +pub fn generate_const(input: TokenStream) -> TokenStream { + let the_const = match var("THE_CONST") { + Ok(x) if x == "12" => { + "const THE_CONST: u32 = 12;" + } + _ => { + "const THE_CONST: u32 = 0;" + } + }; + let another = if var("ANOTHER").is_ok() { + "const ANOTHER: u32 = 1;" + } else { + "const ANOTHER: u32 = 2;" + }; + format!("{the_const}{another}").parse().unwrap() +} diff --git a/tests/ui/proc-macro/env.rs b/tests/ui/proc-macro/env.rs new file mode 100644 index 00000000000..1b1d1873eb3 --- /dev/null +++ b/tests/ui/proc-macro/env.rs @@ -0,0 +1,17 @@ +// aux-build:env.rs +// run-pass +// rustc-env: THE_CONST=1 +// compile-flags: -Zunstable-options --env THE_CONST=12 --env ANOTHER=4 + +#![crate_name = "foo"] + +extern crate env; + +use env::generate_const; + +generate_const!(); + +fn main() { + assert_eq!(THE_CONST, 12); + assert_eq!(ANOTHER, 1); +} diff --git a/tests/ui/regions/resolve-re-error-ice.rs b/tests/ui/regions/resolve-re-error-ice.rs index f37b27a82b3..bf6defb9bae 100644 --- a/tests/ui/regions/resolve-re-error-ice.rs +++ b/tests/ui/regions/resolve-re-error-ice.rs @@ -1,8 +1,3 @@ -// check-pass - -// Allow this for now, can remove this UI test when this becomes a hard error. -#![allow(implied_bounds_entailment)] - use std::collections::hash_map::{Keys, HashMap}; use std::marker::PhantomData; @@ -15,6 +10,7 @@ struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>); impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R> { fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { + //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements todo!() } } diff --git a/tests/ui/regions/resolve-re-error-ice.stderr b/tests/ui/regions/resolve-re-error-ice.stderr index e7003e1c32f..41c5f0fa92e 100644 --- a/tests/ui/regions/resolve-re-error-ice.stderr +++ b/tests/ui/regions/resolve-re-error-ice.stderr @@ -1,15 +1,37 @@ -Future incompatibility report: Future breakage diagnostic: -warning: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/resolve-re-error-ice.rs:17:16 +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements + --> $DIR/resolve-re-error-ice.rs:12:5 | LL | fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { - | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `Subject<'_, std::collections::hash_map::Keys<'_, K, V>, (), R>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> -note: the lint level is defined here - --> $DIR/resolve-re-error-ice.rs:4:10 +note: first, the lifetime cannot outlive the anonymous lifetime defined here... + --> $DIR/resolve-re-error-ice.rs:5:16 | -LL | #![allow(implied_bounds_entailment)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn key_set(&self) -> Subject<Keys<K, V>, (), R>; + | ^^^^^ +note: ...so that the method type is compatible with trait + --> $DIR/resolve-re-error-ice.rs:12:5 + | +LL | fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `fn(&Subject<'_, _, _, _>) -> Subject<'_, std::collections::hash_map::Keys<'_, _, _>, _, _>` + found `fn(&Subject<'_, _, _, _>) -> Subject<'a, std::collections::hash_map::Keys<'_, _, _>, _, _>` +note: but, the lifetime must be valid for the lifetime `'a` as defined here... + --> $DIR/resolve-re-error-ice.rs:10:6 + | +LL | impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R> + | ^^ +note: ...so that the type `std::collections::hash_map::Keys<'_, K, V>` will meet its required lifetime bounds... + --> $DIR/resolve-re-error-ice.rs:12:5 + | +LL | fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...that is required by this bound + --> $DIR/resolve-re-error-ice.rs:8:29 + | +LL | struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0495`. diff --git a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr index 1a26f34a52d..2c018ca875d 100644 --- a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr +++ b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr @@ -1,28 +1,28 @@ -[$DIR/dbg-macro-expected-behavior.rs:22] Unit = Unit -[$DIR/dbg-macro-expected-behavior.rs:23] a = Unit -[$DIR/dbg-macro-expected-behavior.rs:29] Point { x: 42, y: 24 } = Point { +[$DIR/dbg-macro-expected-behavior.rs:22:19] Unit = Unit +[$DIR/dbg-macro-expected-behavior.rs:23:19] a = Unit +[$DIR/dbg-macro-expected-behavior.rs:29:24] Point { x: 42, y: 24 } = Point { x: 42, y: 24, } -[$DIR/dbg-macro-expected-behavior.rs:30] b = Point { +[$DIR/dbg-macro-expected-behavior.rs:30:24] b = Point { x: 42, y: 24, } -[$DIR/dbg-macro-expected-behavior.rs:38] -[$DIR/dbg-macro-expected-behavior.rs:42] &a = NoCopy( +[$DIR/dbg-macro-expected-behavior.rs:38:17] +[$DIR/dbg-macro-expected-behavior.rs:42:27] &a = NoCopy( 1337, ) -[$DIR/dbg-macro-expected-behavior.rs:42] dbg!(&a) = NoCopy( +[$DIR/dbg-macro-expected-behavior.rs:42:22] dbg!(&a) = NoCopy( 1337, ) -[$DIR/dbg-macro-expected-behavior.rs:47] f(&42) = 42 +[$DIR/dbg-macro-expected-behavior.rs:47:18] f(&42) = 42 before -[$DIR/dbg-macro-expected-behavior.rs:52] { foo += 1; eprintln!("before"); 7331 } = 7331 -[$DIR/dbg-macro-expected-behavior.rs:60] ("Yeah",) = ( +[$DIR/dbg-macro-expected-behavior.rs:52:22] { foo += 1; eprintln!("before"); 7331 } = 7331 +[$DIR/dbg-macro-expected-behavior.rs:60:27] ("Yeah",) = ( "Yeah", ) -[$DIR/dbg-macro-expected-behavior.rs:63] 1 = 1 -[$DIR/dbg-macro-expected-behavior.rs:63] 2 = 2 -[$DIR/dbg-macro-expected-behavior.rs:67] 1u8 = 1 -[$DIR/dbg-macro-expected-behavior.rs:67] 2u32 = 2 -[$DIR/dbg-macro-expected-behavior.rs:67] "Yeah" = "Yeah" +[$DIR/dbg-macro-expected-behavior.rs:63:29] 1 = 1 +[$DIR/dbg-macro-expected-behavior.rs:63:29] 2 = 2 +[$DIR/dbg-macro-expected-behavior.rs:67:37] 1u8 = 1 +[$DIR/dbg-macro-expected-behavior.rs:67:37] 2u32 = 2 +[$DIR/dbg-macro-expected-behavior.rs:67:37] "Yeah" = "Yeah" diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs index 2a2e8cec3f0..59fb48e794c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs @@ -1,12 +1,13 @@ // check-pass #![crate_type = "lib"] -#![feature(no_core, lang_items, unboxed_closures, auto_traits, intrinsics, rustc_attrs)] +#![feature(no_core, lang_items, unboxed_closures, auto_traits, intrinsics, rustc_attrs, staged_api)] #![feature(fundamental)] #![feature(const_trait_impl, effects, const_mut_refs)] #![allow(internal_features)] #![no_std] #![no_core] +#![stable(feature = "minicore", since = "1.0.0")] #[lang = "sized"] trait Sized {} @@ -82,6 +83,7 @@ trait FnMut<Args: Tuple>: ~const FnOnce<Args> { #[lang = "fn_once"] #[rustc_paren_sugar] trait FnOnce<Args: Tuple> { + #[lang = "fn_once_output"] type Output; extern "rust-call" fn call_once(self, args: Args) -> Self::Output; @@ -93,7 +95,7 @@ struct ConstFnMutClosure<CapturedData, Function> { } #[lang = "tuple_trait"] -pub trait Tuple {} +trait Tuple {} macro_rules! impl_fn_mut_tuple { ($($var:ident)*) => { @@ -509,3 +511,17 @@ trait StructuralPartialEq {} trait StructuralEq {} const fn drop<T: ~const Destruct>(_: T) {} + +extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_eval_select", since = "1.0.0")] + fn const_eval_select<ARG: Tuple, F, G, RET>( + arg: ARG, + called_in_const: F, + called_at_rt: G, + ) -> RET + /* where clauses enforced by built-in method confirmation: + where + F: const FnOnce<Arg, Output = RET>, + G: FnOnce<Arg, Output = RET>, + */; +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs index bbe1194f7a3..5ecb75094f0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs @@ -52,4 +52,7 @@ trait Child1 where Self: ~const Trait {} //~ ERROR `~const` is not allowed // non-const impl impl<T: ~const Trait> Trait for T {} //~ ERROR `~const` is not allowed +// inherent impl (regression test for issue #117004) +impl<T: ~const Trait> Struct<T> {} //~ ERROR `~const` is not allowed + fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index c6e18924fd8..497ec5bcf84 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -194,6 +194,18 @@ note: this impl is not `const`, so it cannot have `~const` trait bounds LL | impl<T: ~const Trait> Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: `~const` is not allowed here + --> $DIR/tilde-const-invalid-places.rs:56:9 + | +LL | impl<T: ~const Trait> Struct<T> {} + | ^^^^^^ + | +note: inherent impls cannot have `~const` trait bounds + --> $DIR/tilde-const-invalid-places.rs:56:1 + | +LL | impl<T: ~const Trait> Struct<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0658]: generic const items are experimental --> $DIR/tilde-const-invalid-places.rs:19:15 | @@ -239,6 +251,6 @@ LL | type Type<T: ~const Trait> = (); = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable -error: aborting due to 26 previous errors +error: aborting due to 27 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs index fbdc3a4f370..bfd9fe42e67 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs @@ -1,5 +1,4 @@ -// known-bug: #110395 -// FIXME check-pass +// check-pass #![feature(const_trait_impl, effects)] #[const_trait] @@ -9,8 +8,8 @@ trait Foo { struct Bar<T>(T); -impl<T: ~const Foo> Bar<T> { - const fn foo(&self) { +impl<T> Bar<T> { + const fn foo(&self) where T: ~const Foo { self.0.foo() } } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr deleted file mode 100644 index 0925bfa7e57..00000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/tilde_const_on_impl_bound.rs:14:9 - | -LL | self.0.foo() - | ^^^^^^^^^^^^ expected `host`, found `true` - | - = note: expected constant `host` - found constant `true` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs index 406e5c8441e..490d6a2f918 100644 --- a/tests/ui/structs-enums/type-sizes.rs +++ b/tests/ui/structs-enums/type-sizes.rs @@ -4,7 +4,6 @@ #![allow(dead_code)] #![feature(never_type)] #![feature(pointer_is_aligned)] -#![feature(ptr_from_ref)] #![feature(strict_provenance)] use std::mem::size_of; diff --git a/tests/ui/traits/issue-102989.rs b/tests/ui/traits/issue-102989.rs index 216cd78e56f..f1ecee0a552 100644 --- a/tests/ui/traits/issue-102989.rs +++ b/tests/ui/traits/issue-102989.rs @@ -7,6 +7,7 @@ trait Sized { } //~ ERROR found duplicate lang item `sized` fn ref_Struct(self: &Struct, f: &u32) -> &u32 { //~^ ERROR `self` parameter is only allowed in associated functions //~| ERROR cannot find type `Struct` in this scope + //~| ERROR mismatched types let x = x << 1; //~^ ERROR cannot find value `x` in this scope } diff --git a/tests/ui/traits/issue-102989.stderr b/tests/ui/traits/issue-102989.stderr index 7d0098fe885..40e49df2b2d 100644 --- a/tests/ui/traits/issue-102989.stderr +++ b/tests/ui/traits/issue-102989.stderr @@ -13,7 +13,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | ^^^^^^ not found in this scope error[E0425]: cannot find value `x` in this scope - --> $DIR/issue-102989.rs:10:13 + --> $DIR/issue-102989.rs:11:13 | LL | let x = x << 1; | ^ help: a local variable with a similar name exists: `f` @@ -22,13 +22,27 @@ error[E0152]: found duplicate lang item `sized` --> $DIR/issue-102989.rs:5:1 | LL | trait Sized { } - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `core` (which `std` depends on) = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib = note: second definition in the local crate (`issue_102989`) -error: aborting due to 4 previous errors +error[E0308]: mismatched types + --> $DIR/issue-102989.rs:7:42 + | +LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + | ---------- ^^^^ expected `&u32`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | +help: consider returning the local binding `f` + | +LL ~ let x = x << 1; +LL + f + | + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0152, E0412, E0425. +Some errors have detailed explanations: E0152, E0308, E0412, E0425. For more information about an error, try `rustc --explain E0152`. diff --git a/tests/ui/traits/issue-117794.rs b/tests/ui/traits/issue-117794.rs new file mode 100644 index 00000000000..a66d6eb10ed --- /dev/null +++ b/tests/ui/traits/issue-117794.rs @@ -0,0 +1,10 @@ +trait Foo {} + +trait T { + fn a(&self) -> impl Foo { + self.b(|| 0) + //~^ ERROR no method named `b` found for reference `&Self` in the current scope + } +} + +fn main() {} diff --git a/tests/ui/traits/issue-117794.stderr b/tests/ui/traits/issue-117794.stderr new file mode 100644 index 00000000000..af63b47f07d --- /dev/null +++ b/tests/ui/traits/issue-117794.stderr @@ -0,0 +1,9 @@ +error[E0599]: no method named `b` found for reference `&Self` in the current scope + --> $DIR/issue-117794.rs:5:14 + | +LL | self.b(|| 0) + | ^ help: there is a method with a similar name: `a` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs new file mode 100644 index 00000000000..10fb7d525b7 --- /dev/null +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -0,0 +1,22 @@ +// compile-flags: -Znext-solver +// +// This is a gnarly test but I don't know how to minimize it, frankly. + +#![feature(lazy_type_alias)] +//~^ WARN the feature `lazy_type_alias` is incomplete + +trait ToUnit<'a> { + type Unit; +} + +trait Overlap<T> {} + +type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit; + +impl<T> Overlap<T> for T {} + +impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} +//~^ ERROR conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)` +//~| ERROR cannot find type `Missing` in this scope + +fn main() {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr new file mode 100644 index 00000000000..c16a48d5f15 --- /dev/null +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -0,0 +1,36 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/issue-118950-root-region.rs:18:55 + | +LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} + | ^^^^^^^ not found in this scope + +warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-118950-root-region.rs:5:12 + | +LL | #![feature(lazy_type_alias)] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = note: `#[warn(incomplete_features)]` on by default + +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)` + --> $DIR/issue-118950-root-region.rs:18:1 + | +LL | impl<T> Overlap<T> for T {} + | ------------------------ first implementation here +LL | +LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)` + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0119, E0412. +For more information about an error, try `rustc --explain E0119`. |
