summaryrefslogtreecommitdiffstats
path: root/src/test/ui/span
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/span
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/span')
-rw-r--r--src/test/ui/span/E0046.rs11
-rw-r--r--src/test/ui/span/E0046.stderr12
-rw-r--r--src/test/ui/span/E0072.rs7
-rw-r--r--src/test/ui/span/E0072.stderr17
-rw-r--r--src/test/ui/span/E0204.rs26
-rw-r--r--src/test/ui/span/E0204.stderr43
-rw-r--r--src/test/ui/span/E0493.rs21
-rw-r--r--src/test/ui/span/E0493.stderr11
-rw-r--r--src/test/ui/span/E0535.rs6
-rw-r--r--src/test/ui/span/E0535.stderr9
-rw-r--r--src/test/ui/span/E0536.rs4
-rw-r--r--src/test/ui/span/E0536.stderr9
-rw-r--r--src/test/ui/span/E0537.rs4
-rw-r--r--src/test/ui/span/E0537.stderr9
-rw-r--r--src/test/ui/span/auxiliary/transitive_dep_three.rs9
-rw-r--r--src/test/ui/span/auxiliary/transitive_dep_two.rs3
-rw-r--r--src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.rs142
-rw-r--r--src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr88
-rw-r--r--src/test/ui/span/borrowck-borrow-overloaded-deref-mut.rs60
-rw-r--r--src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr35
-rw-r--r--src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs62
-rw-r--r--src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr55
-rw-r--r--src/test/ui/span/borrowck-call-method-from-mut-aliasable.rs21
-rw-r--r--src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr12
-rw-r--r--src/test/ui/span/borrowck-fn-in-const-b.rs14
-rw-r--r--src/test/ui/span/borrowck-fn-in-const-b.stderr11
-rw-r--r--src/test/ui/span/borrowck-let-suggestion-suffixes.rs59
-rw-r--r--src/test/ui/span/borrowck-let-suggestion-suffixes.stderr63
-rw-r--r--src/test/ui/span/borrowck-object-mutability.rs26
-rw-r--r--src/test/ui/span/borrowck-object-mutability.stderr21
-rw-r--r--src/test/ui/span/borrowck-ref-into-rvalue.fixed13
-rw-r--r--src/test/ui/span/borrowck-ref-into-rvalue.rs12
-rw-r--r--src/test/ui/span/borrowck-ref-into-rvalue.stderr20
-rw-r--r--src/test/ui/span/coerce-suggestions.rs23
-rw-r--r--src/test/ui/span/coerce-suggestions.stderr72
-rw-r--r--src/test/ui/span/destructor-restrictions.rs11
-rw-r--r--src/test/ui/span/destructor-restrictions.stderr23
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs18
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr93
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs15
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr24
-rw-r--r--src/test/ui/span/dropck-object-cycle.rs47
-rw-r--r--src/test/ui/span/dropck-object-cycle.stderr15
-rw-r--r--src/test/ui/span/dropck_arr_cycle_checked.rs106
-rw-r--r--src/test/ui/span/dropck_arr_cycle_checked.stderr43
-rw-r--r--src/test/ui/span/dropck_direct_cycle_with_drop.rs44
-rw-r--r--src/test/ui/span/dropck_direct_cycle_with_drop.stderr29
-rw-r--r--src/test/ui/span/dropck_misc_variants.rs37
-rw-r--r--src/test/ui/span/dropck_misc_variants.stderr30
-rw-r--r--src/test/ui/span/dropck_vec_cycle_checked.rs111
-rw-r--r--src/test/ui/span/dropck_vec_cycle_checked.stderr43
-rw-r--r--src/test/ui/span/gated-features-attr-spans.rs7
-rw-r--r--src/test/ui/span/gated-features-attr-spans.stderr12
-rw-r--r--src/test/ui/span/impl-wrong-item-for-trait.rs38
-rw-r--r--src/test/ui/span/impl-wrong-item-for-trait.stderr66
-rw-r--r--src/test/ui/span/import-ty-params.rs23
-rw-r--r--src/test/ui/span/import-ty-params.stderr20
-rw-r--r--src/test/ui/span/issue-11925.rs13
-rw-r--r--src/test/ui/span/issue-11925.stderr9
-rw-r--r--src/test/ui/span/issue-15480.fixed14
-rw-r--r--src/test/ui/span/issue-15480.rs13
-rw-r--r--src/test/ui/span/issue-15480.stderr21
-rw-r--r--src/test/ui/span/issue-23338-locals-die-before-temps-of-body.rs28
-rw-r--r--src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr44
-rw-r--r--src/test/ui/span/issue-23729.rs33
-rw-r--r--src/test/ui/span/issue-23729.stderr11
-rw-r--r--src/test/ui/span/issue-23827.rs33
-rw-r--r--src/test/ui/span/issue-23827.stderr11
-rw-r--r--src/test/ui/span/issue-24356.rs27
-rw-r--r--src/test/ui/span/issue-24356.stderr11
-rw-r--r--src/test/ui/span/issue-24690.rs16
-rw-r--r--src/test/ui/span/issue-24690.stderr29
-rw-r--r--src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.rs37
-rw-r--r--src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr17
-rw-r--r--src/test/ui/span/issue-24805-dropck-trait-has-items.rs57
-rw-r--r--src/test/ui/span/issue-24805-dropck-trait-has-items.stderr42
-rw-r--r--src/test/ui/span/issue-24895-copy-clone-dropck.rs29
-rw-r--r--src/test/ui/span/issue-24895-copy-clone-dropck.stderr16
-rw-r--r--src/test/ui/span/issue-25199.rs74
-rw-r--r--src/test/ui/span/issue-25199.stderr15
-rw-r--r--src/test/ui/span/issue-26656.rs42
-rw-r--r--src/test/ui/span/issue-26656.stderr16
-rw-r--r--src/test/ui/span/issue-27522.rs9
-rw-r--r--src/test/ui/span/issue-27522.stderr12
-rw-r--r--src/test/ui/span/issue-29106.rs26
-rw-r--r--src/test/ui/span/issue-29106.stderr29
-rw-r--r--src/test/ui/span/issue-29595.rs7
-rw-r--r--src/test/ui/span/issue-29595.stderr9
-rw-r--r--src/test/ui/span/issue-33884.rs18
-rw-r--r--src/test/ui/span/issue-33884.stderr11
-rw-r--r--src/test/ui/span/issue-34264.rs11
-rw-r--r--src/test/ui/span/issue-34264.stderr102
-rw-r--r--src/test/ui/span/issue-35987.rs14
-rw-r--r--src/test/ui/span/issue-35987.stderr14
-rw-r--r--src/test/ui/span/issue-36530.rs12
-rw-r--r--src/test/ui/span/issue-36530.stderr12
-rw-r--r--src/test/ui/span/issue-36537.rs14
-rw-r--r--src/test/ui/span/issue-36537.stderr14
-rw-r--r--src/test/ui/span/issue-37767.rs41
-rw-r--r--src/test/ui/span/issue-37767.stderr78
-rw-r--r--src/test/ui/span/issue-39018.rs38
-rw-r--r--src/test/ui/span/issue-39018.stderr197
-rw-r--r--src/test/ui/span/issue-39698.rs16
-rw-r--r--src/test/ui/span/issue-39698.stderr43
-rw-r--r--src/test/ui/span/issue-40157.rs4
-rw-r--r--src/test/ui/span/issue-40157.stderr13
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr27
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr27
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.rs19
-rw-r--r--src/test/ui/span/issue-43927-non-ADT-derive.rs6
-rw-r--r--src/test/ui/span/issue-43927-non-ADT-derive.stderr21
-rw-r--r--src/test/ui/span/issue-71363.rs19
-rw-r--r--src/test/ui/span/issue-71363.stderr27
-rw-r--r--src/test/ui/span/issue-7575.rs75
-rw-r--r--src/test/ui/span/issue-7575.stderr82
-rw-r--r--src/test/ui/span/issue-81800.rs2
-rw-r--r--src/test/ui/span/issue-81800.stderr19
-rw-r--r--src/test/ui/span/issue28498-reject-ex1.rs37
-rw-r--r--src/test/ui/span/issue28498-reject-ex1.stderr17
-rw-r--r--src/test/ui/span/issue28498-reject-lifetime-param.rs36
-rw-r--r--src/test/ui/span/issue28498-reject-lifetime-param.stderr17
-rw-r--r--src/test/ui/span/issue28498-reject-passed-to-fn.rs38
-rw-r--r--src/test/ui/span/issue28498-reject-passed-to-fn.stderr17
-rw-r--r--src/test/ui/span/issue28498-reject-trait-bound.rs38
-rw-r--r--src/test/ui/span/issue28498-reject-trait-bound.stderr17
-rw-r--r--src/test/ui/span/lint-unused-unsafe-thir.rs61
-rw-r--r--src/test/ui/span/lint-unused-unsafe-thir.stderr66
-rw-r--r--src/test/ui/span/lint-unused-unsafe.mir.stderr1824
-rw-r--r--src/test/ui/span/lint-unused-unsafe.rs1100
-rw-r--r--src/test/ui/span/macro-span-replacement.rs13
-rw-r--r--src/test/ui/span/macro-span-replacement.stderr19
-rw-r--r--src/test/ui/span/macro-ty-params.rs13
-rw-r--r--src/test/ui/span/macro-ty-params.stderr20
-rw-r--r--src/test/ui/span/method-and-field-eager-resolution.rs15
-rw-r--r--src/test/ui/span/method-and-field-eager-resolution.stderr31
-rw-r--r--src/test/ui/span/missing-unit-argument.rs17
-rw-r--r--src/test/ui/span/missing-unit-argument.stderr99
-rw-r--r--src/test/ui/span/move-closure.rs6
-rw-r--r--src/test/ui/span/move-closure.stderr18
-rw-r--r--src/test/ui/span/multiline-span-E0072.rs10
-rw-r--r--src/test/ui/span/multiline-span-E0072.stderr18
-rw-r--r--src/test/ui/span/multiline-span-simple.rs20
-rw-r--r--src/test/ui/span/multiline-span-simple.stderr21
-rw-r--r--src/test/ui/span/multispan-import-lint.rs10
-rw-r--r--src/test/ui/span/multispan-import-lint.stderr15
-rw-r--r--src/test/ui/span/mut-arg-hint.rs22
-rw-r--r--src/test/ui/span/mut-arg-hint.stderr27
-rw-r--r--src/test/ui/span/mut-ptr-cant-outlive-ref.rs15
-rw-r--r--src/test/ui/span/mut-ptr-cant-outlive-ref.stderr14
-rw-r--r--src/test/ui/span/non-existing-module-import.rs3
-rw-r--r--src/test/ui/span/non-existing-module-import.stderr9
-rw-r--r--src/test/ui/span/pub-struct-field.rs10
-rw-r--r--src/test/ui/span/pub-struct-field.stderr20
-rw-r--r--src/test/ui/span/range-2.rs15
-rw-r--r--src/test/ui/span/range-2.stderr25
-rw-r--r--src/test/ui/span/recursive-type-field.rs18
-rw-r--r--src/test/ui/span/recursive-type-field.stderr35
-rw-r--r--src/test/ui/span/regionck-unboxed-closure-lifetimes.rs16
-rw-r--r--src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr14
-rw-r--r--src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs16
-rw-r--r--src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr16
-rw-r--r--src/test/ui/span/regions-close-over-type-parameter-2.rs27
-rw-r--r--src/test/ui/span/regions-close-over-type-parameter-2.stderr13
-rw-r--r--src/test/ui/span/regions-escape-loop-via-variable.rs14
-rw-r--r--src/test/ui/span/regions-escape-loop-via-variable.stderr13
-rw-r--r--src/test/ui/span/regions-escape-loop-via-vec.rs13
-rw-r--r--src/test/ui/span/regions-escape-loop-via-vec.stderr50
-rw-r--r--src/test/ui/span/regions-infer-borrow-scope-within-loop.rs22
-rw-r--r--src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr14
-rw-r--r--src/test/ui/span/send-is-not-static-ensures-scoping.rs26
-rw-r--r--src/test/ui/span/send-is-not-static-ensures-scoping.stderr29
-rw-r--r--src/test/ui/span/send-is-not-static-std-sync-2.rs39
-rw-r--r--src/test/ui/span/send-is-not-static-std-sync-2.stderr37
-rw-r--r--src/test/ui/span/send-is-not-static-std-sync.rs55
-rw-r--r--src/test/ui/span/send-is-not-static-std-sync.stderr72
-rw-r--r--src/test/ui/span/slice-borrow.rs14
-rw-r--r--src/test/ui/span/slice-borrow.stderr17
-rw-r--r--src/test/ui/span/suggestion-non-ascii.rs4
-rw-r--r--src/test/ui/span/suggestion-non-ascii.stderr9
-rw-r--r--src/test/ui/span/transitive-dep-span.rs15
-rw-r--r--src/test/ui/span/transitive-dep-span.stderr18
-rw-r--r--src/test/ui/span/type-annotations-needed-expr.rs3
-rw-r--r--src/test/ui/span/type-annotations-needed-expr.stderr14
-rw-r--r--src/test/ui/span/type-binding.rs9
-rw-r--r--src/test/ui/span/type-binding.stderr9
-rw-r--r--src/test/ui/span/typo-suggestion.rs9
-rw-r--r--src/test/ui/span/typo-suggestion.stderr15
-rw-r--r--src/test/ui/span/unused-warning-point-at-identifier.rs30
-rw-r--r--src/test/ui/span/unused-warning-point-at-identifier.stderr33
-rw-r--r--src/test/ui/span/vec-must-not-hide-type-from-dropck.rs125
-rw-r--r--src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr29
-rw-r--r--src/test/ui/span/vec_refs_data_with_early_death.rs33
-rw-r--r--src/test/ui/span/vec_refs_data_with_early_death.stderr31
-rw-r--r--src/test/ui/span/visibility-ty-params.rs13
-rw-r--r--src/test/ui/span/visibility-ty-params.stderr21
-rw-r--r--src/test/ui/span/wf-method-late-bound-regions.rs24
-rw-r--r--src/test/ui/span/wf-method-late-bound-regions.stderr14
197 files changed, 8392 insertions, 0 deletions
diff --git a/src/test/ui/span/E0046.rs b/src/test/ui/span/E0046.rs
new file mode 100644
index 000000000..961109892
--- /dev/null
+++ b/src/test/ui/span/E0046.rs
@@ -0,0 +1,11 @@
+trait Foo {
+ fn foo();
+}
+
+struct Bar;
+
+impl Foo for Bar {}
+//~^ ERROR E0046
+
+fn main() {
+}
diff --git a/src/test/ui/span/E0046.stderr b/src/test/ui/span/E0046.stderr
new file mode 100644
index 000000000..1323524f2
--- /dev/null
+++ b/src/test/ui/span/E0046.stderr
@@ -0,0 +1,12 @@
+error[E0046]: not all trait items implemented, missing: `foo`
+ --> $DIR/E0046.rs:7:1
+ |
+LL | fn foo();
+ | --------- `foo` from trait
+...
+LL | impl Foo for Bar {}
+ | ^^^^^^^^^^^^^^^^ missing `foo` in implementation
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/src/test/ui/span/E0072.rs b/src/test/ui/span/E0072.rs
new file mode 100644
index 000000000..bc284cdcb
--- /dev/null
+++ b/src/test/ui/span/E0072.rs
@@ -0,0 +1,7 @@
+struct ListNode { //~ ERROR has infinite size
+ head: u8,
+ tail: Option<ListNode>,
+}
+
+fn main() {
+}
diff --git a/src/test/ui/span/E0072.stderr b/src/test/ui/span/E0072.stderr
new file mode 100644
index 000000000..882ed577c
--- /dev/null
+++ b/src/test/ui/span/E0072.stderr
@@ -0,0 +1,17 @@
+error[E0072]: recursive type `ListNode` has infinite size
+ --> $DIR/E0072.rs:1:1
+ |
+LL | struct ListNode {
+ | ^^^^^^^^^^^^^^^ recursive type has infinite size
+LL | head: u8,
+LL | tail: Option<ListNode>,
+ | ---------------- recursive without indirection
+ |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `ListNode` representable
+ |
+LL | tail: Option<Box<ListNode>>,
+ | ++++ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0072`.
diff --git a/src/test/ui/span/E0204.rs b/src/test/ui/span/E0204.rs
new file mode 100644
index 000000000..174de8cdd
--- /dev/null
+++ b/src/test/ui/span/E0204.rs
@@ -0,0 +1,26 @@
+struct Foo {
+ foo: Vec<u32>,
+}
+
+impl Copy for Foo { } //~ ERROR may not be implemented for this type
+
+#[derive(Copy)] //~ ERROR may not be implemented for this type
+struct Foo2<'a> {
+ ty: &'a mut bool,
+}
+
+enum EFoo {
+ Bar { x: Vec<u32> },
+ Baz,
+}
+
+impl Copy for EFoo { } //~ ERROR may not be implemented for this type
+
+#[derive(Copy)] //~ ERROR may not be implemented for this type
+enum EFoo2<'a> {
+ Bar(&'a mut bool),
+ Baz,
+}
+
+fn main() {
+}
diff --git a/src/test/ui/span/E0204.stderr b/src/test/ui/span/E0204.stderr
new file mode 100644
index 000000000..257584843
--- /dev/null
+++ b/src/test/ui/span/E0204.stderr
@@ -0,0 +1,43 @@
+error[E0204]: the trait `Copy` may not be implemented for this type
+ --> $DIR/E0204.rs:5:6
+ |
+LL | foo: Vec<u32>,
+ | ------------- this field does not implement `Copy`
+...
+LL | impl Copy for Foo { }
+ | ^^^^
+
+error[E0204]: the trait `Copy` may not be implemented for this type
+ --> $DIR/E0204.rs:7:10
+ |
+LL | #[derive(Copy)]
+ | ^^^^
+LL | struct Foo2<'a> {
+LL | ty: &'a mut bool,
+ | ---------------- this field does not implement `Copy`
+ |
+ = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0204]: the trait `Copy` may not be implemented for this type
+ --> $DIR/E0204.rs:17:6
+ |
+LL | Bar { x: Vec<u32> },
+ | ----------- this field does not implement `Copy`
+...
+LL | impl Copy for EFoo { }
+ | ^^^^
+
+error[E0204]: the trait `Copy` may not be implemented for this type
+ --> $DIR/E0204.rs:19:10
+ |
+LL | #[derive(Copy)]
+ | ^^^^
+LL | enum EFoo2<'a> {
+LL | Bar(&'a mut bool),
+ | ------------ this field does not implement `Copy`
+ |
+ = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0204`.
diff --git a/src/test/ui/span/E0493.rs b/src/test/ui/span/E0493.rs
new file mode 100644
index 000000000..ad4100205
--- /dev/null
+++ b/src/test/ui/span/E0493.rs
@@ -0,0 +1,21 @@
+struct Foo {
+ a: u32
+}
+
+impl Drop for Foo {
+ fn drop(&mut self) {}
+}
+
+struct Bar {
+ a: u32
+}
+
+impl Drop for Bar {
+ fn drop(&mut self) {}
+}
+
+const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1;
+//~^ destructors cannot be evaluated at compile-time
+
+fn main() {
+}
diff --git a/src/test/ui/span/E0493.stderr b/src/test/ui/span/E0493.stderr
new file mode 100644
index 000000000..29d1b0009
--- /dev/null
+++ b/src/test/ui/span/E0493.stderr
@@ -0,0 +1,11 @@
+error[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/E0493.rs:17:17
+ |
+LL | const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - value is dropped here
+ | |
+ | constants cannot evaluate destructors
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0493`.
diff --git a/src/test/ui/span/E0535.rs b/src/test/ui/span/E0535.rs
new file mode 100644
index 000000000..e26334e9b
--- /dev/null
+++ b/src/test/ui/span/E0535.rs
@@ -0,0 +1,6 @@
+#[inline(unknown)] //~ ERROR E0535
+pub fn something() {}
+
+fn main() {
+ something();
+}
diff --git a/src/test/ui/span/E0535.stderr b/src/test/ui/span/E0535.stderr
new file mode 100644
index 000000000..f52c3f9f2
--- /dev/null
+++ b/src/test/ui/span/E0535.stderr
@@ -0,0 +1,9 @@
+error[E0535]: invalid argument
+ --> $DIR/E0535.rs:1:10
+ |
+LL | #[inline(unknown)]
+ | ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0535`.
diff --git a/src/test/ui/span/E0536.rs b/src/test/ui/span/E0536.rs
new file mode 100644
index 000000000..72de7b6f4
--- /dev/null
+++ b/src/test/ui/span/E0536.rs
@@ -0,0 +1,4 @@
+#[cfg(not())] //~ ERROR E0536
+pub fn something() {}
+
+pub fn main() {}
diff --git a/src/test/ui/span/E0536.stderr b/src/test/ui/span/E0536.stderr
new file mode 100644
index 000000000..820b0d744
--- /dev/null
+++ b/src/test/ui/span/E0536.stderr
@@ -0,0 +1,9 @@
+error[E0536]: expected 1 cfg-pattern
+ --> $DIR/E0536.rs:1:7
+ |
+LL | #[cfg(not())]
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0536`.
diff --git a/src/test/ui/span/E0537.rs b/src/test/ui/span/E0537.rs
new file mode 100644
index 000000000..4088a9ae5
--- /dev/null
+++ b/src/test/ui/span/E0537.rs
@@ -0,0 +1,4 @@
+#[cfg(unknown())] //~ ERROR E0537
+pub fn something() {}
+
+pub fn main() {}
diff --git a/src/test/ui/span/E0537.stderr b/src/test/ui/span/E0537.stderr
new file mode 100644
index 000000000..5478c3fbc
--- /dev/null
+++ b/src/test/ui/span/E0537.stderr
@@ -0,0 +1,9 @@
+error[E0537]: invalid predicate `unknown`
+ --> $DIR/E0537.rs:1:7
+ |
+LL | #[cfg(unknown())]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0537`.
diff --git a/src/test/ui/span/auxiliary/transitive_dep_three.rs b/src/test/ui/span/auxiliary/transitive_dep_three.rs
new file mode 100644
index 000000000..99b51625a
--- /dev/null
+++ b/src/test/ui/span/auxiliary/transitive_dep_three.rs
@@ -0,0 +1,9 @@
+#[macro_export]
+macro_rules! define_parse_error {
+ () => {
+ #[macro_export]
+ macro_rules! parse_error {
+ () => { parse error }
+ }
+ }
+}
diff --git a/src/test/ui/span/auxiliary/transitive_dep_two.rs b/src/test/ui/span/auxiliary/transitive_dep_two.rs
new file mode 100644
index 000000000..5110c4276
--- /dev/null
+++ b/src/test/ui/span/auxiliary/transitive_dep_two.rs
@@ -0,0 +1,3 @@
+extern crate transitive_dep_three;
+
+transitive_dep_three::define_parse_error!();
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.rs b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.rs
new file mode 100644
index 000000000..76a1d12ea
--- /dev/null
+++ b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.rs
@@ -0,0 +1,142 @@
+// Test how overloaded deref interacts with borrows when DerefMut
+// is implemented.
+
+use std::ops::{Deref, DerefMut};
+
+struct Own<T> {
+ value: *mut T
+}
+
+impl<T> Deref for Own<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ unsafe { &*self.value }
+ }
+}
+
+impl<T> DerefMut for Own<T> {
+ fn deref_mut(&mut self) -> &mut T {
+ unsafe { &mut *self.value }
+ }
+}
+
+struct Point {
+ x: isize,
+ y: isize
+}
+
+impl Point {
+ fn get(&self) -> (isize, isize) {
+ (self.x, self.y)
+ }
+
+ fn set(&mut self, x: isize, y: isize) {
+ self.x = x;
+ self.y = y;
+ }
+
+ fn x_ref(&self) -> &isize {
+ &self.x
+ }
+
+ fn y_mut(&mut self) -> &mut isize {
+ &mut self.y
+ }
+}
+
+fn deref_imm_field(x: Own<Point>) {
+ let __isize = &x.y;
+}
+
+fn deref_mut_field1(x: Own<Point>) {
+ let __isize = &mut x.y; //~ ERROR cannot borrow
+}
+
+fn deref_mut_field2(mut x: Own<Point>) {
+ let __isize = &mut x.y;
+}
+
+fn deref_extend_field(x: &Own<Point>) -> &isize {
+ &x.y
+}
+
+fn deref_extend_mut_field1(x: &Own<Point>) -> &mut isize {
+ &mut x.y //~ ERROR cannot borrow
+}
+
+fn deref_extend_mut_field2(x: &mut Own<Point>) -> &mut isize {
+ &mut x.y
+}
+
+fn deref_extend_mut_field3(x: &mut Own<Point>) {
+ // Hmm, this is unfortunate, because with box it would work,
+ // but it's presently the expected outcome. See `deref_extend_mut_field4`
+ // for the workaround.
+
+ let _x = &mut x.x;
+ let _y = &mut x.y; //~ ERROR cannot borrow
+ use_mut(_x);
+}
+fn deref_extend_mut_field4<'a>(x: &'a mut Own<Point>) {
+ let p = &mut **x;
+ let _x = &mut p.x;
+ let _y = &mut p.y;
+}
+
+fn assign_field1<'a>(x: Own<Point>) {
+ x.y = 3; //~ ERROR cannot borrow
+}
+
+fn assign_field2<'a>(x: &'a Own<Point>) {
+ x.y = 3; //~ ERROR cannot borrow
+}
+
+fn assign_field3<'a>(x: &'a mut Own<Point>) {
+ x.y = 3;
+}
+
+fn assign_field4<'a>(x: &'a mut Own<Point>) {
+ let _p: &mut Point = &mut **x;
+ x.y = 3; //~ ERROR cannot borrow
+ use_mut(_p);
+}
+fn deref_imm_method(x: Own<Point>) {
+ let __isize = x.get();
+}
+
+fn deref_mut_method1(x: Own<Point>) {
+ x.set(0, 0); //~ ERROR cannot borrow
+}
+
+fn deref_mut_method2(mut x: Own<Point>) {
+ x.set(0, 0);
+}
+
+fn deref_extend_method(x: &Own<Point>) -> &isize {
+ x.x_ref()
+}
+
+fn deref_extend_mut_method1(x: &Own<Point>) -> &mut isize {
+ x.y_mut() //~ ERROR cannot borrow
+}
+
+fn deref_extend_mut_method2(x: &mut Own<Point>) -> &mut isize {
+ x.y_mut()
+}
+
+fn assign_method1<'a>(x: Own<Point>) {
+ *x.y_mut() = 3; //~ ERROR cannot borrow
+}
+
+fn assign_method2<'a>(x: &'a Own<Point>) {
+ *x.y_mut() = 3; //~ ERROR cannot borrow
+}
+
+fn assign_method3<'a>(x: &'a mut Own<Point>) {
+ *x.y_mut() = 3;
+}
+
+pub fn main() {}
+
+fn use_mut<T>(_: &mut T) {}
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
new file mode 100644
index 000000000..e4ec9f875
--- /dev/null
+++ b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
@@ -0,0 +1,88 @@
+error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:53:24
+ |
+LL | fn deref_mut_field1(x: Own<Point>) {
+ | - help: consider changing this to be mutable: `mut x`
+LL | let __isize = &mut x.y;
+ | ^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:65:10
+ |
+LL | fn deref_extend_mut_field1(x: &Own<Point>) -> &mut isize {
+ | ----------- help: consider changing this to be a mutable reference: `&mut Own<Point>`
+LL | &mut x.y
+ | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0499]: cannot borrow `*x` as mutable more than once at a time
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:78:19
+ |
+LL | let _x = &mut x.x;
+ | - first mutable borrow occurs here
+LL | let _y = &mut x.y;
+ | ^ second mutable borrow occurs here
+LL | use_mut(_x);
+ | -- first borrow later used here
+
+error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:88:5
+ |
+LL | fn assign_field1<'a>(x: Own<Point>) {
+ | - help: consider changing this to be mutable: `mut x`
+LL | x.y = 3;
+ | ^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:92:5
+ |
+LL | fn assign_field2<'a>(x: &'a Own<Point>) {
+ | -------------- help: consider changing this to be a mutable reference: `&'a mut Own<Point>`
+LL | x.y = 3;
+ | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0499]: cannot borrow `*x` as mutable more than once at a time
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:101:5
+ |
+LL | let _p: &mut Point = &mut **x;
+ | -- first mutable borrow occurs here
+LL | x.y = 3;
+ | ^ second mutable borrow occurs here
+LL | use_mut(_p);
+ | -- first borrow later used here
+
+error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:109:5
+ |
+LL | fn deref_mut_method1(x: Own<Point>) {
+ | - help: consider changing this to be mutable: `mut x`
+LL | x.set(0, 0);
+ | ^^^^^^^^^^^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:121:5
+ |
+LL | fn deref_extend_mut_method1(x: &Own<Point>) -> &mut isize {
+ | ----------- help: consider changing this to be a mutable reference: `&mut Own<Point>`
+LL | x.y_mut()
+ | ^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:129:6
+ |
+LL | fn assign_method1<'a>(x: Own<Point>) {
+ | - help: consider changing this to be mutable: `mut x`
+LL | *x.y_mut() = 3;
+ | ^^^^^^^^^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:133:6
+ |
+LL | fn assign_method2<'a>(x: &'a Own<Point>) {
+ | -------------- help: consider changing this to be a mutable reference: `&'a mut Own<Point>`
+LL | *x.y_mut() = 3;
+ | ^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to 10 previous errors
+
+Some errors have detailed explanations: E0499, E0596.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.rs b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.rs
new file mode 100644
index 000000000..8d43d5da4
--- /dev/null
+++ b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.rs
@@ -0,0 +1,60 @@
+// Test how overloaded deref interacts with borrows when DerefMut
+// is implemented.
+
+use std::ops::{Deref, DerefMut};
+
+struct Own<T> {
+ value: *mut T
+}
+
+impl<T> Deref for Own<T> {
+ type Target = T;
+
+ fn deref<'a>(&'a self) -> &'a T {
+ unsafe { &*self.value }
+ }
+}
+
+impl<T> DerefMut for Own<T> {
+ fn deref_mut<'a>(&'a mut self) -> &'a mut T {
+ unsafe { &mut *self.value }
+ }
+}
+
+fn deref_imm(x: Own<isize>) {
+ let __isize = &*x;
+}
+
+fn deref_mut1(x: Own<isize>) {
+ let __isize = &mut *x; //~ ERROR cannot borrow
+}
+
+fn deref_mut2(mut x: Own<isize>) {
+ let __isize = &mut *x;
+}
+
+fn deref_extend<'a>(x: &'a Own<isize>) -> &'a isize {
+ &**x
+}
+
+fn deref_extend_mut1<'a>(x: &'a Own<isize>) -> &'a mut isize {
+ &mut **x //~ ERROR cannot borrow
+}
+
+fn deref_extend_mut2<'a>(x: &'a mut Own<isize>) -> &'a mut isize {
+ &mut **x
+}
+
+fn assign1<'a>(x: Own<isize>) {
+ *x = 3; //~ ERROR cannot borrow
+}
+
+fn assign2<'a>(x: &'a Own<isize>) {
+ **x = 3; //~ ERROR cannot borrow
+}
+
+fn assign3<'a>(x: &'a mut Own<isize>) {
+ **x = 3;
+}
+
+pub fn main() {}
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
new file mode 100644
index 000000000..3ebfba7e4
--- /dev/null
+++ b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
@@ -0,0 +1,35 @@
+error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
+ --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:29:25
+ |
+LL | fn deref_mut1(x: Own<isize>) {
+ | - help: consider changing this to be mutable: `mut x`
+LL | let __isize = &mut *x;
+ | ^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:41:11
+ |
+LL | fn deref_extend_mut1<'a>(x: &'a Own<isize>) -> &'a mut isize {
+ | -------------- help: consider changing this to be a mutable reference: `&'a mut Own<isize>`
+LL | &mut **x
+ | ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
+ --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:49:6
+ |
+LL | fn assign1<'a>(x: Own<isize>) {
+ | - help: consider changing this to be mutable: `mut x`
+LL | *x = 3;
+ | ^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:53:6
+ |
+LL | fn assign2<'a>(x: &'a Own<isize>) {
+ | -------------- help: consider changing this to be a mutable reference: `&'a mut Own<isize>`
+LL | **x = 3;
+ | ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
new file mode 100644
index 000000000..938fdaf11
--- /dev/null
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
@@ -0,0 +1,62 @@
+#![feature(fn_traits)]
+
+// Ensure that invoking a closure counts as a unique immutable borrow
+
+type Fn<'a> = Box<dyn FnMut() + 'a>;
+
+struct Test<'a> {
+ f: Box<dyn FnMut() + 'a>
+}
+
+fn call<F>(mut f: F) where F: FnMut(Fn) {
+ f(Box::new(|| {
+ //~^ ERROR: cannot borrow `f` as mutable more than once
+ f((Box::new(|| {})))
+ }));
+}
+
+fn test1() {
+ call(|mut a| {
+ a.call_mut(());
+ });
+}
+
+fn test2<F>(f: &F) where F: FnMut() {
+ (*f)();
+ //~^ ERROR cannot borrow `*f` as mutable, as it is behind a `&` reference
+}
+
+fn test3<F>(f: &mut F) where F: FnMut() {
+ (*f)();
+}
+
+fn test4(f: &Test) {
+ f.f.call_mut(())
+ //~^ ERROR: cannot borrow `f.f` as mutable, as it is behind a `&` reference
+}
+
+fn test5(f: &mut Test) {
+ f.f.call_mut(())
+}
+
+fn test6() {
+ let mut f = || {};
+ (|| {
+ f();
+ })();
+}
+
+fn test7() {
+ fn foo<F>(_: F) where F: FnMut(Box<dyn FnMut(isize)>, isize) {}
+ let s = String::new(); // Capture to make f !Copy
+ let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
+ let _ = s.len();
+ };
+ f(Box::new(|a| {
+ //~^ ERROR cannot move out of `f` because it is borrowed
+ foo(f);
+ //~^ ERROR cannot move out of `f`, a captured variable in an `FnMut` closure
+ }), 3);
+}
+
+fn main() {}
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
new file mode 100644
index 000000000..6b43801b5
--- /dev/null
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
@@ -0,0 +1,55 @@
+error[E0499]: cannot borrow `f` as mutable more than once at a time
+ --> $DIR/borrowck-call-is-borrow-issue-12224.rs:12:16
+ |
+LL | f(Box::new(|| {
+ | - ^^ second mutable borrow occurs here
+ | |
+ | first mutable borrow occurs here
+ | first borrow later used by call
+LL |
+LL | f((Box::new(|| {})))
+ | - second borrow occurs due to use of `f` in closure
+
+error[E0596]: cannot borrow `*f` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-call-is-borrow-issue-12224.rs:25:5
+ |
+LL | fn test2<F>(f: &F) where F: FnMut() {
+ | -- help: consider changing this to be a mutable reference: `&mut F`
+LL | (*f)();
+ | ^^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `f.f` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-call-is-borrow-issue-12224.rs:34:5
+ |
+LL | fn test4(f: &Test) {
+ | ----- help: consider changing this to be a mutable reference: `&mut Test<'_>`
+LL | f.f.call_mut(())
+ | ^^^^^^^^^^^^^^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
+ --> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13
+ |
+LL | let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
+ | ----- captured outer variable
+...
+LL | f(Box::new(|a| {
+ | --- captured by this `FnMut` closure
+LL |
+LL | foo(f);
+ | ^ move occurs because `f` has type `[closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 52:58]`, which does not implement the `Copy` trait
+
+error[E0505]: cannot move out of `f` because it is borrowed
+ --> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16
+ |
+LL | f(Box::new(|a| {
+ | - ^^^ move out of `f` occurs here
+ | |
+ | borrow of `f` occurs here
+LL |
+LL | foo(f);
+ | - move occurs due to use in closure
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0499, E0505, E0507, E0596.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.rs b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.rs
new file mode 100644
index 000000000..caf2d2a55
--- /dev/null
+++ b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.rs
@@ -0,0 +1,21 @@
+struct Foo {
+ x: isize,
+}
+
+impl Foo {
+ pub fn f(&self) {}
+ pub fn h(&mut self) {}
+}
+
+fn a(x: &mut Foo) {
+ x.f();
+ x.h();
+}
+
+fn b(x: &Foo) {
+ x.f();
+ x.h(); //~ ERROR cannot borrow
+}
+
+fn main() {
+}
diff --git a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr
new file mode 100644
index 000000000..1864f5de1
--- /dev/null
+++ b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr
@@ -0,0 +1,12 @@
+error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-call-method-from-mut-aliasable.rs:17:5
+ |
+LL | fn b(x: &Foo) {
+ | ---- help: consider changing this to be a mutable reference: `&mut Foo`
+LL | x.f();
+LL | x.h();
+ | ^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/span/borrowck-fn-in-const-b.rs b/src/test/ui/span/borrowck-fn-in-const-b.rs
new file mode 100644
index 000000000..822083efe
--- /dev/null
+++ b/src/test/ui/span/borrowck-fn-in-const-b.rs
@@ -0,0 +1,14 @@
+// Check that we check fns appearing in constant declarations.
+// Issue #22382.
+
+// How about mutating an immutable vector?
+const MUTATE: fn(&Vec<String>) = {
+ fn broken(x: &Vec<String>) {
+ x.push(format!("this is broken"));
+ //~^ ERROR cannot borrow
+ }
+ broken
+};
+
+fn main() {
+}
diff --git a/src/test/ui/span/borrowck-fn-in-const-b.stderr b/src/test/ui/span/borrowck-fn-in-const-b.stderr
new file mode 100644
index 000000000..1f5d8bd32
--- /dev/null
+++ b/src/test/ui/span/borrowck-fn-in-const-b.stderr
@@ -0,0 +1,11 @@
+error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-fn-in-const-b.rs:7:9
+ |
+LL | fn broken(x: &Vec<String>) {
+ | ------------ help: consider changing this to be a mutable reference: `&mut Vec<String>`
+LL | x.push(format!("this is broken"));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.rs b/src/test/ui/span/borrowck-let-suggestion-suffixes.rs
new file mode 100644
index 000000000..6240f103c
--- /dev/null
+++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.rs
@@ -0,0 +1,59 @@
+fn id<T>(x: T) -> T { x }
+
+fn f() {
+ let old = ['o']; // statement 0
+ let mut v1 = Vec::new(); // statement 1
+
+ let mut v2 = Vec::new(); // statement 2
+
+ {
+ let young = ['y']; // statement 3
+
+ v2.push(&young[0]); // statement 4
+ //~^ ERROR `young[_]` does not live long enough
+ //~| NOTE borrowed value does not live long enough
+ } //~ NOTE `young[_]` dropped here while still borrowed
+
+ let mut v3 = Vec::new(); // statement 5
+
+ v3.push(&id('x')); // statement 6
+ //~^ ERROR temporary value dropped while borrowed
+ //~| NOTE creates a temporary which is freed while still in use
+ //~| NOTE temporary value is freed at the end of this statement
+ //~| HELP consider using a `let` binding to create a longer lived value
+
+ {
+
+ let mut v4 = Vec::new(); // (sub) statement 0
+
+ v4.push(&id('y'));
+ //~^ ERROR temporary value dropped while borrowed
+ //~| NOTE creates a temporary which is freed while still in use
+ //~| NOTE temporary value is freed at the end of this statement
+ //~| NOTE consider using a `let` binding to create a longer lived value
+ v4.use_ref();
+ //~^ NOTE borrow later used here
+ } // (statement 7)
+
+ let mut v5 = Vec::new(); // statement 8
+
+ v5.push(&id('z'));
+ //~^ ERROR temporary value dropped while borrowed
+ //~| NOTE creates a temporary which is freed while still in use
+ //~| NOTE temporary value is freed at the end of this statement
+ //~| HELP consider using a `let` binding to create a longer lived value
+
+ v1.push(&old[0]);
+
+ (v1, v2, v3, /* v4 is above. */ v5).use_ref();
+ //~^ NOTE borrow later used here
+ //~| NOTE borrow later used here
+ //~| NOTE borrow later used here
+}
+
+fn main() {
+ f();
+}
+
+trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } }
+impl<T> Fake for T { }
diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr
new file mode 100644
index 000000000..a236dab3a
--- /dev/null
+++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr
@@ -0,0 +1,63 @@
+error[E0597]: `young[_]` does not live long enough
+ --> $DIR/borrowck-let-suggestion-suffixes.rs:12:17
+ |
+LL | v2.push(&young[0]); // statement 4
+ | ^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `young[_]` dropped here while still borrowed
+...
+LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref();
+ | -- borrow later used here
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/borrowck-let-suggestion-suffixes.rs:19:14
+ |
+LL | v3.push(&id('x')); // statement 6
+ | ^^^^^^^ - temporary value is freed at the end of this statement
+ | |
+ | creates a temporary which is freed while still in use
+...
+LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref();
+ | -- borrow later used here
+ |
+help: consider using a `let` binding to create a longer lived value
+ |
+LL ~ let binding = id('x');
+LL ~ v3.push(&binding); // statement 6
+ |
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/borrowck-let-suggestion-suffixes.rs:29:18
+ |
+LL | v4.push(&id('y'));
+ | ^^^^^^^ - temporary value is freed at the end of this statement
+ | |
+ | creates a temporary which is freed while still in use
+...
+LL | v4.use_ref();
+ | ------------ borrow later used here
+ |
+ = note: consider using a `let` binding to create a longer lived value
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/borrowck-let-suggestion-suffixes.rs:40:14
+ |
+LL | v5.push(&id('z'));
+ | ^^^^^^^ - temporary value is freed at the end of this statement
+ | |
+ | creates a temporary which is freed while still in use
+...
+LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref();
+ | -- borrow later used here
+ |
+help: consider using a `let` binding to create a longer lived value
+ |
+LL ~ let binding = id('z');
+LL ~ v5.push(&binding);
+ |
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0597, E0716.
+For more information about an error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/borrowck-object-mutability.rs b/src/test/ui/span/borrowck-object-mutability.rs
new file mode 100644
index 000000000..f5adc2cc1
--- /dev/null
+++ b/src/test/ui/span/borrowck-object-mutability.rs
@@ -0,0 +1,26 @@
+trait Foo {
+ fn borrowed(&self);
+ fn borrowed_mut(&mut self);
+}
+
+fn borrowed_receiver(x: &dyn Foo) {
+ x.borrowed();
+ x.borrowed_mut(); //~ ERROR cannot borrow
+}
+
+fn borrowed_mut_receiver(x: &mut dyn Foo) {
+ x.borrowed();
+ x.borrowed_mut();
+}
+
+fn owned_receiver(x: Box<dyn Foo>) {
+ x.borrowed();
+ x.borrowed_mut(); //~ ERROR cannot borrow
+}
+
+fn mut_owned_receiver(mut x: Box<dyn Foo>) {
+ x.borrowed();
+ x.borrowed_mut();
+}
+
+fn main() {}
diff --git a/src/test/ui/span/borrowck-object-mutability.stderr b/src/test/ui/span/borrowck-object-mutability.stderr
new file mode 100644
index 000000000..cc43f6d09
--- /dev/null
+++ b/src/test/ui/span/borrowck-object-mutability.stderr
@@ -0,0 +1,21 @@
+error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
+ --> $DIR/borrowck-object-mutability.rs:8:5
+ |
+LL | fn borrowed_receiver(x: &dyn Foo) {
+ | -------- help: consider changing this to be a mutable reference: `&mut dyn Foo`
+LL | x.borrowed();
+LL | x.borrowed_mut();
+ | ^^^^^^^^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable
+ --> $DIR/borrowck-object-mutability.rs:18:5
+ |
+LL | fn owned_receiver(x: Box<dyn Foo>) {
+ | - help: consider changing this to be mutable: `mut x`
+LL | x.borrowed();
+LL | x.borrowed_mut();
+ | ^^^^^^^^^^^^^^^^ cannot borrow as mutable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/span/borrowck-ref-into-rvalue.fixed b/src/test/ui/span/borrowck-ref-into-rvalue.fixed
new file mode 100644
index 000000000..51f65e534
--- /dev/null
+++ b/src/test/ui/span/borrowck-ref-into-rvalue.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+fn main() {
+ let msg;
+ let binding = Some("Hello".to_string());
+ match binding {
+ //~^ ERROR temporary value dropped while borrowed
+ Some(ref m) => {
+ msg = m;
+ },
+ None => { panic!() }
+ }
+ println!("{}", *msg);
+}
diff --git a/src/test/ui/span/borrowck-ref-into-rvalue.rs b/src/test/ui/span/borrowck-ref-into-rvalue.rs
new file mode 100644
index 000000000..7b09fad92
--- /dev/null
+++ b/src/test/ui/span/borrowck-ref-into-rvalue.rs
@@ -0,0 +1,12 @@
+// run-rustfix
+fn main() {
+ let msg;
+ match Some("Hello".to_string()) {
+ //~^ ERROR temporary value dropped while borrowed
+ Some(ref m) => {
+ msg = m;
+ },
+ None => { panic!() }
+ }
+ println!("{}", *msg);
+}
diff --git a/src/test/ui/span/borrowck-ref-into-rvalue.stderr b/src/test/ui/span/borrowck-ref-into-rvalue.stderr
new file mode 100644
index 000000000..cb5289d24
--- /dev/null
+++ b/src/test/ui/span/borrowck-ref-into-rvalue.stderr
@@ -0,0 +1,20 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/borrowck-ref-into-rvalue.rs:4:11
+ |
+LL | match Some("Hello".to_string()) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+LL | println!("{}", *msg);
+ | ---- borrow later used here
+ |
+help: consider using a `let` binding to create a longer lived value
+ |
+LL ~ let binding = Some("Hello".to_string());
+LL ~ match binding {
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/src/test/ui/span/coerce-suggestions.rs b/src/test/ui/span/coerce-suggestions.rs
new file mode 100644
index 000000000..7920ae0b2
--- /dev/null
+++ b/src/test/ui/span/coerce-suggestions.rs
@@ -0,0 +1,23 @@
+fn test(_x: &mut String) {}
+
+fn test2(_x: &mut i32) {}
+
+
+fn main() {
+ let x: usize = String::new();
+ //~^ ERROR E0308
+ let x: &str = String::new();
+ //~^ ERROR E0308
+ let y = String::new();
+ test(&y);
+ //~^ ERROR E0308
+ test2(&y);
+ //~^ ERROR E0308
+ let f;
+ f = Box::new(f);
+ //~^ ERROR E0308
+
+ let s = &mut String::new();
+ s = format!("foo");
+ //~^ ERROR E0308
+}
diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr
new file mode 100644
index 000000000..db784d5fe
--- /dev/null
+++ b/src/test/ui/span/coerce-suggestions.stderr
@@ -0,0 +1,72 @@
+error[E0308]: mismatched types
+ --> $DIR/coerce-suggestions.rs:7:20
+ |
+LL | let x: usize = String::new();
+ | ----- ^^^^^^^^^^^^^ expected `usize`, found struct `String`
+ | |
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/coerce-suggestions.rs:9:19
+ |
+LL | let x: &str = String::new();
+ | ---- ^^^^^^^^^^^^^
+ | | |
+ | | expected `&str`, found struct `String`
+ | | help: consider borrowing here: `&String::new()`
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/coerce-suggestions.rs:12:10
+ |
+LL | test(&y);
+ | ---- ^^ types differ in mutability
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected mutable reference `&mut String`
+ found reference `&String`
+note: function defined here
+ --> $DIR/coerce-suggestions.rs:1:4
+ |
+LL | fn test(_x: &mut String) {}
+ | ^^^^ ---------------
+
+error[E0308]: mismatched types
+ --> $DIR/coerce-suggestions.rs:14:11
+ |
+LL | test2(&y);
+ | ----- ^^ types differ in mutability
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected mutable reference `&mut i32`
+ found reference `&String`
+note: function defined here
+ --> $DIR/coerce-suggestions.rs:3:4
+ |
+LL | fn test2(_x: &mut i32) {}
+ | ^^^^^ ------------
+
+error[E0308]: mismatched types
+ --> $DIR/coerce-suggestions.rs:17:9
+ |
+LL | f = Box::new(f);
+ | ^^^^^^^^^^^ cyclic type of infinite size
+ |
+help: consider unboxing the value
+ |
+LL | f = *Box::new(f);
+ | +
+
+error[E0308]: mismatched types
+ --> $DIR/coerce-suggestions.rs:21:9
+ |
+LL | s = format!("foo");
+ | ^^^^^^^^^^^^^^ expected `&mut String`, found struct `String`
+ |
+ = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/span/destructor-restrictions.rs b/src/test/ui/span/destructor-restrictions.rs
new file mode 100644
index 000000000..7fb348a14
--- /dev/null
+++ b/src/test/ui/span/destructor-restrictions.rs
@@ -0,0 +1,11 @@
+// Tests the new destructor semantics.
+
+use std::cell::RefCell;
+
+fn main() {
+ let b = {
+ let a = Box::new(RefCell::new(4));
+ *a.borrow() + 1
+ }; //~^ ERROR `*a` does not live long enough
+ println!("{}", b);
+}
diff --git a/src/test/ui/span/destructor-restrictions.stderr b/src/test/ui/span/destructor-restrictions.stderr
new file mode 100644
index 000000000..53c940462
--- /dev/null
+++ b/src/test/ui/span/destructor-restrictions.stderr
@@ -0,0 +1,23 @@
+error[E0597]: `*a` does not live long enough
+ --> $DIR/destructor-restrictions.rs:8:10
+ |
+LL | *a.borrow() + 1
+ | ^^^^^^^^^^
+ | |
+ | borrowed value does not live long enough
+ | a temporary with access to the borrow is created here ...
+LL | };
+ | -- ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, i32>`
+ | |
+ | `*a` dropped here while still borrowed
+ |
+ = note: the temporary is part of an expression at the end of a block;
+ consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
+help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
+ |
+LL | let x = *a.borrow() + 1; x
+ | +++++++ +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs
new file mode 100644
index 000000000..b280c8ab6
--- /dev/null
+++ b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Wrust-2021-incompatible-closure-captures
+
+pub struct A {}
+
+impl A {
+ async fn create(path: impl AsRef<std::path::Path>) { //~ ERROR `async fn` is not permitted in Rust 2015
+ //~^ WARN changes to closure capture in Rust 2021 will affect drop order [rust_2021_incompatible_closure_captures]
+ ;
+ crate(move || {} ).await //~ ERROR expected function, found module `crate`
+ }
+}
+
+trait C{async fn new(val: T) {} //~ ERROR `async fn` is not permitted in Rust 2015
+//~^ ERROR functions in traits cannot be declared `async`
+//~^^ ERROR cannot find type `T` in this scope
+//~^^^ WARN changes to closure capture in Rust 2021 will affect drop order [rust_2021_incompatible_closure_captures]
+
+//~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
new file mode 100644
index 000000000..50de23229
--- /dev/null
+++ b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
@@ -0,0 +1,93 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:18:53
+ |
+LL | trait C{async fn new(val: T) {}
+ | - unclosed delimiter
+...
+LL |
+ | ^
+
+error[E0670]: `async fn` is not permitted in Rust 2015
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:6:5
+ |
+LL | async fn create(path: impl AsRef<std::path::Path>) {
+ | ^^^^^ to use `async fn`, switch to Rust 2018 or later
+ |
+ = help: pass `--edition 2021` to `rustc`
+ = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0670]: `async fn` is not permitted in Rust 2015
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:9
+ |
+LL | trait C{async fn new(val: T) {}
+ | ^^^^^ to use `async fn`, switch to Rust 2018 or later
+ |
+ = help: pass `--edition 2021` to `rustc`
+ = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:9
+ |
+LL | trait C{async fn new(val: T) {}
+ | -----^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error[E0423]: expected function, found module `crate`
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:9:5
+ |
+LL | crate(move || {} ).await
+ | ^^^^^ not a function
+
+error[E0412]: cannot find type `T` in this scope
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:27
+ |
+LL | pub struct A {}
+ | ------------ similarly named struct `A` defined here
+...
+LL | trait C{async fn new(val: T) {}
+ | ^ help: a struct with a similar name exists: `A`
+
+warning: changes to closure capture in Rust 2021 will affect drop order
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:6:57
+ |
+LL | async fn create(path: impl AsRef<std::path::Path>) {
+ | _____________________----_____________________________-__^
+ | | | |
+ | | | in Rust 2018, `path` is dropped here along with the closure, but in Rust 2021 `path` is not part of the closure
+ | | in Rust 2018, this causes the closure to capture `path`, but in Rust 2021, it has no effect
+LL | |
+LL | | ;
+LL | | crate(move || {} ).await
+LL | | }
+ | |_____^
+ |
+ = note: requested on the command line with `-W rust-2021-incompatible-closure-captures`
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+help: add a dummy let to cause `path` to be fully captured
+ |
+LL | async fn create(path: impl AsRef<std::path::Path>) { let _ = &path;
+ | ++++++++++++++
+
+warning: changes to closure capture in Rust 2021 will affect drop order
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:30
+ |
+LL | trait C{async fn new(val: T) {}
+ | --- - ^^
+ | | |
+ | | in Rust 2018, `val` is dropped here along with the closure, but in Rust 2021 `val` is not part of the closure
+ | in Rust 2018, this causes the closure to capture `val`, but in Rust 2021, it has no effect
+ |
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+help: add a dummy let to cause `val` to be fully captured
+ |
+LL | trait C{async fn new(val: T) { let _ = &val;}
+ | +++++++++++++
+
+error: aborting due to 6 previous errors; 2 warnings emitted
+
+Some errors have detailed explanations: E0412, E0423, E0670, E0706.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs
new file mode 100644
index 000000000..a776e5089
--- /dev/null
+++ b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs
@@ -0,0 +1,15 @@
+// compile-flags -Wrust-2021-incompatible-closure-captures
+
+fn main() {}
+
+pub(crate) struct Numberer {}
+
+impl Numberer {
+ pub(crate) async fn new(
+ //~^ ERROR `async fn` is not permitted in Rust 2015
+ interval: Duration,
+ //~^ ERROR cannot find type `Duration` in this scope
+ ) -> Numberer {
+ Numberer {}
+ }
+}
diff --git a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr
new file mode 100644
index 000000000..37b2f4138
--- /dev/null
+++ b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr
@@ -0,0 +1,24 @@
+error[E0670]: `async fn` is not permitted in Rust 2015
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs:8:16
+ |
+LL | pub(crate) async fn new(
+ | ^^^^^ to use `async fn`, switch to Rust 2018 or later
+ |
+ = help: pass `--edition 2021` to `rustc`
+ = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0412]: cannot find type `Duration` in this scope
+ --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs:10:19
+ |
+LL | interval: Duration,
+ | ^^^^^^^^ not found in this scope
+ |
+help: consider importing this struct
+ |
+LL | use std::time::Duration;
+ |
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0412, E0670.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/span/dropck-object-cycle.rs b/src/test/ui/span/dropck-object-cycle.rs
new file mode 100644
index 000000000..a26123d52
--- /dev/null
+++ b/src/test/ui/span/dropck-object-cycle.rs
@@ -0,0 +1,47 @@
+// This test used to be part of a run-pass test, but revised outlives
+// rule means that it no longer compiles.
+
+#![allow(unused_variables)]
+
+trait Trait<'a> {
+ fn long(&'a self) -> isize;
+ fn short<'b>(&'b self) -> isize;
+}
+
+fn object_invoke1<'d>(x: &'d dyn Trait<'d>) -> (isize, isize) { loop { } }
+
+trait MakerTrait {
+ fn mk() -> Self;
+}
+
+fn make_val<T:MakerTrait>() -> T {
+ MakerTrait::mk()
+}
+
+impl<'t> MakerTrait for Box<dyn Trait<'t>+'static> {
+ fn mk() -> Box<dyn Trait<'t>+'static> { loop { } }
+}
+
+pub fn main() {
+ let m : Box<dyn Trait+'static> = make_val();
+ assert_eq!(object_invoke1(&*m), (4,5));
+ //~^ ERROR `*m` does not live long enough
+
+ // the problem here is that the full type of `m` is
+ //
+ // Box<Trait<'m>+'static>
+ //
+ // Here `'m` must be exactly the lifetime of the variable `m`.
+ // This is because of two requirements:
+ // 1. First, the basic type rules require that the
+ // type of `m`'s value outlives the lifetime of `m`. This puts a lower
+ // bound `'m`.
+ //
+ // 2. Meanwhile, the signature of `object_invoke1` requires that
+ // we create a reference of type `&'d Trait<'d>` for some `'d`.
+ // `'d` cannot outlive `'m`, so that forces the lifetime to be `'m`.
+ //
+ // This then conflicts with the dropck rules, which require that
+ // the type of `m` *strictly outlives* `'m`. Hence we get an
+ // error.
+}
diff --git a/src/test/ui/span/dropck-object-cycle.stderr b/src/test/ui/span/dropck-object-cycle.stderr
new file mode 100644
index 000000000..229d17e1c
--- /dev/null
+++ b/src/test/ui/span/dropck-object-cycle.stderr
@@ -0,0 +1,15 @@
+error[E0597]: `*m` does not live long enough
+ --> $DIR/dropck-object-cycle.rs:27:31
+ |
+LL | assert_eq!(object_invoke1(&*m), (4,5));
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `*m` dropped here while still borrowed
+ | borrow might be used here, when `m` is dropped and runs the destructor for type `Box<dyn Trait<'_>>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/dropck_arr_cycle_checked.rs b/src/test/ui/span/dropck_arr_cycle_checked.rs
new file mode 100644
index 000000000..a14db5ff0
--- /dev/null
+++ b/src/test/ui/span/dropck_arr_cycle_checked.rs
@@ -0,0 +1,106 @@
+// Reject mixing cyclic structure and Drop when using fixed length
+// arrays.
+//
+// (Compare against ui/span/dropck_vec_cycle_checked.rs)
+
+
+
+use std::cell::Cell;
+use id::Id;
+
+mod s {
+ use std::sync::atomic::{AtomicUsize, Ordering};
+
+ static S_COUNT: AtomicUsize = AtomicUsize::new(0);
+
+ pub fn next_count() -> usize {
+ S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
+ }
+}
+
+mod id {
+ use s;
+ #[derive(Debug)]
+ pub struct Id {
+ orig_count: usize,
+ count: usize,
+ }
+
+ impl Id {
+ pub fn new() -> Id {
+ let c = s::next_count();
+ println!("building Id {}", c);
+ Id { orig_count: c, count: c }
+ }
+ pub fn count(&self) -> usize {
+ println!("Id::count on {} returns {}", self.orig_count, self.count);
+ self.count
+ }
+ }
+
+ impl Drop for Id {
+ fn drop(&mut self) {
+ println!("dropping Id {}", self.count);
+ self.count = 0;
+ }
+ }
+}
+
+trait HasId {
+ fn count(&self) -> usize;
+}
+
+#[derive(Debug)]
+struct CheckId<T:HasId> {
+ v: T
+}
+
+#[allow(non_snake_case)]
+fn CheckId<T:HasId>(t: T) -> CheckId<T> { CheckId{ v: t } }
+
+impl<T:HasId> Drop for CheckId<T> {
+ fn drop(&mut self) {
+ assert!(self.v.count() > 0);
+ }
+}
+
+#[derive(Debug)]
+struct B<'a> {
+ id: Id,
+ a: [CheckId<Cell<Option<&'a B<'a>>>>; 2]
+}
+
+impl<'a> HasId for Cell<Option<&'a B<'a>>> {
+ fn count(&self) -> usize {
+ match self.get() {
+ None => 1,
+ Some(b) => b.id.count(),
+ }
+ }
+}
+
+impl<'a> B<'a> {
+ fn new() -> B<'a> {
+ B { id: Id::new(), a: [CheckId(Cell::new(None)), CheckId(Cell::new(None))] }
+ }
+}
+
+fn f() {
+ let (b1, b2, b3);
+ b1 = B::new();
+ b2 = B::new();
+ b3 = B::new();
+ b1.a[0].v.set(Some(&b2));
+ //~^ ERROR `b2` does not live long enough
+ b1.a[1].v.set(Some(&b3));
+ //~^ ERROR `b3` does not live long enough
+ b2.a[0].v.set(Some(&b2));
+ b2.a[1].v.set(Some(&b3));
+ b3.a[0].v.set(Some(&b1));
+ //~^ ERROR `b1` does not live long enough
+ b3.a[1].v.set(Some(&b2));
+}
+
+fn main() {
+ f();
+}
diff --git a/src/test/ui/span/dropck_arr_cycle_checked.stderr b/src/test/ui/span/dropck_arr_cycle_checked.stderr
new file mode 100644
index 000000000..068c779ae
--- /dev/null
+++ b/src/test/ui/span/dropck_arr_cycle_checked.stderr
@@ -0,0 +1,43 @@
+error[E0597]: `b2` does not live long enough
+ --> $DIR/dropck_arr_cycle_checked.rs:93:24
+ |
+LL | b1.a[0].v.set(Some(&b2));
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `b2` dropped here while still borrowed
+ | borrow might be used here, when `b1` is dropped and runs the destructor for type `B<'_>`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `b3` does not live long enough
+ --> $DIR/dropck_arr_cycle_checked.rs:95:24
+ |
+LL | b1.a[1].v.set(Some(&b3));
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `b3` dropped here while still borrowed
+ | borrow might be used here, when `b1` is dropped and runs the destructor for type `B<'_>`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `b1` does not live long enough
+ --> $DIR/dropck_arr_cycle_checked.rs:99:24
+ |
+LL | b3.a[0].v.set(Some(&b1));
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `b1` dropped here while still borrowed
+ | borrow might be used here, when `b1` is dropped and runs the destructor for type `B<'_>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/dropck_direct_cycle_with_drop.rs b/src/test/ui/span/dropck_direct_cycle_with_drop.rs
new file mode 100644
index 000000000..14d6e6654
--- /dev/null
+++ b/src/test/ui/span/dropck_direct_cycle_with_drop.rs
@@ -0,0 +1,44 @@
+// A simple example of an unsound mixing of cyclic structure and Drop.
+//
+// Each `D` has a name and an optional reference to another `D`
+// sibling, but also implements a drop method that prints out its own
+// name as well as the name of its sibling.
+//
+// By setting up a cyclic structure, the drop code cannot possibly
+// work. Therefore this code must be rejected.
+//
+// (As it turns out, essentially any attempt to install a sibling here
+// will be rejected, regardless of whether it forms a cyclic
+// structure or not. This is because the use of the same lifetime
+// `'a` in `&'a D<'a>` cannot be satisfied when `D<'a>` implements
+// `Drop`.)
+
+use std::cell::Cell;
+
+struct D<'a> {
+ name: String,
+ p: Cell<Option<&'a D<'a>>>,
+}
+
+impl<'a> D<'a> {
+ fn new(name: String) -> D<'a> { D { name: name, p: Cell::new(None) } }
+}
+
+impl<'a> Drop for D<'a> {
+ fn drop(&mut self) {
+ println!("dropping {} whose sibling is {:?}",
+ self.name, self.p.get().map(|d| &d.name));
+ }
+}
+
+fn g() {
+ let (d1, d2) = (D::new(format!("d1")), D::new(format!("d2")));
+ d1.p.set(Some(&d2));
+ //~^ ERROR `d2` does not live long enough
+ d2.p.set(Some(&d1));
+ //~^ ERROR `d1` does not live long enough
+}
+
+fn main() {
+ g();
+}
diff --git a/src/test/ui/span/dropck_direct_cycle_with_drop.stderr b/src/test/ui/span/dropck_direct_cycle_with_drop.stderr
new file mode 100644
index 000000000..07ae138ac
--- /dev/null
+++ b/src/test/ui/span/dropck_direct_cycle_with_drop.stderr
@@ -0,0 +1,29 @@
+error[E0597]: `d2` does not live long enough
+ --> $DIR/dropck_direct_cycle_with_drop.rs:36:19
+ |
+LL | d1.p.set(Some(&d2));
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `d2` dropped here while still borrowed
+ | borrow might be used here, when `d1` is dropped and runs the `Drop` code for type `D`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `d1` does not live long enough
+ --> $DIR/dropck_direct_cycle_with_drop.rs:38:19
+ |
+LL | d2.p.set(Some(&d1));
+ | ^^^ borrowed value does not live long enough
+LL |
+LL | }
+ | -
+ | |
+ | `d1` dropped here while still borrowed
+ | borrow might be used here, when `d1` is dropped and runs the `Drop` code for type `D`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/dropck_misc_variants.rs b/src/test/ui/span/dropck_misc_variants.rs
new file mode 100644
index 000000000..5818a94bc
--- /dev/null
+++ b/src/test/ui/span/dropck_misc_variants.rs
@@ -0,0 +1,37 @@
+// check that dropck does the right thing with misc. Ty variants
+
+use std::fmt;
+struct NoisyDrop<T: fmt::Debug>(T);
+impl<T: fmt::Debug> Drop for NoisyDrop<T> {
+ fn drop(&mut self) {
+ let _ = vec!["0wned"];
+ println!("dropping {:?}", self.0)
+ }
+}
+
+trait Associator {
+ type As;
+}
+impl<T: fmt::Debug> Associator for T {
+ type As = NoisyDrop<T>;
+}
+struct Wrap<A: Associator>(<A as Associator>::As);
+
+fn projection() {
+ let (_w, bomb);
+ bomb = vec![""];
+ _w = Wrap::<&[&str]>(NoisyDrop(&bomb));
+}
+//~^^ ERROR `bomb` does not live long enough
+
+fn closure() {
+ let (_w,v);
+ v = vec![""];
+ _w = {
+ let u = NoisyDrop(&v);
+ //~^ ERROR `v` does not live long enough
+ move || u.0.len()
+ };
+}
+
+fn main() { closure(); projection() }
diff --git a/src/test/ui/span/dropck_misc_variants.stderr b/src/test/ui/span/dropck_misc_variants.stderr
new file mode 100644
index 000000000..76e90574c
--- /dev/null
+++ b/src/test/ui/span/dropck_misc_variants.stderr
@@ -0,0 +1,30 @@
+error[E0597]: `bomb` does not live long enough
+ --> $DIR/dropck_misc_variants.rs:23:36
+ |
+LL | _w = Wrap::<&[&str]>(NoisyDrop(&bomb));
+ | ^^^^^ borrowed value does not live long enough
+LL | }
+ | -
+ | |
+ | `bomb` dropped here while still borrowed
+ | borrow might be used here, when `_w` is dropped and runs the destructor for type `Wrap<&[&str]>`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `v` does not live long enough
+ --> $DIR/dropck_misc_variants.rs:31:27
+ |
+LL | let u = NoisyDrop(&v);
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `v` dropped here while still borrowed
+ | borrow might be used here, when `_w` is dropped and runs the destructor for closure
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/dropck_vec_cycle_checked.rs b/src/test/ui/span/dropck_vec_cycle_checked.rs
new file mode 100644
index 000000000..c5d21507d
--- /dev/null
+++ b/src/test/ui/span/dropck_vec_cycle_checked.rs
@@ -0,0 +1,111 @@
+// Reject mixing cyclic structure and Drop when using Vec.
+//
+// (Compare against ui/span/dropck_arr_cycle_checked.rs)
+
+use std::cell::Cell;
+use id::Id;
+
+mod s {
+ use std::sync::atomic::{AtomicUsize, Ordering};
+
+ static S_COUNT: AtomicUsize = AtomicUsize::new(0);
+
+ pub fn next_count() -> usize {
+ S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
+ }
+}
+
+mod id {
+ use s;
+ #[derive(Debug)]
+ pub struct Id {
+ orig_count: usize,
+ count: usize,
+ }
+
+ impl Id {
+ pub fn new() -> Id {
+ let c = s::next_count();
+ println!("building Id {}", c);
+ Id { orig_count: c, count: c }
+ }
+ pub fn count(&self) -> usize {
+ println!("Id::count on {} returns {}", self.orig_count, self.count);
+ self.count
+ }
+ }
+
+ impl Drop for Id {
+ fn drop(&mut self) {
+ println!("dropping Id {}", self.count);
+ self.count = 0;
+ }
+ }
+}
+
+trait HasId {
+ fn count(&self) -> usize;
+}
+
+#[derive(Debug)]
+struct CheckId<T:HasId> {
+ v: T
+}
+
+#[allow(non_snake_case)]
+fn CheckId<T:HasId>(t: T) -> CheckId<T> { CheckId{ v: t } }
+
+impl<T:HasId> Drop for CheckId<T> {
+ fn drop(&mut self) {
+ assert!(self.v.count() > 0);
+ }
+}
+
+#[derive(Debug)]
+struct C<'a> {
+ id: Id,
+ v: Vec<CheckId<Cell<Option<&'a C<'a>>>>>,
+}
+
+impl<'a> HasId for Cell<Option<&'a C<'a>>> {
+ fn count(&self) -> usize {
+ match self.get() {
+ None => 1,
+ Some(c) => c.id.count(),
+ }
+ }
+}
+
+impl<'a> C<'a> {
+ fn new() -> C<'a> {
+ C { id: Id::new(), v: Vec::new() }
+ }
+}
+
+fn f() {
+ let (mut c1, mut c2, mut c3);
+ c1 = C::new();
+ c2 = C::new();
+ c3 = C::new();
+
+ c1.v.push(CheckId(Cell::new(None)));
+ c1.v.push(CheckId(Cell::new(None)));
+ c2.v.push(CheckId(Cell::new(None)));
+ c2.v.push(CheckId(Cell::new(None)));
+ c3.v.push(CheckId(Cell::new(None)));
+ c3.v.push(CheckId(Cell::new(None)));
+
+ c1.v[0].v.set(Some(&c2));
+ //~^ ERROR `c2` does not live long enough
+ c1.v[1].v.set(Some(&c3));
+ //~^ ERROR `c3` does not live long enough
+ c2.v[0].v.set(Some(&c2));
+ c2.v[1].v.set(Some(&c3));
+ c3.v[0].v.set(Some(&c1));
+ //~^ ERROR `c1` does not live long enough
+ c3.v[1].v.set(Some(&c2));
+}
+
+fn main() {
+ f();
+}
diff --git a/src/test/ui/span/dropck_vec_cycle_checked.stderr b/src/test/ui/span/dropck_vec_cycle_checked.stderr
new file mode 100644
index 000000000..7ff991c0c
--- /dev/null
+++ b/src/test/ui/span/dropck_vec_cycle_checked.stderr
@@ -0,0 +1,43 @@
+error[E0597]: `c2` does not live long enough
+ --> $DIR/dropck_vec_cycle_checked.rs:98:24
+ |
+LL | c1.v[0].v.set(Some(&c2));
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `c2` dropped here while still borrowed
+ | borrow might be used here, when `c1` is dropped and runs the destructor for type `C<'_>`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `c3` does not live long enough
+ --> $DIR/dropck_vec_cycle_checked.rs:100:24
+ |
+LL | c1.v[1].v.set(Some(&c3));
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `c3` dropped here while still borrowed
+ | borrow might be used here, when `c1` is dropped and runs the destructor for type `C<'_>`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `c1` does not live long enough
+ --> $DIR/dropck_vec_cycle_checked.rs:104:24
+ |
+LL | c3.v[0].v.set(Some(&c1));
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `c1` dropped here while still borrowed
+ | borrow might be used here, when `c1` is dropped and runs the destructor for type `C<'_>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/gated-features-attr-spans.rs b/src/test/ui/span/gated-features-attr-spans.rs
new file mode 100644
index 000000000..69511ab8e
--- /dev/null
+++ b/src/test/ui/span/gated-features-attr-spans.rs
@@ -0,0 +1,7 @@
+#[repr(simd)] //~ ERROR are experimental
+struct Coord {
+ x: u32,
+ y: u32,
+}
+
+fn main() {}
diff --git a/src/test/ui/span/gated-features-attr-spans.stderr b/src/test/ui/span/gated-features-attr-spans.stderr
new file mode 100644
index 000000000..c8b8f346b
--- /dev/null
+++ b/src/test/ui/span/gated-features-attr-spans.stderr
@@ -0,0 +1,12 @@
+error[E0658]: SIMD types are experimental and possibly buggy
+ --> $DIR/gated-features-attr-spans.rs:1:1
+ |
+LL | #[repr(simd)]
+ | ^^^^^^^^^^^^^
+ |
+ = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
+ = help: add `#![feature(repr_simd)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/span/impl-wrong-item-for-trait.rs b/src/test/ui/span/impl-wrong-item-for-trait.rs
new file mode 100644
index 000000000..bf3358686
--- /dev/null
+++ b/src/test/ui/span/impl-wrong-item-for-trait.rs
@@ -0,0 +1,38 @@
+use std::fmt::Debug;
+
+trait Foo {
+ fn bar(&self);
+ const MY_CONST: u32;
+}
+
+pub struct FooConstForMethod;
+
+impl Foo for FooConstForMethod {
+ //~^ ERROR E0046
+ const bar: u64 = 1;
+ //~^ ERROR E0323
+ const MY_CONST: u32 = 1;
+}
+
+pub struct FooMethodForConst;
+
+impl Foo for FooMethodForConst {
+ //~^ ERROR E0046
+ fn bar(&self) {}
+ fn MY_CONST() {}
+ //~^ ERROR E0324
+}
+
+pub struct FooTypeForMethod;
+
+impl Foo for FooTypeForMethod {
+ //~^ ERROR E0046
+ type bar = u64;
+ //~^ ERROR E0325
+ const MY_CONST: u32 = 1;
+}
+
+impl Debug for FooTypeForMethod {}
+//~^ ERROR E0046
+
+fn main() {}
diff --git a/src/test/ui/span/impl-wrong-item-for-trait.stderr b/src/test/ui/span/impl-wrong-item-for-trait.stderr
new file mode 100644
index 000000000..f919092f9
--- /dev/null
+++ b/src/test/ui/span/impl-wrong-item-for-trait.stderr
@@ -0,0 +1,66 @@
+error[E0323]: item `bar` is an associated const, which doesn't match its trait `Foo`
+ --> $DIR/impl-wrong-item-for-trait.rs:12:5
+ |
+LL | fn bar(&self);
+ | -------------- item in trait
+...
+LL | const bar: u64 = 1;
+ | ^^^^^^^^^^^^^^^^^^^ does not match trait
+
+error[E0324]: item `MY_CONST` is an associated method, which doesn't match its trait `Foo`
+ --> $DIR/impl-wrong-item-for-trait.rs:22:5
+ |
+LL | const MY_CONST: u32;
+ | -------------------- item in trait
+...
+LL | fn MY_CONST() {}
+ | ^^^^^^^^^^^^^^^^ does not match trait
+
+error[E0325]: item `bar` is an associated type, which doesn't match its trait `Foo`
+ --> $DIR/impl-wrong-item-for-trait.rs:30:5
+ |
+LL | fn bar(&self);
+ | -------------- item in trait
+...
+LL | type bar = u64;
+ | ^^^^^^^^^^^^^^^ does not match trait
+
+error[E0046]: not all trait items implemented, missing: `bar`
+ --> $DIR/impl-wrong-item-for-trait.rs:10:1
+ |
+LL | fn bar(&self);
+ | -------------- `bar` from trait
+...
+LL | impl Foo for FooConstForMethod {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `bar` in implementation
+
+error[E0046]: not all trait items implemented, missing: `MY_CONST`
+ --> $DIR/impl-wrong-item-for-trait.rs:19:1
+ |
+LL | const MY_CONST: u32;
+ | ------------------- `MY_CONST` from trait
+...
+LL | impl Foo for FooMethodForConst {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `MY_CONST` in implementation
+
+error[E0046]: not all trait items implemented, missing: `bar`
+ --> $DIR/impl-wrong-item-for-trait.rs:28:1
+ |
+LL | fn bar(&self);
+ | -------------- `bar` from trait
+...
+LL | impl Foo for FooTypeForMethod {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `bar` in implementation
+
+error[E0046]: not all trait items implemented, missing: `fmt`
+ --> $DIR/impl-wrong-item-for-trait.rs:35:1
+ |
+LL | impl Debug for FooTypeForMethod {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation
+ |
+ = help: implement the missing item: `fn fmt(&self, _: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { todo!() }`
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0046, E0323, E0324, E0325.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/src/test/ui/span/import-ty-params.rs b/src/test/ui/span/import-ty-params.rs
new file mode 100644
index 000000000..313cd227b
--- /dev/null
+++ b/src/test/ui/span/import-ty-params.rs
@@ -0,0 +1,23 @@
+mod a {
+ pub mod b {
+ pub mod c {
+ pub struct S<T>(T);
+ }
+ }
+}
+
+macro_rules! import {
+ ($p: path) => (use $p;);
+}
+
+fn f1() {
+ import! { a::b::c::S<u8> } //~ ERROR unexpected generic arguments in path
+}
+fn f2() {
+ import! { a::b::c::S<> } //~ ERROR unexpected generic arguments in path
+}
+fn f3() {
+ import! { a::b<>::c<u8>::S<> } //~ ERROR unexpected generic arguments in path
+}
+
+fn main() {}
diff --git a/src/test/ui/span/import-ty-params.stderr b/src/test/ui/span/import-ty-params.stderr
new file mode 100644
index 000000000..701cd0c04
--- /dev/null
+++ b/src/test/ui/span/import-ty-params.stderr
@@ -0,0 +1,20 @@
+error: unexpected generic arguments in path
+ --> $DIR/import-ty-params.rs:14:25
+ |
+LL | import! { a::b::c::S<u8> }
+ | ^^^^
+
+error: unexpected generic arguments in path
+ --> $DIR/import-ty-params.rs:17:25
+ |
+LL | import! { a::b::c::S<> }
+ | ^^
+
+error: unexpected generic arguments in path
+ --> $DIR/import-ty-params.rs:20:19
+ |
+LL | import! { a::b<>::c<u8>::S<> }
+ | ^^ ^^^^ ^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/span/issue-11925.rs b/src/test/ui/span/issue-11925.rs
new file mode 100644
index 000000000..d9c08fbdd
--- /dev/null
+++ b/src/test/ui/span/issue-11925.rs
@@ -0,0 +1,13 @@
+#![feature(unboxed_closures)]
+
+fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
+
+fn main() {
+ let r = {
+ let x: Box<_> = Box::new(42);
+ let f = to_fn_once(move|| &x); //~ ERROR cannot return reference to local data `x`
+ f()
+ };
+
+ drop(r);
+}
diff --git a/src/test/ui/span/issue-11925.stderr b/src/test/ui/span/issue-11925.stderr
new file mode 100644
index 000000000..1d317fc33
--- /dev/null
+++ b/src/test/ui/span/issue-11925.stderr
@@ -0,0 +1,9 @@
+error[E0515]: cannot return reference to local data `x`
+ --> $DIR/issue-11925.rs:8:35
+ |
+LL | let f = to_fn_once(move|| &x);
+ | ^^ returns a reference to data owned by the current function
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0515`.
diff --git a/src/test/ui/span/issue-15480.fixed b/src/test/ui/span/issue-15480.fixed
new file mode 100644
index 000000000..e6d1a4dd3
--- /dev/null
+++ b/src/test/ui/span/issue-15480.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+ let binding = id(3);
+ let v = vec![
+ &binding
+ ];
+ //~^^ ERROR temporary value dropped while borrowed
+
+ for &&x in &v {
+ println!("{}", x + 3);
+ }
+}
diff --git a/src/test/ui/span/issue-15480.rs b/src/test/ui/span/issue-15480.rs
new file mode 100644
index 000000000..916ce4b1e
--- /dev/null
+++ b/src/test/ui/span/issue-15480.rs
@@ -0,0 +1,13 @@
+// run-rustfix
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+ let v = vec![
+ &id(3)
+ ];
+ //~^^ ERROR temporary value dropped while borrowed
+
+ for &&x in &v {
+ println!("{}", x + 3);
+ }
+}
diff --git a/src/test/ui/span/issue-15480.stderr b/src/test/ui/span/issue-15480.stderr
new file mode 100644
index 000000000..460ad9ac7
--- /dev/null
+++ b/src/test/ui/span/issue-15480.stderr
@@ -0,0 +1,21 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/issue-15480.rs:6:10
+ |
+LL | &id(3)
+ | ^^^^^ creates a temporary which is freed while still in use
+LL | ];
+ | - temporary value is freed at the end of this statement
+...
+LL | for &&x in &v {
+ | -- borrow later used here
+ |
+help: consider using a `let` binding to create a longer lived value
+ |
+LL ~ let binding = id(3);
+LL ~ let v = vec![
+LL ~ &binding
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.rs b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.rs
new file mode 100644
index 000000000..a92ea4ddc
--- /dev/null
+++ b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.rs
@@ -0,0 +1,28 @@
+// This is just checking that we still reject code where temp values
+// are borrowing values for longer than they will be around.
+//
+// Compare to run-pass/issue-23338-params-outlive-temps-of-body.rs
+
+use std::cell::RefCell;
+
+fn foo(x: RefCell<String>) -> String {
+ let y = x;
+ y.borrow().clone()
+}
+//~^^ ERROR `y` does not live long enough
+
+fn foo2(x: RefCell<String>) -> String {
+ let ret = {
+ let y = x;
+ y.borrow().clone()
+ };
+ //~^^ ERROR `y` does not live long enough
+ ret
+}
+
+fn main() {
+ let r = RefCell::new(format!("data"));
+ assert_eq!(foo(r), "data");
+ let r = RefCell::new(format!("data"));
+ assert_eq!(foo2(r), "data");
+}
diff --git a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr
new file mode 100644
index 000000000..3c2022748
--- /dev/null
+++ b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr
@@ -0,0 +1,44 @@
+error[E0597]: `y` does not live long enough
+ --> $DIR/issue-23338-locals-die-before-temps-of-body.rs:10:5
+ |
+LL | y.borrow().clone()
+ | ^^^^^^^^^^
+ | |
+ | borrowed value does not live long enough
+ | a temporary with access to the borrow is created here ...
+LL | }
+ | -
+ | |
+ | `y` dropped here while still borrowed
+ | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, String>`
+ |
+ = note: the temporary is part of an expression at the end of a block;
+ consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
+help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
+ |
+LL | let x = y.borrow().clone(); x
+ | +++++++ +++
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/issue-23338-locals-die-before-temps-of-body.rs:17:9
+ |
+LL | y.borrow().clone()
+ | ^^^^^^^^^^
+ | |
+ | borrowed value does not live long enough
+ | a temporary with access to the borrow is created here ...
+LL | };
+ | -- ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, String>`
+ | |
+ | `y` dropped here while still borrowed
+ |
+ = note: the temporary is part of an expression at the end of a block;
+ consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
+help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
+ |
+LL | let x = y.borrow().clone(); x
+ | +++++++ +++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue-23729.rs b/src/test/ui/span/issue-23729.rs
new file mode 100644
index 000000000..ca33f9c77
--- /dev/null
+++ b/src/test/ui/span/issue-23729.rs
@@ -0,0 +1,33 @@
+// Regression test for #23729
+
+fn main() {
+ let fib = {
+ struct Recurrence {
+ mem: [u64; 2],
+ pos: usize,
+ }
+
+ impl Iterator for Recurrence {
+ //~^ ERROR E0046
+ #[inline]
+ fn next(&mut self) -> Option<u64> {
+ if self.pos < 2 {
+ let next_val = self.mem[self.pos];
+ self.pos += 1;
+ Some(next_val)
+ } else {
+ let next_val = self.mem[0] + self.mem[1];
+ self.mem[0] = self.mem[1];
+ self.mem[1] = next_val;
+ Some(next_val)
+ }
+ }
+ }
+
+ Recurrence { mem: [0, 1], pos: 0 }
+ };
+
+ for e in fib.take(10) {
+ println!("{}", e)
+ }
+}
diff --git a/src/test/ui/span/issue-23729.stderr b/src/test/ui/span/issue-23729.stderr
new file mode 100644
index 000000000..f88ce6c88
--- /dev/null
+++ b/src/test/ui/span/issue-23729.stderr
@@ -0,0 +1,11 @@
+error[E0046]: not all trait items implemented, missing: `Item`
+ --> $DIR/issue-23729.rs:10:9
+ |
+LL | impl Iterator for Recurrence {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation
+ |
+ = help: implement the missing item: `type Item = Type;`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/src/test/ui/span/issue-23827.rs b/src/test/ui/span/issue-23827.rs
new file mode 100644
index 000000000..6b065bf6c
--- /dev/null
+++ b/src/test/ui/span/issue-23827.rs
@@ -0,0 +1,33 @@
+// Regression test for #23827
+
+#![feature(fn_traits, unboxed_closures)]
+
+pub struct Prototype {
+ pub target: u32
+}
+
+trait Component {
+ fn apply(self, e: u32);
+}
+
+impl<C: Component> Fn<(C,)> for Prototype {
+ extern "rust-call" fn call(&self, (comp,): (C,)) -> Prototype {
+ comp.apply(self.target);
+ *self
+ }
+}
+
+impl<C: Component> FnMut<(C,)> for Prototype {
+ extern "rust-call" fn call_mut(&mut self, (comp,): (C,)) -> Prototype {
+ Fn::call(*&self, (comp,))
+ }
+}
+
+impl<C: Component> FnOnce<(C,)> for Prototype {
+ //~^ ERROR E0046
+ extern "rust-call" fn call_once(self, (comp,): (C,)) -> Prototype {
+ Fn::call(&self, (comp,))
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/span/issue-23827.stderr b/src/test/ui/span/issue-23827.stderr
new file mode 100644
index 000000000..46a820f1b
--- /dev/null
+++ b/src/test/ui/span/issue-23827.stderr
@@ -0,0 +1,11 @@
+error[E0046]: not all trait items implemented, missing: `Output`
+ --> $DIR/issue-23827.rs:26:1
+ |
+LL | impl<C: Component> FnOnce<(C,)> for Prototype {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation
+ |
+ = help: implement the missing item: `type Output = Type;`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/src/test/ui/span/issue-24356.rs b/src/test/ui/span/issue-24356.rs
new file mode 100644
index 000000000..7ec05aab2
--- /dev/null
+++ b/src/test/ui/span/issue-24356.rs
@@ -0,0 +1,27 @@
+// Regression test for #24356
+
+fn main() {
+ {
+ use std::ops::Deref;
+
+ struct Thing(i8);
+
+ /*
+ // Correct impl
+ impl Deref for Thing {
+ type Target = i8;
+ fn deref(&self) -> &i8 { &self.0 }
+ }
+ */
+
+ // Causes ICE
+ impl Deref for Thing {
+ //~^ ERROR E0046
+ fn deref(&self) -> i8 { self.0 }
+ }
+
+ let thing = Thing(72);
+
+ *thing
+ };
+}
diff --git a/src/test/ui/span/issue-24356.stderr b/src/test/ui/span/issue-24356.stderr
new file mode 100644
index 000000000..a1f9b2550
--- /dev/null
+++ b/src/test/ui/span/issue-24356.stderr
@@ -0,0 +1,11 @@
+error[E0046]: not all trait items implemented, missing: `Target`
+ --> $DIR/issue-24356.rs:18:9
+ |
+LL | impl Deref for Thing {
+ | ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation
+ |
+ = help: implement the missing item: `type Target = Type;`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/src/test/ui/span/issue-24690.rs b/src/test/ui/span/issue-24690.rs
new file mode 100644
index 000000000..2b7349c55
--- /dev/null
+++ b/src/test/ui/span/issue-24690.rs
@@ -0,0 +1,16 @@
+//! A test to ensure that helpful `note` messages aren't emitted more often
+//! than necessary.
+
+// check-pass
+
+// Although there are three warnings, we should only get two "lint level defined
+// here" notes pointing at the `warnings` span, one for each error type.
+#![warn(unused)]
+
+
+fn main() {
+ let theTwo = 2; //~ WARN should have a snake case name
+ let theOtherTwo = 2; //~ WARN should have a snake case name
+ //~^ WARN unused variable
+ println!("{}", theTwo);
+}
diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr
new file mode 100644
index 000000000..73e166e64
--- /dev/null
+++ b/src/test/ui/span/issue-24690.stderr
@@ -0,0 +1,29 @@
+warning: unused variable: `theOtherTwo`
+ --> $DIR/issue-24690.rs:13:9
+ |
+LL | let theOtherTwo = 2;
+ | ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_theOtherTwo`
+ |
+note: the lint level is defined here
+ --> $DIR/issue-24690.rs:8:9
+ |
+LL | #![warn(unused)]
+ | ^^^^^^
+ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
+
+warning: variable `theTwo` should have a snake case name
+ --> $DIR/issue-24690.rs:12:9
+ |
+LL | let theTwo = 2;
+ | ^^^^^^ help: convert the identifier to snake case: `the_two`
+ |
+ = note: `#[warn(non_snake_case)]` on by default
+
+warning: variable `theOtherTwo` should have a snake case name
+ --> $DIR/issue-24690.rs:13:9
+ |
+LL | let theOtherTwo = 2;
+ | ^^^^^^^^^^^ help: convert the identifier to snake case: `the_other_two`
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.rs b/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.rs
new file mode 100644
index 000000000..9c772052f
--- /dev/null
+++ b/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.rs
@@ -0,0 +1,37 @@
+// Check that child trait who only has items via its *parent* trait
+// does cause dropck to inject extra region constraints.
+
+#![allow(non_camel_case_types)]
+
+trait Parent { fn foo(&self); }
+trait Child: Parent { }
+
+impl Parent for i32 { fn foo(&self) { } }
+impl<'a> Parent for &'a D_Child<i32> {
+ fn foo(&self) {
+ println!("accessing child value: {}", self.0);
+ }
+}
+
+impl Child for i32 { }
+impl<'a> Child for &'a D_Child<i32> { }
+
+struct D_Child<T:Child>(T);
+impl <T:Child> Drop for D_Child<T> { fn drop(&mut self) { self.0.foo() } }
+
+fn f_child() {
+ // `_d` and `d1` are assigned the *same* lifetime by region inference ...
+ let (_d, d1);
+
+ d1 = D_Child(1);
+ // ... we store a reference to `d1` within `_d` ...
+ _d = D_Child(&d1);
+ //~^ ERROR `d1` does not live long enough
+
+ // ... dropck *should* complain, because Drop of _d could (and
+ // does) access the already dropped `d1` via the `foo` method.
+}
+
+fn main() {
+ f_child();
+}
diff --git a/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr b/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr
new file mode 100644
index 000000000..809e60a8c
--- /dev/null
+++ b/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr
@@ -0,0 +1,17 @@
+error[E0597]: `d1` does not live long enough
+ --> $DIR/issue-24805-dropck-child-has-items-via-parent.rs:28:18
+ |
+LL | _d = D_Child(&d1);
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `d1` dropped here while still borrowed
+ | borrow might be used here, when `_d` is dropped and runs the `Drop` code for type `D_Child`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue-24805-dropck-trait-has-items.rs b/src/test/ui/span/issue-24805-dropck-trait-has-items.rs
new file mode 100644
index 000000000..b5c410cd3
--- /dev/null
+++ b/src/test/ui/span/issue-24805-dropck-trait-has-items.rs
@@ -0,0 +1,57 @@
+// Check that traits with various kinds of associated items cause
+// dropck to inject extra region constraints.
+
+#![allow(non_camel_case_types)]
+
+trait HasSelfMethod { fn m1(&self) { } }
+trait HasMethodWithSelfArg { fn m2(x: &Self) { } }
+trait HasType { type Something; }
+
+impl HasSelfMethod for i32 { }
+impl HasMethodWithSelfArg for i32 { }
+impl HasType for i32 { type Something = (); }
+
+impl<'a,T> HasSelfMethod for &'a T { }
+impl<'a,T> HasMethodWithSelfArg for &'a T { }
+impl<'a,T> HasType for &'a T { type Something = (); }
+
+// e.g., `impl_drop!(Send, D_Send)` expands to:
+// ```rust
+// struct D_Send<T:Send>(T);
+// impl<T:Send> Drop for D_Send<T> { fn drop(&mut self) { } }
+// ```
+macro_rules! impl_drop {
+ ($Bound:ident, $Id:ident) => {
+ struct $Id<T:$Bound>(T);
+ impl <T:$Bound> Drop for $Id<T> { fn drop(&mut self) { } }
+ }
+}
+
+impl_drop!{HasSelfMethod, D_HasSelfMethod}
+impl_drop!{HasMethodWithSelfArg, D_HasMethodWithSelfArg}
+impl_drop!{HasType, D_HasType}
+
+fn f_sm() {
+ let (_d, d1);
+ d1 = D_HasSelfMethod(1);
+ _d = D_HasSelfMethod(&d1);
+}
+//~^^ ERROR `d1` does not live long enough
+fn f_mwsa() {
+ let (_d, d1);
+ d1 = D_HasMethodWithSelfArg(1);
+ _d = D_HasMethodWithSelfArg(&d1);
+}
+//~^^ ERROR `d1` does not live long enough
+fn f_t() {
+ let (_d, d1);
+ d1 = D_HasType(1);
+ _d = D_HasType(&d1);
+}
+//~^^ ERROR `d1` does not live long enough
+
+fn main() {
+ f_sm();
+ f_mwsa();
+ f_t();
+}
diff --git a/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr b/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr
new file mode 100644
index 000000000..2e2170669
--- /dev/null
+++ b/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr
@@ -0,0 +1,42 @@
+error[E0597]: `d1` does not live long enough
+ --> $DIR/issue-24805-dropck-trait-has-items.rs:37:26
+ |
+LL | _d = D_HasSelfMethod(&d1);
+ | ^^^ borrowed value does not live long enough
+LL | }
+ | -
+ | |
+ | `d1` dropped here while still borrowed
+ | borrow might be used here, when `_d` is dropped and runs the `Drop` code for type `D_HasSelfMethod`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `d1` does not live long enough
+ --> $DIR/issue-24805-dropck-trait-has-items.rs:43:33
+ |
+LL | _d = D_HasMethodWithSelfArg(&d1);
+ | ^^^ borrowed value does not live long enough
+LL | }
+ | -
+ | |
+ | `d1` dropped here while still borrowed
+ | borrow might be used here, when `_d` is dropped and runs the `Drop` code for type `D_HasMethodWithSelfArg`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `d1` does not live long enough
+ --> $DIR/issue-24805-dropck-trait-has-items.rs:49:20
+ |
+LL | _d = D_HasType(&d1);
+ | ^^^ borrowed value does not live long enough
+LL | }
+ | -
+ | |
+ | `d1` dropped here while still borrowed
+ | borrow might be used here, when `_d` is dropped and runs the `Drop` code for type `D_HasType`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue-24895-copy-clone-dropck.rs b/src/test/ui/span/issue-24895-copy-clone-dropck.rs
new file mode 100644
index 000000000..904cd8f67
--- /dev/null
+++ b/src/test/ui/span/issue-24895-copy-clone-dropck.rs
@@ -0,0 +1,29 @@
+// Check that one cannot subvert Drop Check rule via a user-defined
+// Clone implementation.
+
+#![allow(unused_variables, unused_assignments)]
+
+struct D<T:Copy>(T, &'static str);
+
+#[derive(Copy)]
+struct S<'a>(&'a D<i32>, &'static str);
+impl<'a> Clone for S<'a> {
+ fn clone(&self) -> S<'a> {
+ println!("cloning `S(_, {})` and thus accessing: {}", self.1, (self.0).0);
+ S(self.0, self.1)
+ }
+}
+
+impl<T:Copy> Drop for D<T> {
+ fn drop(&mut self) {
+ println!("calling Drop for {}", self.1);
+ let _call = self.0.clone();
+ }
+}
+
+fn main() {
+ let (d2, d1);
+ d1 = D(34, "d1");
+ d2 = D(S(&d1, "inner"), "d2");
+}
+//~^^ ERROR `d1` does not live long enough
diff --git a/src/test/ui/span/issue-24895-copy-clone-dropck.stderr b/src/test/ui/span/issue-24895-copy-clone-dropck.stderr
new file mode 100644
index 000000000..18a3dc9e6
--- /dev/null
+++ b/src/test/ui/span/issue-24895-copy-clone-dropck.stderr
@@ -0,0 +1,16 @@
+error[E0597]: `d1` does not live long enough
+ --> $DIR/issue-24895-copy-clone-dropck.rs:27:14
+ |
+LL | d2 = D(S(&d1, "inner"), "d2");
+ | ^^^ borrowed value does not live long enough
+LL | }
+ | -
+ | |
+ | `d1` dropped here while still borrowed
+ | borrow might be used here, when `d2` is dropped and runs the `Drop` code for type `D`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue-25199.rs b/src/test/ui/span/issue-25199.rs
new file mode 100644
index 000000000..dbc3b1900
--- /dev/null
+++ b/src/test/ui/span/issue-25199.rs
@@ -0,0 +1,74 @@
+// Regression test for Issue 25199: Check that one cannot hide a
+// destructor's access to borrowed data behind a boxed trait object.
+//
+// Prior to fixing Issue 25199, this example was able to be compiled
+// with rustc, and thus when you ran it, you would see the `Drop` impl
+// for `Test` accessing state that had already been dropping (which is
+// marked explicitly here with checking code within the `Drop` impl
+// for `VecHolder`, but in the general case could just do unsound
+// things like accessing memory that has been freed).
+//
+// Note that I would have liked to encode my go-to example of cyclic
+// structure that accesses its neighbors in drop (and thus is
+// fundamentally unsound) via this trick, but the closest I was able
+// to come was dropck_trait_cycle_checked.rs, which is not quite as
+// "good" as this regression test because the encoding of that example
+// was forced to attach a lifetime to the trait definition itself
+// (`trait Obj<'a>`) while *this* example is solely
+
+use std::cell::RefCell;
+
+trait Obj { }
+
+struct VecHolder {
+ v: Vec<(bool, &'static str)>,
+}
+
+impl Drop for VecHolder {
+ fn drop(&mut self) {
+ println!("Dropping Vec");
+ self.v[30].0 = false;
+ self.v[30].1 = "invalid access: VecHolder dropped already";
+ }
+}
+
+struct Container<'a> {
+ v: VecHolder,
+ d: RefCell<Vec<Box<dyn Obj+'a>>>,
+}
+
+impl<'a> Container<'a> {
+ fn new() -> Container<'a> {
+ Container {
+ d: RefCell::new(Vec::new()),
+ v: VecHolder {
+ v: vec![(true, "valid"); 100]
+ }
+ }
+ }
+
+ fn store<T: Obj+'a>(&'a self, val: T) {
+ self.d.borrow_mut().push(Box::new(val));
+ }
+}
+
+struct Test<'a> {
+ test: &'a Container<'a>,
+}
+
+impl<'a> Obj for Test<'a> { }
+impl<'a> Drop for Test<'a> {
+ fn drop(&mut self) {
+ for e in &self.test.v.v {
+ assert!(e.0, e.1);
+ }
+ }
+}
+
+fn main() {
+ let container = Container::new();
+ let test = Test{test: &container};
+ //~^ ERROR `container` does not live long enough
+ println!("container.v[30]: {:?}", container.v.v[30]);
+ container.store(test);
+}
diff --git a/src/test/ui/span/issue-25199.stderr b/src/test/ui/span/issue-25199.stderr
new file mode 100644
index 000000000..d70a4afc1
--- /dev/null
+++ b/src/test/ui/span/issue-25199.stderr
@@ -0,0 +1,15 @@
+error[E0597]: `container` does not live long enough
+ --> $DIR/issue-25199.rs:70:27
+ |
+LL | let test = Test{test: &container};
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `container` dropped here while still borrowed
+ | borrow might be used here, when `container` is dropped and runs the destructor for type `Container<'_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue-26656.rs b/src/test/ui/span/issue-26656.rs
new file mode 100644
index 000000000..cde68da18
--- /dev/null
+++ b/src/test/ui/span/issue-26656.rs
@@ -0,0 +1,42 @@
+// Issue #26656: Verify that trait objects cannot bypass dropck.
+
+// Using this instead of Fn etc. to take HRTB out of the equation.
+trait Trigger<B> { fn fire(&self, b: &mut B); }
+impl<B: Button> Trigger<B> for () {
+ fn fire(&self, b: &mut B) {
+ b.push();
+ }
+}
+
+// Still unsound Zook
+trait Button { fn push(&self); }
+struct Zook<B> { button: B, trigger: Box<dyn Trigger<B>+'static> }
+
+impl<B> Drop for Zook<B> {
+ fn drop(&mut self) {
+ self.trigger.fire(&mut self.button);
+ }
+}
+
+// AND
+struct Bomb { usable: bool }
+impl Drop for Bomb { fn drop(&mut self) { self.usable = false; } }
+impl Bomb { fn activate(&self) { assert!(self.usable) } }
+
+enum B<'a> { HarmlessButton, BigRedButton(&'a Bomb) }
+impl<'a> Button for B<'a> {
+ fn push(&self) {
+ if let B::BigRedButton(borrowed) = *self {
+ borrowed.activate();
+ }
+ }
+}
+
+fn main() {
+ let (mut zook, ticking);
+ zook = Zook { button: B::HarmlessButton,
+ trigger: Box::new(()) };
+ ticking = Bomb { usable: true };
+ zook.button = B::BigRedButton(&ticking);
+}
+//~^^ ERROR `ticking` does not live long enough
diff --git a/src/test/ui/span/issue-26656.stderr b/src/test/ui/span/issue-26656.stderr
new file mode 100644
index 000000000..1e939c484
--- /dev/null
+++ b/src/test/ui/span/issue-26656.stderr
@@ -0,0 +1,16 @@
+error[E0597]: `ticking` does not live long enough
+ --> $DIR/issue-26656.rs:40:35
+ |
+LL | zook.button = B::BigRedButton(&ticking);
+ | ^^^^^^^^ borrowed value does not live long enough
+LL | }
+ | -
+ | |
+ | `ticking` dropped here while still borrowed
+ | borrow might be used here, when `zook` is dropped and runs the `Drop` code for type `Zook`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue-27522.rs b/src/test/ui/span/issue-27522.rs
new file mode 100644
index 000000000..7a0cfb679
--- /dev/null
+++ b/src/test/ui/span/issue-27522.rs
@@ -0,0 +1,9 @@
+// Point at correct span for self type
+
+struct SomeType {}
+
+trait Foo {
+ fn handler(self: &SomeType); //~ ERROR invalid `self` parameter type
+}
+
+fn main() {}
diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr
new file mode 100644
index 000000000..8a254a968
--- /dev/null
+++ b/src/test/ui/span/issue-27522.stderr
@@ -0,0 +1,12 @@
+error[E0307]: invalid `self` parameter type: &SomeType
+ --> $DIR/issue-27522.rs:6:22
+ |
+LL | fn handler(self: &SomeType);
+ | ^^^^^^^^^
+ |
+ = note: type of `self` must be `Self` or a type that dereferences to it
+ = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0307`.
diff --git a/src/test/ui/span/issue-29106.rs b/src/test/ui/span/issue-29106.rs
new file mode 100644
index 000000000..1be8d4cba
--- /dev/null
+++ b/src/test/ui/span/issue-29106.rs
@@ -0,0 +1,26 @@
+use std::rc::Rc;
+use std::sync::Arc;
+
+struct Foo<'a>(&'a String);
+
+impl<'a> Drop for Foo<'a> {
+ fn drop(&mut self) {
+ println!("{:?}", self.0);
+ }
+}
+
+fn main() {
+ {
+ let (y, x);
+ x = "alive".to_string();
+ y = Arc::new(Foo(&x));
+ }
+ //~^^ ERROR `x` does not live long enough
+
+ {
+ let (y, x);
+ x = "alive".to_string();
+ y = Rc::new(Foo(&x));
+ }
+ //~^^ ERROR `x` does not live long enough
+}
diff --git a/src/test/ui/span/issue-29106.stderr b/src/test/ui/span/issue-29106.stderr
new file mode 100644
index 000000000..71fbd60ee
--- /dev/null
+++ b/src/test/ui/span/issue-29106.stderr
@@ -0,0 +1,29 @@
+error[E0597]: `x` does not live long enough
+ --> $DIR/issue-29106.rs:16:26
+ |
+LL | y = Arc::new(Foo(&x));
+ | ^^ borrowed value does not live long enough
+LL | }
+ | -
+ | |
+ | `x` dropped here while still borrowed
+ | borrow might be used here, when `y` is dropped and runs the `Drop` code for type `Arc`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `x` does not live long enough
+ --> $DIR/issue-29106.rs:23:25
+ |
+LL | y = Rc::new(Foo(&x));
+ | ^^ borrowed value does not live long enough
+LL | }
+ | -
+ | |
+ | `x` dropped here while still borrowed
+ | borrow might be used here, when `y` is dropped and runs the `Drop` code for type `Rc`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue-29595.rs b/src/test/ui/span/issue-29595.rs
new file mode 100644
index 000000000..87d7c4cfd
--- /dev/null
+++ b/src/test/ui/span/issue-29595.rs
@@ -0,0 +1,7 @@
+trait Tr {
+ const C: Self;
+}
+
+fn main() {
+ let a: u8 = Tr::C; //~ ERROR the trait bound `u8: Tr` is not satisfied
+}
diff --git a/src/test/ui/span/issue-29595.stderr b/src/test/ui/span/issue-29595.stderr
new file mode 100644
index 000000000..92445e407
--- /dev/null
+++ b/src/test/ui/span/issue-29595.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `u8: Tr` is not satisfied
+ --> $DIR/issue-29595.rs:6:17
+ |
+LL | let a: u8 = Tr::C;
+ | ^^^^^ the trait `Tr` is not implemented for `u8`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/span/issue-33884.rs b/src/test/ui/span/issue-33884.rs
new file mode 100644
index 000000000..5d927a5ac
--- /dev/null
+++ b/src/test/ui/span/issue-33884.rs
@@ -0,0 +1,18 @@
+use std::net::TcpListener;
+use std::net::TcpStream;
+use std::io::{self, Read, Write};
+
+fn handle_client(stream: TcpStream) -> io::Result<()> {
+ stream.write_fmt(format!("message received"))
+ //~^ ERROR mismatched types
+}
+
+fn main() {
+ if let Ok(listener) = TcpListener::bind("127.0.0.1:8080") {
+ for incoming in listener.incoming() {
+ if let Ok(stream) = incoming {
+ handle_client(stream);
+ }
+ }
+ }
+}
diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr
new file mode 100644
index 000000000..aee153085
--- /dev/null
+++ b/src/test/ui/span/issue-33884.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-33884.rs:6:22
+ |
+LL | stream.write_fmt(format!("message received"))
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Arguments`, found struct `String`
+ |
+ = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/span/issue-34264.rs b/src/test/ui/span/issue-34264.rs
new file mode 100644
index 000000000..5b8fc7138
--- /dev/null
+++ b/src/test/ui/span/issue-34264.rs
@@ -0,0 +1,11 @@
+fn foo(Option<i32>, String) {} //~ ERROR expected one of
+//~^ ERROR expected one of
+fn bar(x, y: usize) {} //~ ERROR expected one of
+
+fn main() {
+ foo(Some(42), 2);
+ foo(Some(42), 2, ""); //~ ERROR this function takes
+ bar("", ""); //~ ERROR mismatched types
+ bar(1, 2);
+ bar(1, 2, 3); //~ ERROR this function takes
+}
diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr
new file mode 100644
index 000000000..e676d7372
--- /dev/null
+++ b/src/test/ui/span/issue-34264.stderr
@@ -0,0 +1,102 @@
+error: expected one of `:`, `@`, or `|`, found `<`
+ --> $DIR/issue-34264.rs:1:14
+ |
+LL | fn foo(Option<i32>, String) {}
+ | ^ expected one of `:`, `@`, or `|`
+ |
+ = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+ |
+LL | fn foo(self: Option<i32>, String) {}
+ | +++++
+help: if this is a type, explicitly ignore the parameter name
+ |
+LL | fn foo(_: Option<i32>, String) {}
+ | ++
+
+error: expected one of `:`, `@`, or `|`, found `)`
+ --> $DIR/issue-34264.rs:1:27
+ |
+LL | fn foo(Option<i32>, String) {}
+ | ^ expected one of `:`, `@`, or `|`
+ |
+ = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a parameter name, give it a type
+ |
+LL | fn foo(Option<i32>, String: TypeName) {}
+ | ++++++++++
+help: if this is a type, explicitly ignore the parameter name
+ |
+LL | fn foo(Option<i32>, _: String) {}
+ | ++
+
+error: expected one of `:`, `@`, or `|`, found `,`
+ --> $DIR/issue-34264.rs:3:9
+ |
+LL | fn bar(x, y: usize) {}
+ | ^ expected one of `:`, `@`, or `|`
+ |
+ = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+ |
+LL | fn bar(self: x, y: usize) {}
+ | +++++
+help: if this is a parameter name, give it a type
+ |
+LL | fn bar(x: TypeName, y: usize) {}
+ | ++++++++++
+help: if this is a type, explicitly ignore the parameter name
+ |
+LL | fn bar(_: x, y: usize) {}
+ | ++
+
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+ --> $DIR/issue-34264.rs:7:5
+ |
+LL | foo(Some(42), 2, "");
+ | ^^^ -- argument of type `&'static str` unexpected
+ |
+note: function defined here
+ --> $DIR/issue-34264.rs:1:4
+ |
+LL | fn foo(Option<i32>, String) {}
+ | ^^^ ----------- ------
+help: remove the extra argument
+ |
+LL | foo(Some(42), 2);
+ | ~~~~~~~~~~~~~~~~
+
+error[E0308]: mismatched types
+ --> $DIR/issue-34264.rs:8:13
+ |
+LL | bar("", "");
+ | --- ^^ expected `usize`, found `&str`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/issue-34264.rs:3:4
+ |
+LL | fn bar(x, y: usize) {}
+ | ^^^ - --------
+
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+ --> $DIR/issue-34264.rs:10:5
+ |
+LL | bar(1, 2, 3);
+ | ^^^ - argument of type `{integer}` unexpected
+ |
+note: function defined here
+ --> $DIR/issue-34264.rs:3:4
+ |
+LL | fn bar(x, y: usize) {}
+ | ^^^ - --------
+help: remove the extra argument
+ |
+LL | bar(1, 2);
+ | ~~~~~~~~~
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/span/issue-35987.rs b/src/test/ui/span/issue-35987.rs
new file mode 100644
index 000000000..3a6e6ffe2
--- /dev/null
+++ b/src/test/ui/span/issue-35987.rs
@@ -0,0 +1,14 @@
+struct Foo<T: Clone>(T);
+
+use std::ops::Add;
+
+impl<T: Clone, Add> Add for Foo<T> {
+//~^ ERROR expected trait, found type parameter
+ type Output = usize;
+
+ fn add(self, rhs: Self) -> Self::Output {
+ unimplemented!();
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr
new file mode 100644
index 000000000..2bc3ff4c3
--- /dev/null
+++ b/src/test/ui/span/issue-35987.stderr
@@ -0,0 +1,14 @@
+error[E0404]: expected trait, found type parameter `Add`
+ --> $DIR/issue-35987.rs:5:21
+ |
+LL | impl<T: Clone, Add> Add for Foo<T> {
+ | ^^^ not a trait
+ |
+help: consider importing this trait instead
+ |
+LL | use std::ops::Add;
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0404`.
diff --git a/src/test/ui/span/issue-36530.rs b/src/test/ui/span/issue-36530.rs
new file mode 100644
index 000000000..70e04bf7e
--- /dev/null
+++ b/src/test/ui/span/issue-36530.rs
@@ -0,0 +1,12 @@
+// gate-test-custom_inner_attributes
+
+#![feature(register_attr)]
+
+#![register_attr(foo)]
+
+#[foo]
+mod foo {
+ #![foo] //~ ERROR custom inner attributes are unstable
+}
+
+fn main() {}
diff --git a/src/test/ui/span/issue-36530.stderr b/src/test/ui/span/issue-36530.stderr
new file mode 100644
index 000000000..a998d7217
--- /dev/null
+++ b/src/test/ui/span/issue-36530.stderr
@@ -0,0 +1,12 @@
+error[E0658]: custom inner attributes are unstable
+ --> $DIR/issue-36530.rs:9:8
+ |
+LL | #![foo]
+ | ^^^
+ |
+ = note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
+ = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/span/issue-36537.rs b/src/test/ui/span/issue-36537.rs
new file mode 100644
index 000000000..a5546ccbb
--- /dev/null
+++ b/src/test/ui/span/issue-36537.rs
@@ -0,0 +1,14 @@
+fn main() {
+ let p;
+ {
+ let a = 42;
+ p = &a;
+ //~^ ERROR `a` does not live long enough
+
+ }
+ p.use_ref();
+
+}
+
+trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } }
+impl<T> Fake for T { }
diff --git a/src/test/ui/span/issue-36537.stderr b/src/test/ui/span/issue-36537.stderr
new file mode 100644
index 000000000..79a0ebaeb
--- /dev/null
+++ b/src/test/ui/span/issue-36537.stderr
@@ -0,0 +1,14 @@
+error[E0597]: `a` does not live long enough
+ --> $DIR/issue-36537.rs:5:13
+ |
+LL | p = &a;
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | - `a` dropped here while still borrowed
+LL | p.use_ref();
+ | ----------- borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue-37767.rs b/src/test/ui/span/issue-37767.rs
new file mode 100644
index 000000000..9e34c2c1f
--- /dev/null
+++ b/src/test/ui/span/issue-37767.rs
@@ -0,0 +1,41 @@
+trait A {
+ fn foo(&mut self) {}
+}
+
+trait B : A {
+ fn foo(&mut self) {}
+}
+
+fn bar<T: B>(a: &T) {
+ a.foo() //~ ERROR multiple applicable items
+}
+
+trait C {
+ fn foo(&self) {}
+}
+
+trait D : C {
+ fn foo(&self) {}
+}
+
+fn quz<T: D>(a: &T) {
+ a.foo() //~ ERROR multiple applicable items
+}
+
+trait E : Sized {
+ fn foo(self) {}
+}
+
+trait F : E {
+ fn foo(self) {}
+}
+
+fn foo<T: F>(a: T) {
+ a.foo() //~ ERROR multiple applicable items
+}
+
+fn pass<T: C>(a: &T) {
+ a.foo()
+}
+
+fn main() {}
diff --git a/src/test/ui/span/issue-37767.stderr b/src/test/ui/span/issue-37767.stderr
new file mode 100644
index 000000000..f7732847a
--- /dev/null
+++ b/src/test/ui/span/issue-37767.stderr
@@ -0,0 +1,78 @@
+error[E0034]: multiple applicable items in scope
+ --> $DIR/issue-37767.rs:10:7
+ |
+LL | a.foo()
+ | ^^^ multiple `foo` found
+ |
+note: candidate #1 is defined in the trait `A`
+ --> $DIR/issue-37767.rs:2:5
+ |
+LL | fn foo(&mut self) {}
+ | ^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in the trait `B`
+ --> $DIR/issue-37767.rs:6:5
+ |
+LL | fn foo(&mut self) {}
+ | ^^^^^^^^^^^^^^^^^
+help: disambiguate the associated function for candidate #1
+ |
+LL | A::foo(&a)
+ | ~~~~~~~~~~
+help: disambiguate the associated function for candidate #2
+ |
+LL | B::foo(&a)
+ | ~~~~~~~~~~
+
+error[E0034]: multiple applicable items in scope
+ --> $DIR/issue-37767.rs:22:7
+ |
+LL | a.foo()
+ | ^^^ multiple `foo` found
+ |
+note: candidate #1 is defined in the trait `C`
+ --> $DIR/issue-37767.rs:14:5
+ |
+LL | fn foo(&self) {}
+ | ^^^^^^^^^^^^^
+note: candidate #2 is defined in the trait `D`
+ --> $DIR/issue-37767.rs:18:5
+ |
+LL | fn foo(&self) {}
+ | ^^^^^^^^^^^^^
+help: disambiguate the associated function for candidate #1
+ |
+LL | C::foo(&a)
+ | ~~~~~~~~~~
+help: disambiguate the associated function for candidate #2
+ |
+LL | D::foo(&a)
+ | ~~~~~~~~~~
+
+error[E0034]: multiple applicable items in scope
+ --> $DIR/issue-37767.rs:34:7
+ |
+LL | a.foo()
+ | ^^^ multiple `foo` found
+ |
+note: candidate #1 is defined in the trait `E`
+ --> $DIR/issue-37767.rs:26:5
+ |
+LL | fn foo(self) {}
+ | ^^^^^^^^^^^^
+note: candidate #2 is defined in the trait `F`
+ --> $DIR/issue-37767.rs:30:5
+ |
+LL | fn foo(self) {}
+ | ^^^^^^^^^^^^
+help: disambiguate the associated function for candidate #1
+ |
+LL | E::foo(a)
+ | ~~~~~~~~~
+help: disambiguate the associated function for candidate #2
+ |
+LL | F::foo(a)
+ | ~~~~~~~~~
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0034`.
diff --git a/src/test/ui/span/issue-39018.rs b/src/test/ui/span/issue-39018.rs
new file mode 100644
index 000000000..b6db4008d
--- /dev/null
+++ b/src/test/ui/span/issue-39018.rs
@@ -0,0 +1,38 @@
+pub fn main() {
+ let x = "Hello " + "World!";
+ //~^ ERROR cannot add
+
+ // Make sure that the span outputs a warning
+ // for not having an implementation for std::ops::Add
+ // that won't output for the above string concatenation
+ let y = World::Hello + World::Goodbye;
+ //~^ ERROR cannot add
+
+ let x = "Hello " + "World!".to_owned();
+ //~^ ERROR cannot add
+}
+
+enum World {
+ Hello,
+ Goodbye,
+}
+
+fn foo() {
+ let a = String::new();
+ let b = String::new();
+ let c = "";
+ let d = "";
+ let e = &a;
+ let _ = &a + &b; //~ ERROR cannot add
+ let _ = &a + b; //~ ERROR cannot add
+ let _ = a + &b; // ok
+ let _ = a + b; //~ ERROR mismatched types
+ let _ = e + b; //~ ERROR cannot add
+ let _ = e + &b; //~ ERROR cannot add
+ let _ = e + d; //~ ERROR cannot add
+ let _ = e + &d; //~ ERROR cannot add
+ let _ = &c + &d; //~ ERROR cannot add
+ let _ = &c + d; //~ ERROR cannot add
+ let _ = c + &d; //~ ERROR cannot add
+ let _ = c + d; //~ ERROR cannot add
+}
diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr
new file mode 100644
index 000000000..eea94643e
--- /dev/null
+++ b/src/test/ui/span/issue-39018.stderr
@@ -0,0 +1,197 @@
+error[E0369]: cannot add `&str` to `&str`
+ --> $DIR/issue-39018.rs:2:22
+ |
+LL | let x = "Hello " + "World!";
+ | -------- ^ -------- &str
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &str
+ |
+ = note: string concatenation requires an owned `String` on the left
+help: create an owned `String` from a string reference
+ |
+LL | let x = "Hello ".to_owned() + "World!";
+ | +++++++++++
+
+error[E0369]: cannot add `World` to `World`
+ --> $DIR/issue-39018.rs:8:26
+ |
+LL | let y = World::Hello + World::Goodbye;
+ | ------------ ^ -------------- World
+ | |
+ | World
+ |
+note: an implementation of `Add<_>` might be missing for `World`
+ --> $DIR/issue-39018.rs:15:1
+ |
+LL | enum World {
+ | ^^^^^^^^^^ must implement `Add<_>`
+note: the following trait must be implemented
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ |
+LL | pub trait Add<Rhs = Self> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0369]: cannot add `String` to `&str`
+ --> $DIR/issue-39018.rs:11:22
+ |
+LL | let x = "Hello " + "World!".to_owned();
+ | -------- ^ ------------------- String
+ | | |
+ | | `+` cannot be used to concatenate a `&str` with a `String`
+ | &str
+ |
+help: create an owned `String` on the left and add a borrow on the right
+ |
+LL | let x = "Hello ".to_owned() + &"World!".to_owned();
+ | +++++++++++ +
+
+error[E0369]: cannot add `&String` to `&String`
+ --> $DIR/issue-39018.rs:26:16
+ |
+LL | let _ = &a + &b;
+ | -- ^ -- &String
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &String
+ |
+ = note: string concatenation requires an owned `String` on the left
+help: remove the borrow to obtain an owned `String`
+ |
+LL - let _ = &a + &b;
+LL + let _ = a + &b;
+ |
+
+error[E0369]: cannot add `String` to `&String`
+ --> $DIR/issue-39018.rs:27:16
+ |
+LL | let _ = &a + b;
+ | -- ^ - String
+ | | |
+ | | `+` cannot be used to concatenate a `&str` with a `String`
+ | &String
+ |
+help: remove the borrow on the left and add one on the right
+ |
+LL - let _ = &a + b;
+LL + let _ = a + &b;
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/issue-39018.rs:29:17
+ |
+LL | let _ = a + b;
+ | ^
+ | |
+ | expected `&str`, found struct `String`
+ | help: consider borrowing here: `&b`
+
+error[E0369]: cannot add `String` to `&String`
+ --> $DIR/issue-39018.rs:30:15
+ |
+LL | let _ = e + b;
+ | - ^ - String
+ | | |
+ | | `+` cannot be used to concatenate a `&str` with a `String`
+ | &String
+ |
+help: create an owned `String` on the left and add a borrow on the right
+ |
+LL | let _ = e.to_owned() + &b;
+ | +++++++++++ +
+
+error[E0369]: cannot add `&String` to `&String`
+ --> $DIR/issue-39018.rs:31:15
+ |
+LL | let _ = e + &b;
+ | - ^ -- &String
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &String
+ |
+ = note: string concatenation requires an owned `String` on the left
+help: create an owned `String` from a string reference
+ |
+LL | let _ = e.to_owned() + &b;
+ | +++++++++++
+
+error[E0369]: cannot add `&str` to `&String`
+ --> $DIR/issue-39018.rs:32:15
+ |
+LL | let _ = e + d;
+ | - ^ - &str
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &String
+ |
+ = note: string concatenation requires an owned `String` on the left
+help: create an owned `String` from a string reference
+ |
+LL | let _ = e.to_owned() + d;
+ | +++++++++++
+
+error[E0369]: cannot add `&&str` to `&String`
+ --> $DIR/issue-39018.rs:33:15
+ |
+LL | let _ = e + &d;
+ | - ^ -- &&str
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &String
+ |
+ = note: string concatenation requires an owned `String` on the left
+help: create an owned `String` from a string reference
+ |
+LL | let _ = e.to_owned() + &d;
+ | +++++++++++
+
+error[E0369]: cannot add `&&str` to `&&str`
+ --> $DIR/issue-39018.rs:34:16
+ |
+LL | let _ = &c + &d;
+ | -- ^ -- &&str
+ | |
+ | &&str
+
+error[E0369]: cannot add `&str` to `&&str`
+ --> $DIR/issue-39018.rs:35:16
+ |
+LL | let _ = &c + d;
+ | -- ^ - &str
+ | |
+ | &&str
+
+error[E0369]: cannot add `&&str` to `&str`
+ --> $DIR/issue-39018.rs:36:15
+ |
+LL | let _ = c + &d;
+ | - ^ -- &&str
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &str
+ |
+ = note: string concatenation requires an owned `String` on the left
+help: create an owned `String` from a string reference
+ |
+LL | let _ = c.to_owned() + &d;
+ | +++++++++++
+
+error[E0369]: cannot add `&str` to `&str`
+ --> $DIR/issue-39018.rs:37:15
+ |
+LL | let _ = c + d;
+ | - ^ - &str
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &str
+ |
+ = note: string concatenation requires an owned `String` on the left
+help: create an owned `String` from a string reference
+ |
+LL | let _ = c.to_owned() + d;
+ | +++++++++++
+
+error: aborting due to 14 previous errors
+
+Some errors have detailed explanations: E0308, E0369.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/span/issue-39698.rs b/src/test/ui/span/issue-39698.rs
new file mode 100644
index 000000000..1079bae2c
--- /dev/null
+++ b/src/test/ui/span/issue-39698.rs
@@ -0,0 +1,16 @@
+enum T {
+ T1(i32, i32),
+ T2(i32, i32),
+ T3(i32),
+ T4(i32),
+}
+
+fn main() {
+ match T::T1(123, 456) {
+ T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+ //~^ ERROR is not bound in all patterns
+ //~| ERROR is not bound in all patterns
+ //~| ERROR is not bound in all patterns
+ //~| ERROR is not bound in all patterns
+ }
+}
diff --git a/src/test/ui/span/issue-39698.stderr b/src/test/ui/span/issue-39698.stderr
new file mode 100644
index 000000000..25c35fd54
--- /dev/null
+++ b/src/test/ui/span/issue-39698.stderr
@@ -0,0 +1,43 @@
+error[E0408]: variable `d` is not bound in all patterns
+ --> $DIR/issue-39698.rs:10:37
+ |
+LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+ | - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d`
+ | | | |
+ | | | pattern doesn't bind `d`
+ | | variable not in all patterns
+ | variable not in all patterns
+
+error[E0408]: variable `a` is not bound in all patterns
+ --> $DIR/issue-39698.rs:10:23
+ |
+LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+ | - ^^^^^^^^^^^ ^^^^^^^^ - variable not in all patterns
+ | | | |
+ | | | pattern doesn't bind `a`
+ | | pattern doesn't bind `a`
+ | variable not in all patterns
+
+error[E0408]: variable `b` is not bound in all patterns
+ --> $DIR/issue-39698.rs:10:9
+ |
+LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+ | ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `b`
+ | | | |
+ | | | pattern doesn't bind `b`
+ | | variable not in all patterns
+ | pattern doesn't bind `b`
+
+error[E0408]: variable `c` is not bound in all patterns
+ --> $DIR/issue-39698.rs:10:9
+ |
+LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+ | ^^^^^^^^^^^ ^^^^^^^^^^^ - ^^^^^^^^ pattern doesn't bind `c`
+ | | | |
+ | | | variable not in all patterns
+ | | pattern doesn't bind `c`
+ | pattern doesn't bind `c`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0408`.
diff --git a/src/test/ui/span/issue-40157.rs b/src/test/ui/span/issue-40157.rs
new file mode 100644
index 000000000..03ad21ae7
--- /dev/null
+++ b/src/test/ui/span/issue-40157.rs
@@ -0,0 +1,4 @@
+fn main () {
+ {println!("{:?}", match { let foo = vec![1, 2]; foo.get(1) } { x => x });}
+ //~^ ERROR does not live long enough
+}
diff --git a/src/test/ui/span/issue-40157.stderr b/src/test/ui/span/issue-40157.stderr
new file mode 100644
index 000000000..57f80214a
--- /dev/null
+++ b/src/test/ui/span/issue-40157.stderr
@@ -0,0 +1,13 @@
+error[E0597]: `foo` does not live long enough
+ --> $DIR/issue-40157.rs:2:53
+ |
+LL | {println!("{:?}", match { let foo = vec![1, 2]; foo.get(1) } { x => x });}
+ | ------------------------^^^^^^^^^^--
+ | | | |
+ | | | `foo` dropped here while still borrowed
+ | | borrowed value does not live long enough
+ | borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr
new file mode 100644
index 000000000..2b1789908
--- /dev/null
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr
@@ -0,0 +1,27 @@
+error[E0282]: type annotations needed
+ --> $DIR/issue-42234-unknown-receiver-type.rs:9:24
+ |
+LL | let x: Option<_> = None;
+ | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
+LL | x.unwrap().method_that_could_exist_on_some_type();
+ | ---------- type must be known at this point
+ |
+help: consider specifying the generic argument
+ |
+LL | let x: Option<_> = None::<T>;
+ | +++++
+
+error[E0282]: type annotations needed
+ --> $DIR/issue-42234-unknown-receiver-type.rs:15:10
+ |
+LL | .sum::<_>()
+ | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
+ |
+help: consider specifying the generic argument
+ |
+LL | .sum::<_>()
+ | ~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr
new file mode 100644
index 000000000..d93d54e87
--- /dev/null
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr
@@ -0,0 +1,27 @@
+error[E0282]: type annotations needed
+ --> $DIR/issue-42234-unknown-receiver-type.rs:9:24
+ |
+LL | let x: Option<_> = None;
+ | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
+LL | x.unwrap().method_that_could_exist_on_some_type();
+ | ---------- type must be known at this point
+ |
+help: consider specifying the generic argument
+ |
+LL | let x: Option<_> = None::<T>;
+ | +++++
+
+error[E0282]: type annotations needed
+ --> $DIR/issue-42234-unknown-receiver-type.rs:15:10
+ |
+LL | .sum::<_>()
+ | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
+ |
+help: consider specifying the generic argument
+ |
+LL | .sum::<S>()
+ | ~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.rs b/src/test/ui/span/issue-42234-unknown-receiver-type.rs
new file mode 100644
index 000000000..fd5312120
--- /dev/null
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.rs
@@ -0,0 +1,19 @@
+// revisions: full generic_arg
+#![cfg_attr(generic_arg, feature(generic_arg_infer))]
+
+// When the type of a method call's receiver is unknown, the span should point
+// to the receiver (and not the entire call, as was previously the case before
+// the fix of which this tests).
+
+fn shines_a_beacon_through_the_darkness() {
+ let x: Option<_> = None; //~ ERROR type annotations needed
+ x.unwrap().method_that_could_exist_on_some_type();
+}
+
+fn courier_to_des_moines_and_points_west(data: &[u32]) -> String {
+ data.iter()
+ .sum::<_>() //~ ERROR type annotations needed
+ .to_string()
+}
+
+fn main() {}
diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.rs b/src/test/ui/span/issue-43927-non-ADT-derive.rs
new file mode 100644
index 000000000..935bfa001
--- /dev/null
+++ b/src/test/ui/span/issue-43927-non-ADT-derive.rs
@@ -0,0 +1,6 @@
+#![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
+//~^ ERROR cannot determine resolution for the attribute macro `derive`
+//~^^ ERROR `derive` attribute cannot be used at crate level
+struct DerivedOn;
+
+fn main() {}
diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.stderr b/src/test/ui/span/issue-43927-non-ADT-derive.stderr
new file mode 100644
index 000000000..e3ae37e36
--- /dev/null
+++ b/src/test/ui/span/issue-43927-non-ADT-derive.stderr
@@ -0,0 +1,21 @@
+error: cannot determine resolution for the attribute macro `derive`
+ --> $DIR/issue-43927-non-ADT-derive.rs:1:4
+ |
+LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
+ | ^^^^^^
+ |
+ = note: import resolution is stuck, try simplifying macro imports
+
+error: `derive` attribute cannot be used at crate level
+ --> $DIR/issue-43927-non-ADT-derive.rs:1:1
+ |
+LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: perhaps you meant to use an outer attribute
+ |
+LL | #[derive(Debug, PartialEq, Eq)] // should be an outer attribute!
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/span/issue-71363.rs b/src/test/ui/span/issue-71363.rs
new file mode 100644
index 000000000..bbb4a9362
--- /dev/null
+++ b/src/test/ui/span/issue-71363.rs
@@ -0,0 +1,19 @@
+// compile-flags: -Z simulate-remapped-rust-src-base=/rustc/xyz -Z translate-remapped-path-to-local-path=no -Z ui-testing=no
+
+struct MyError;
+impl std::error::Error for MyError {}
+//~^ ERROR: `MyError` doesn't implement `std::fmt::Display`
+//~| ERROR: `MyError` doesn't implement `Debug`
+
+fn main() {}
+
+// This test relies on library/std/src/error.rs *not* being included in the error message, so that
+// we can test whether a file not included in the error message affects it (more specifically
+// whether the line number of the excluded file affects the indentation of the other line numbers).
+//
+// To test this we're simulating a remap of the rust src base (so that library/std/src/error.rs
+// does not point to a local file) *and* we're disabling the code to try mapping a remapped path to
+// a local file (which would defeat the purpose of the former flag).
+//
+// Note that this comment is at the bottom of the file intentionally, as we need the line number of
+// the impl to be lower than 10.
diff --git a/src/test/ui/span/issue-71363.stderr b/src/test/ui/span/issue-71363.stderr
new file mode 100644
index 000000000..04e2b46c3
--- /dev/null
+++ b/src/test/ui/span/issue-71363.stderr
@@ -0,0 +1,27 @@
+error[E0277]: `MyError` doesn't implement `std::fmt::Display`
+ --> $DIR/issue-71363.rs:4:6
+ |
+4 | impl std::error::Error for MyError {}
+ | ^^^^^^^^^^^^^^^^^ `MyError` cannot be formatted with the default formatter
+ |
+ = help: the trait `std::fmt::Display` is not implemented for `MyError`
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `std::error::Error`
+
+error[E0277]: `MyError` doesn't implement `Debug`
+ --> $DIR/issue-71363.rs:4:6
+ |
+4 | impl std::error::Error for MyError {}
+ | ^^^^^^^^^^^^^^^^^ `MyError` cannot be formatted using `{:?}`
+ |
+ = help: the trait `Debug` is not implemented for `MyError`
+ = note: add `#[derive(Debug)]` to `MyError` or manually `impl Debug for MyError`
+note: required by a bound in `std::error::Error`
+help: consider annotating `MyError` with `#[derive(Debug)]`
+ |
+3 | #[derive(Debug)]
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/span/issue-7575.rs b/src/test/ui/span/issue-7575.rs
new file mode 100644
index 000000000..eddd158ae
--- /dev/null
+++ b/src/test/ui/span/issue-7575.rs
@@ -0,0 +1,75 @@
+// Test the mechanism for warning about possible missing `self` declarations.
+trait CtxtFn {
+ fn f8(self, _: usize) -> usize;
+ fn f9(_: usize) -> usize;
+}
+
+trait OtherTrait {
+ fn f9(_: usize) -> usize;
+}
+
+// Note: this trait is not implemented, but we can't really tell
+// whether or not an impl would match anyhow without a self
+// declaration to match against, so we wind up prisizeing it as a
+// candidate. This seems not unreasonable -- perhaps the user meant to
+// implement it, after all.
+trait UnusedTrait {
+ fn f9(_: usize) -> usize;
+}
+
+impl CtxtFn for usize {
+ fn f8(self, i: usize) -> usize {
+ i * 4
+ }
+
+ fn f9(i: usize) -> usize {
+ i * 4
+ }
+}
+
+impl OtherTrait for usize {
+ fn f9(i: usize) -> usize {
+ i * 8
+ }
+}
+
+struct Myisize(isize);
+
+impl Myisize {
+ fn fff(i: isize) -> isize {
+ i
+ }
+}
+
+trait ManyImplTrait {
+ fn is_str() -> bool {
+ false
+ }
+}
+
+impl ManyImplTrait for String {
+ fn is_str() -> bool {
+ true
+ }
+}
+
+impl ManyImplTrait for usize {}
+impl ManyImplTrait for isize {}
+impl ManyImplTrait for char {}
+impl ManyImplTrait for Myisize {}
+
+fn no_param_bound(u: usize, m: Myisize) -> usize {
+ u.f8(42) + u.f9(342) + m.fff(42)
+ //~^ ERROR no method named `f9` found
+ //~| ERROR no method named `fff` found
+
+
+}
+
+fn param_bound<T: ManyImplTrait>(t: T) -> bool {
+ t.is_str()
+ //~^ ERROR no method named `is_str` found
+}
+
+fn main() {
+}
diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr
new file mode 100644
index 000000000..4f30edb3f
--- /dev/null
+++ b/src/test/ui/span/issue-7575.stderr
@@ -0,0 +1,82 @@
+error[E0599]: no method named `f9` found for type `usize` in the current scope
+ --> $DIR/issue-7575.rs:62:18
+ |
+LL | u.f8(42) + u.f9(342) + m.fff(42)
+ | ^^ this is an associated function, not a method
+ |
+ = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: candidate #1 is defined in the trait `CtxtFn`
+ --> $DIR/issue-7575.rs:4:5
+ |
+LL | fn f9(_: usize) -> usize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in the trait `OtherTrait`
+ --> $DIR/issue-7575.rs:8:5
+ |
+LL | fn f9(_: usize) -> usize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #3 is defined in the trait `UnusedTrait`
+ --> $DIR/issue-7575.rs:17:5
+ |
+LL | fn f9(_: usize) -> usize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ = help: items from traits can only be used if the trait is implemented and in scope
+ = note: the following traits define an item `f9`, perhaps you need to implement one of them:
+ candidate #1: `CtxtFn`
+ candidate #2: `OtherTrait`
+ candidate #3: `UnusedTrait`
+help: disambiguate the associated function for candidate #1
+ |
+LL | u.f8(42) + <usize as CtxtFn>::f9(u, 342) + m.fff(42)
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+help: disambiguate the associated function for candidate #2
+ |
+LL | u.f8(42) + <usize as OtherTrait>::f9(u, 342) + m.fff(42)
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+help: disambiguate the associated function for candidate #3
+ |
+LL | u.f8(42) + <usize as UnusedTrait>::f9(u, 342) + m.fff(42)
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0599]: no method named `fff` found for struct `Myisize` in the current scope
+ --> $DIR/issue-7575.rs:62:30
+ |
+LL | struct Myisize(isize);
+ | -------------- method `fff` not found for this struct
+...
+LL | u.f8(42) + u.f9(342) + m.fff(42)
+ | --^^^
+ | | |
+ | | this is an associated function, not a method
+ | help: use associated function syntax instead: `Myisize::fff`
+ |
+ = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `Myisize`
+ --> $DIR/issue-7575.rs:39:5
+ |
+LL | fn fff(i: isize) -> isize {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `is_str` found for type parameter `T` in the current scope
+ --> $DIR/issue-7575.rs:70:7
+ |
+LL | fn param_bound<T: ManyImplTrait>(t: T) -> bool {
+ | - method `is_str` not found for this type parameter
+LL | t.is_str()
+ | ^^^^^^ this is an associated function, not a method
+ |
+ = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in the trait `ManyImplTrait`
+ --> $DIR/issue-7575.rs:45:5
+ |
+LL | fn is_str() -> bool {
+ | ^^^^^^^^^^^^^^^^^^^
+ = help: items from traits can only be used if the type parameter is bounded by the trait
+help: disambiguate the associated function for the candidate
+ |
+LL | <T as ManyImplTrait>::is_str(t)
+ |
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/span/issue-81800.rs b/src/test/ui/span/issue-81800.rs
new file mode 100644
index 000000000..6ac66fdcb
--- /dev/null
+++ b/src/test/ui/span/issue-81800.rs
@@ -0,0 +1,2 @@
+fn x˂- //~ ERROR: unknown start of token
+ //~^ ERROR: expected one of `#`, `>`, `const`, identifier, or lifetime, found `-`
diff --git a/src/test/ui/span/issue-81800.stderr b/src/test/ui/span/issue-81800.stderr
new file mode 100644
index 000000000..86c64573b
--- /dev/null
+++ b/src/test/ui/span/issue-81800.stderr
@@ -0,0 +1,19 @@
+error: unknown start of token: \u{2c2}
+ --> $DIR/issue-81800.rs:1:5
+ |
+LL | fn x˂-
+ | ^
+ |
+help: Unicode character '˂' (Modifier Letter Left Arrowhead) looks like '<' (Less-Than Sign), but it is not
+ |
+LL | fn x<-
+ | ~
+
+error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `-`
+ --> $DIR/issue-81800.rs:1:6
+ |
+LL | fn x˂-
+ | ^ expected one of `#`, `>`, `const`, identifier, or lifetime
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/span/issue28498-reject-ex1.rs b/src/test/ui/span/issue28498-reject-ex1.rs
new file mode 100644
index 000000000..4d1b41255
--- /dev/null
+++ b/src/test/ui/span/issue28498-reject-ex1.rs
@@ -0,0 +1,37 @@
+// Example taken from RFC 1238 text
+
+// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md
+// #examples-of-code-that-will-start-to-be-rejected
+
+// Compare against test/run-pass/issue28498-must-work-ex2.rs
+
+use std::cell::Cell;
+
+struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>);
+
+struct Foo<T> { data: Vec<T> }
+
+fn potentially_specialized_wrt_t<T>(t: &T) {
+ // Hypothetical code that does one thing for generic T and then is
+ // specialized for T == Concrete (and the specialized form can
+ // then access a reference held in concrete tuple).
+ //
+ // (We don't have specialization yet, but we want to allow for it
+ // in the future.)
+}
+
+impl<T> Drop for Foo<T> {
+ fn drop(&mut self) {
+ potentially_specialized_wrt_t(&self.data[0])
+ }
+}
+
+fn main() {
+ let mut foo = Foo { data: Vec::new() };
+ foo.data.push(Concrete(0, Cell::new(None)));
+ foo.data.push(Concrete(0, Cell::new(None)));
+
+ foo.data[0].1.set(Some(&foo.data[1]));
+ //~^ ERROR borrow may still be in use when destructor runs
+ foo.data[1].1.set(Some(&foo.data[0]));
+}
diff --git a/src/test/ui/span/issue28498-reject-ex1.stderr b/src/test/ui/span/issue28498-reject-ex1.stderr
new file mode 100644
index 000000000..86e2d8c56
--- /dev/null
+++ b/src/test/ui/span/issue28498-reject-ex1.stderr
@@ -0,0 +1,17 @@
+error[E0713]: borrow may still be in use when destructor runs
+ --> $DIR/issue28498-reject-ex1.rs:34:29
+ |
+LL | foo.data[0].1.set(Some(&foo.data[1]));
+ | ^^^^^^^^
+...
+LL | }
+ | -
+ | |
+ | here, drop of `foo` needs exclusive access to `foo.data`, because the type `Foo<Concrete<'_>>` implements the `Drop` trait
+ | borrow might be used here, when `foo` is dropped and runs the `Drop` code for type `Foo`
+ |
+ = note: consider using a `let` binding to create a longer lived value
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0713`.
diff --git a/src/test/ui/span/issue28498-reject-lifetime-param.rs b/src/test/ui/span/issue28498-reject-lifetime-param.rs
new file mode 100644
index 000000000..1e7190157
--- /dev/null
+++ b/src/test/ui/span/issue28498-reject-lifetime-param.rs
@@ -0,0 +1,36 @@
+// Demonstrate that having a lifetime param causes dropck to reject code
+// that might indirectly access previously dropped value.
+//
+// Compare with run-pass/issue28498-ugeh-with-lifetime-param.rs
+
+#[derive(Debug)]
+struct ScribbleOnDrop(String);
+
+impl Drop for ScribbleOnDrop {
+ fn drop(&mut self) {
+ self.0 = format!("DROPPED");
+ }
+}
+
+struct Foo<'a>(u32, &'a ScribbleOnDrop);
+
+impl<'a> Drop for Foo<'a> {
+ fn drop(&mut self) {
+ // Use of `may_dangle` is unsound, because destructor accesses borrowed data
+ // in `self.1` and we must force that to strictly outlive `self`.
+ println!("Dropping Foo({}, {:?})", self.0, self.1);
+ }
+}
+
+fn main() {
+ let (last_dropped, foo0);
+ let (foo1, first_dropped);
+
+ last_dropped = ScribbleOnDrop(format!("last"));
+ first_dropped = ScribbleOnDrop(format!("first"));
+ foo0 = Foo(0, &last_dropped); // OK
+ foo1 = Foo(1, &first_dropped);
+ //~^ ERROR `first_dropped` does not live long enough
+
+ println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1);
+}
diff --git a/src/test/ui/span/issue28498-reject-lifetime-param.stderr b/src/test/ui/span/issue28498-reject-lifetime-param.stderr
new file mode 100644
index 000000000..3119ddd03
--- /dev/null
+++ b/src/test/ui/span/issue28498-reject-lifetime-param.stderr
@@ -0,0 +1,17 @@
+error[E0597]: `first_dropped` does not live long enough
+ --> $DIR/issue28498-reject-lifetime-param.rs:32:19
+ |
+LL | foo1 = Foo(1, &first_dropped);
+ | ^^^^^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `first_dropped` dropped here while still borrowed
+ | borrow might be used here, when `foo1` is dropped and runs the `Drop` code for type `Foo`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue28498-reject-passed-to-fn.rs b/src/test/ui/span/issue28498-reject-passed-to-fn.rs
new file mode 100644
index 000000000..dcd2e9ad4
--- /dev/null
+++ b/src/test/ui/span/issue28498-reject-passed-to-fn.rs
@@ -0,0 +1,38 @@
+// Demonstrate that a type param in negative position causes dropck to reject code
+// that might indirectly access previously dropped value.
+//
+// Compare with run-pass/issue28498-ugeh-with-passed-to-fn.rs
+
+#[derive(Debug)]
+struct ScribbleOnDrop(String);
+
+impl Drop for ScribbleOnDrop {
+ fn drop(&mut self) {
+ self.0 = format!("DROPPED");
+ }
+}
+
+struct Foo<T>(u32, T, Box<for <'r> fn(&'r T) -> String>);
+
+impl<T> Drop for Foo<T> {
+ fn drop(&mut self) {
+ // Use of `may_dangle` is unsound, because we pass `T` to the callback in `self.2`
+ // below, and thus potentially read from borrowed data.
+ println!("Dropping Foo({}, {})", self.0, (self.2)(&self.1));
+ }
+}
+
+fn callback(s: & &ScribbleOnDrop) -> String { format!("{:?}", s) }
+
+fn main() {
+ let (last_dropped, foo0);
+ let (foo1, first_dropped);
+
+ last_dropped = ScribbleOnDrop(format!("last"));
+ first_dropped = ScribbleOnDrop(format!("first"));
+ foo0 = Foo(0, &last_dropped, Box::new(callback)); // OK
+ foo1 = Foo(1, &first_dropped, Box::new(callback));
+ //~^ ERROR `first_dropped` does not live long enough
+
+ println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1);
+}
diff --git a/src/test/ui/span/issue28498-reject-passed-to-fn.stderr b/src/test/ui/span/issue28498-reject-passed-to-fn.stderr
new file mode 100644
index 000000000..60e8a648c
--- /dev/null
+++ b/src/test/ui/span/issue28498-reject-passed-to-fn.stderr
@@ -0,0 +1,17 @@
+error[E0597]: `first_dropped` does not live long enough
+ --> $DIR/issue28498-reject-passed-to-fn.rs:34:19
+ |
+LL | foo1 = Foo(1, &first_dropped, Box::new(callback));
+ | ^^^^^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `first_dropped` dropped here while still borrowed
+ | borrow might be used here, when `foo1` is dropped and runs the `Drop` code for type `Foo`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/issue28498-reject-trait-bound.rs b/src/test/ui/span/issue28498-reject-trait-bound.rs
new file mode 100644
index 000000000..444cebb19
--- /dev/null
+++ b/src/test/ui/span/issue28498-reject-trait-bound.rs
@@ -0,0 +1,38 @@
+// Demonstrate that having a trait bound causes dropck to reject code
+// that might indirectly access previously dropped value.
+//
+// Compare with run-pass/issue28498-ugeh-with-trait-bound.rs
+
+use std::fmt;
+
+#[derive(Debug)]
+struct ScribbleOnDrop(String);
+
+impl Drop for ScribbleOnDrop {
+ fn drop(&mut self) {
+ self.0 = format!("DROPPED");
+ }
+}
+
+struct Foo<T: fmt::Debug>(u32, T);
+
+impl<T: fmt::Debug> Drop for Foo<T> {
+ fn drop(&mut self) {
+ // Use of `may_dangle` is unsound, because we access `T` fmt method when we pass
+ // `self.1` below, and thus potentially read from borrowed data.
+ println!("Dropping Foo({}, {:?})", self.0, self.1);
+ }
+}
+
+fn main() {
+ let (last_dropped, foo0);
+ let (foo1, first_dropped);
+
+ last_dropped = ScribbleOnDrop(format!("last"));
+ first_dropped = ScribbleOnDrop(format!("first"));
+ foo0 = Foo(0, &last_dropped); // OK
+ foo1 = Foo(1, &first_dropped);
+ //~^ ERROR `first_dropped` does not live long enough
+
+ println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1);
+}
diff --git a/src/test/ui/span/issue28498-reject-trait-bound.stderr b/src/test/ui/span/issue28498-reject-trait-bound.stderr
new file mode 100644
index 000000000..22e4a8205
--- /dev/null
+++ b/src/test/ui/span/issue28498-reject-trait-bound.stderr
@@ -0,0 +1,17 @@
+error[E0597]: `first_dropped` does not live long enough
+ --> $DIR/issue28498-reject-trait-bound.rs:34:19
+ |
+LL | foo1 = Foo(1, &first_dropped);
+ | ^^^^^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `first_dropped` dropped here while still borrowed
+ | borrow might be used here, when `foo1` is dropped and runs the `Drop` code for type `Foo`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/lint-unused-unsafe-thir.rs b/src/test/ui/span/lint-unused-unsafe-thir.rs
new file mode 100644
index 000000000..95a537ed2
--- /dev/null
+++ b/src/test/ui/span/lint-unused-unsafe-thir.rs
@@ -0,0 +1,61 @@
+// FIXME: This file is tracking old lint behavior that's still unchanged in the
+// unstable -Zthir-unsafeck implementation. See lint-unused-unsafe.rs for more details.
+//
+// Exercise the unused_unsafe attribute in some positive and negative cases
+
+// compile-flags: -Zthir-unsafeck
+
+#![allow(dead_code)]
+#![deny(unused_unsafe)]
+
+
+mod foo {
+ extern "C" {
+ pub fn bar();
+ }
+}
+
+fn callback<T, F>(_f: F) -> T where F: FnOnce() -> T { panic!() }
+unsafe fn unsf() {}
+
+fn bad1() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
+fn bad2() { unsafe { bad1() } } //~ ERROR: unnecessary `unsafe` block
+unsafe fn bad3() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
+fn bad4() { unsafe { callback(||{}) } } //~ ERROR: unnecessary `unsafe` block
+unsafe fn bad5() { unsafe { unsf() } } //~ ERROR: unnecessary `unsafe` block
+fn bad6() {
+ unsafe { // don't put the warning here
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf()
+ }
+ }
+}
+unsafe fn bad7() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf()
+ }
+ }
+}
+
+unsafe fn good0() { unsf() }
+fn good1() { unsafe { unsf() } }
+fn good2() {
+ /* bug uncovered when implementing warning about unused unsafe blocks. Be
+ sure that when purity is inherited that the source of the unsafe-ness
+ is tracked correctly */
+ unsafe {
+ unsafe fn what() -> Vec<String> { panic!() }
+
+ callback(|| {
+ what();
+ });
+ }
+}
+
+unsafe fn good3() { foo::bar() }
+fn good4() { unsafe { foo::bar() } }
+
+#[allow(unused_unsafe)] fn allowed() { unsafe {} }
+
+fn main() {}
diff --git a/src/test/ui/span/lint-unused-unsafe-thir.stderr b/src/test/ui/span/lint-unused-unsafe-thir.stderr
new file mode 100644
index 000000000..6654910c5
--- /dev/null
+++ b/src/test/ui/span/lint-unused-unsafe-thir.stderr
@@ -0,0 +1,66 @@
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe-thir.rs:21:13
+ |
+LL | fn bad1() { unsafe {} }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe-thir.rs:9:9
+ |
+LL | #![deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe-thir.rs:22:13
+ |
+LL | fn bad2() { unsafe { bad1() } }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe-thir.rs:23:20
+ |
+LL | unsafe fn bad3() { unsafe {} }
+ | ---------------- ^^^^^^ unnecessary `unsafe` block
+ | |
+ | because it's nested under this `unsafe` fn
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe-thir.rs:24:13
+ |
+LL | fn bad4() { unsafe { callback(||{}) } }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe-thir.rs:25:20
+ |
+LL | unsafe fn bad5() { unsafe { unsf() } }
+ | ---------------- ^^^^^^ unnecessary `unsafe` block
+ | |
+ | because it's nested under this `unsafe` fn
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe-thir.rs:28:9
+ |
+LL | unsafe { // don't put the warning here
+ | ------ because it's nested under this `unsafe` block
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe-thir.rs:35:9
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe-thir.rs:34:5
+ |
+LL | unsafe fn bad7() {
+ | ---------------- because it's nested under this `unsafe` fn
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/span/lint-unused-unsafe.mir.stderr b/src/test/ui/span/lint-unused-unsafe.mir.stderr
new file mode 100644
index 000000000..850550a1d
--- /dev/null
+++ b/src/test/ui/span/lint-unused-unsafe.mir.stderr
@@ -0,0 +1,1824 @@
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:26:13
+ |
+LL | fn bad1() { unsafe {} }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:14:9
+ |
+LL | #![deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:27:13
+ |
+LL | fn bad2() { unsafe { bad1() } }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:28:20
+ |
+LL | unsafe fn bad3() { unsafe {} }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:29:13
+ |
+LL | fn bad4() { unsafe { callback(||{}) } }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:30:20
+ |
+LL | unsafe fn bad5() { unsafe { unsf() } }
+ | ---------------- ^^^^^^ unnecessary `unsafe` block
+ | |
+ | because it's nested under this `unsafe` fn
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+ = note: `#[allow(unsafe_op_in_unsafe_fn)]` on by default
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:32:5
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:39:5
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:40:9
+ |
+LL | unsafe fn bad7() {
+ | ---------------- because it's nested under this `unsafe` fn
+LL | unsafe {
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:74:9
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:83:9
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:84:13
+ |
+LL | unsafe {}
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:85:13
+ |
+LL | unsafe {}
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:90:9
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:100:13
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsf();
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:101:13
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:102:13
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:112:17
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:110:20
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:113:17
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:114:17
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:124:9
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:134:9
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:135:13
+ |
+LL | unsafe {}
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:136:13
+ |
+LL | unsafe {}
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:142:9
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:153:13
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsf();
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:154:13
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:155:13
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:166:17
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:164:20
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:167:17
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:168:17
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:178:9
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:188:9
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:189:13
+ |
+LL | unsafe {}
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:190:13
+ |
+LL | unsafe {}
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:196:9
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:197:13
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+LL | unsafe {
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:194:13
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:198:13
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:199:13
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:205:9
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:203:13
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:207:13
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:208:13
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:209:13
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:220:17
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:218:20
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:221:17
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:222:17
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | unsafe { unsf() }
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:242:9
+ |
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:254:9
+ |
+LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+ | ----------------------------------------------- because it's nested under this `unsafe` fn
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:252:13
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:268:13
+ |
+LL | unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:286:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:295:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:296:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:297:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:302:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:312:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsf();
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:313:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:314:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:324:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:322:20
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:325:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:326:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:336:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:346:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:347:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:348:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:354:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:365:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsf();
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:366:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:367:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:378:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:376:20
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:379:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:380:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:390:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:400:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:401:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:402:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:408:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:409:24
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:406:13
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:410:24
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:411:24
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:417:20
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:415:13
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:419:24
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:420:24
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:421:24
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:432:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:430:20
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:433:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:434:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:454:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:466:20
+ |
+LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+ | ----------------------------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:464:13
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:480:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:499:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:508:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:509:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:510:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:515:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:525:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsf();
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:526:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:527:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:537:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:535:20
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:538:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:539:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:549:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:559:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:560:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:561:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:567:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:578:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsf();
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:579:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:580:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:591:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:589:20
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:592:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:593:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:603:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:613:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:614:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:615:24
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:621:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:622:24
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:619:13
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:623:24
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:624:24
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:630:20
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:628:13
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:632:24
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:633:24
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:634:24
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:645:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:643:20
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:646:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:647:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { let _ = || unsf(); };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:667:20
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:679:20
+ |
+LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+ | ----------------------------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:677:13
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:693:24
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:711:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:721:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:722:28
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:723:28
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:729:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:740:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsf();
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:741:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:742:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:753:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:751:24
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:754:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:755:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:765:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:775:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:776:28
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:777:28
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:783:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:784:28
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:781:17
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:785:28
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:786:28
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:792:24
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:790:17
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:794:28
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:795:28
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:796:28
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:807:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:805:24
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:808:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:809:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:829:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:841:24
+ |
+LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+ | ----------------------------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:839:17
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:855:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:869:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:879:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:880:28
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:881:28
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:887:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:898:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | unsf();
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:899:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:900:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:911:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:909:24
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:912:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:913:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:923:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:933:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:934:28
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:935:28
+ |
+LL | let _ = || unsafe {};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:941:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:942:28
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:939:17
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:943:28
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:944:28
+ |
+LL | unsafe fn granularity_2() {
+ | ------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:950:24
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:948:17
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:952:28
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:953:28
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:954:28
+ |
+LL | unsafe fn top_level_used_2() {
+ | ---------------------------- because it's nested under this `unsafe` fn
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:965:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:963:24
+ |
+LL | #[deny(unused_unsafe)]
+ | ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:966:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:967:32
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = || unsafe { unsf() };
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:987:24
+ |
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:999:24
+ |
+LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+ | ----------------------------------------------- because it's nested under this `unsafe` fn
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:997:17
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1013:28
+ |
+LL | let _ = || unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = || unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1044:9
+ |
+LL | unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() {
+ | -------------------------------------------------- because it's nested under this `unsafe` fn
+LL | unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:1045:21
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1059:29
+ |
+LL | let _ = async { unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1066:33
+ |
+LL | let _ = async { unsafe {
+ | ------ because it's nested under this `unsafe` block
+LL | let _ = async { unsf() };
+LL | let _ = async { unsafe { let _ = async { unsf() }; }};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1067:33
+ |
+LL | let _ = async { unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = async { unsafe { let _ = async { unsf() }; }};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1068:33
+ |
+LL | let _ = async { unsafe {
+ | ------ because it's nested under this `unsafe` block
+...
+LL | let _ = async { unsafe { let _ = async { unsf() }; }};
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1073:29
+ |
+LL | let _ = async { unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1074:33
+ |
+LL | async unsafe fn async_blocks() {
+ | ------------------------------ because it's nested under this `unsafe` fn
+...
+LL | let _ = async { unsafe { let _ = async { unsf() }; }};
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+ --> $DIR/lint-unused-unsafe.rs:1071:17
+ |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1075:33
+ |
+LL | async unsafe fn async_blocks() {
+ | ------------------------------ because it's nested under this `unsafe` fn
+...
+LL | let _ = async { unsafe { let _ = async { unsf() }; }};
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1076:33
+ |
+LL | async unsafe fn async_blocks() {
+ | ------------------------------ because it's nested under this `unsafe` fn
+...
+LL | let _ = async { unsafe { let _ = async { unsf() }; }};
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1078:29
+ |
+LL | async unsafe fn async_blocks() {
+ | ------------------------------ because it's nested under this `unsafe` fn
+...
+LL | let _ = async { unsafe {
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1080:33
+ |
+LL | async unsafe fn async_blocks() {
+ | ------------------------------ because it's nested under this `unsafe` fn
+...
+LL | let _ = async { unsafe { let _ = async { unsf() }; }};
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1081:33
+ |
+LL | async unsafe fn async_blocks() {
+ | ------------------------------ because it's nested under this `unsafe` fn
+...
+LL | let _ = async { unsafe { let _ = async { unsf() }; }};
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1082:33
+ |
+LL | async unsafe fn async_blocks() {
+ | ------------------------------ because it's nested under this `unsafe` fn
+...
+LL | let _ = async { unsafe { let _ = async { unsf() }; }};
+ | ^^^^^^ unnecessary `unsafe` block
+ |
+ = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1092:22
+ |
+LL | let _x: [(); unsafe { 0 }] = [];
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+ --> $DIR/lint-unused-unsafe.rs:1096:22
+ |
+LL | let _x: [(); unsafe { unsafe { size() } }] = [];
+ | ^^^^^^ unnecessary `unsafe` block
+
+error: aborting due to 201 previous errors
+
diff --git a/src/test/ui/span/lint-unused-unsafe.rs b/src/test/ui/span/lint-unused-unsafe.rs
new file mode 100644
index 000000000..f8d1dff35
--- /dev/null
+++ b/src/test/ui/span/lint-unused-unsafe.rs
@@ -0,0 +1,1100 @@
+// Exercise the unused_unsafe attribute in some positive and negative cases
+
+
+// edition:2018
+
+// revisions: mir
+
+// FIXME: Adapt -Zthir-unsafeck to behave the same as the mir version after #93678,
+// then delete lint-unused-unsafe-thir.rs, and go back to using the settings below
+// // revisions: mir thir
+// // [thir]compile-flags: -Zthir-unsafeck
+
+#![allow(dead_code)]
+#![deny(unused_unsafe)]
+
+
+mod foo {
+ extern "C" {
+ pub fn bar();
+ }
+}
+
+fn callback<T, F>(_f: F) -> T where F: FnOnce() -> T { panic!() }
+unsafe fn unsf() {}
+
+fn bad1() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
+fn bad2() { unsafe { bad1() } } //~ ERROR: unnecessary `unsafe` block
+unsafe fn bad3() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
+fn bad4() { unsafe { callback(||{}) } } //~ ERROR: unnecessary `unsafe` block
+unsafe fn bad5() { unsafe { unsf() } } //~ ERROR: unnecessary `unsafe` block
+fn bad6() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe { // don't put the warning here
+ unsf()
+ }
+ }
+}
+unsafe fn bad7() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf()
+ }
+ }
+}
+
+unsafe fn good0() { unsf() }
+fn good1() { unsafe { unsf() } }
+fn good2() {
+ /* bug uncovered when implementing warning about unused unsafe blocks. Be
+ sure that when purity is inherited that the source of the unsafe-ness
+ is tracked correctly */
+ unsafe {
+ unsafe fn what() -> Vec<String> { panic!() }
+
+ callback(|| {
+ what();
+ });
+ }
+}
+
+unsafe fn good3() { foo::bar() }
+fn good4() { unsafe { foo::bar() } }
+
+#[allow(unused_unsafe)] fn allowed() { unsafe {} }
+
+fn main() {}
+
+mod additional_tests {
+ unsafe fn unsf() {}
+
+ // some tests
+
+ fn inner_ignored() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ unsafe {
+ unsf()
+ }
+ }
+ }
+
+ fn multi_level_unused() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe {} //~ ERROR: unnecessary `unsafe` block
+ unsafe {} //~ ERROR: unnecessary `unsafe` block
+ }
+ }
+
+ fn granularity() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() }
+ unsafe { unsf() }
+ unsafe { unsf() }
+ }
+ }
+
+ fn top_level_used() {
+ unsafe {
+ unsf();
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ }
+
+ }
+
+ fn top_level_ignored() {
+ #[allow(unused_unsafe)]
+ unsafe {
+ #[deny(unused_unsafe)]
+ {
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ }
+ }
+
+ }
+
+ // same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn inner_ignored_1() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ unsafe {
+ unsf()
+ }
+ }
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn multi_level_unused_1() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe {} //~ ERROR: unnecessary `unsafe` block
+ unsafe {} //~ ERROR: unnecessary `unsafe` block
+ }
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn granularity_1() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() }
+ unsafe { unsf() }
+ unsafe { unsf() }
+ }
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_used_1() {
+ unsafe {
+ unsf();
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ }
+
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_ignored_1() {
+ #[allow(unused_unsafe)]
+ unsafe {
+ #[deny(unused_unsafe)]
+ {
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ }
+ }
+ }
+
+ // same tests, but unsafe_op_in_unsafe_fn allowed,
+ // so that *all* unsafe blocks are unused
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn inner_ignored_2() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ unsafe {
+ unsf()
+ }
+ }
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn multi_level_unused_2() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe {} //~ ERROR: unnecessary `unsafe` block
+ unsafe {} //~ ERROR: unnecessary `unsafe` block
+ }
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granularity_2() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ }
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_used_2() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf();
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ }
+
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_ignored_2() {
+ #[allow(unused_unsafe)]
+ unsafe {
+ #[deny(unused_unsafe)]
+ {
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+ }
+ }
+ }
+
+ // additional tests when using unsafe_op_in_unsafe_fn
+ // in more complex ways
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn() {
+ unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ }
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_2() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ }
+ }
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ }
+ unsf();
+ }
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_4() {
+ unsafe {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf();
+ }
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ }
+ }
+}
+
+// the same set of tests, with closures everywhere
+mod additional_tests_closures {
+ unsafe fn unsf() {}
+
+ // some tests
+
+ fn inner_ignored() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ unsf()
+ };
+ };
+ }
+
+ fn multi_level_unused() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ fn granularity() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ };
+ }
+
+ fn top_level_used() {
+ let _ = || unsafe {
+ unsf();
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ };
+
+ }
+
+ fn top_level_ignored() {
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ #[deny(unused_unsafe)]
+ {
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ }
+ };
+
+ }
+
+ // same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn inner_ignored_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ unsf()
+ };
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn multi_level_unused_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn granularity_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_used_1() {
+ let _ = || unsafe {
+ unsf();
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ };
+
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_ignored_1() {
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ #[deny(unused_unsafe)]
+ {
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ }
+ };
+ }
+
+ // same tests, but unsafe_op_in_unsafe_fn allowed,
+ // so that *all* unsafe blocks are unused
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn inner_ignored_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ unsf()
+ };
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn multi_level_unused_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granularity_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_used_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf();
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ };
+
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_ignored_2() {
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ #[deny(unused_unsafe)]
+ {
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ }
+ };
+ }
+
+ // additional tests when using unsafe_op_in_unsafe_fn
+ // in more complex ways
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn() {
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ unsf();
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_4() {
+ let _ = || unsafe {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf();
+ };
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ }
+}
+
+// the same set of tests, with closures everywhere
+// and closures on the unsafe fn calls
+mod additional_tests_even_more_closures {
+ unsafe fn unsf() {}
+
+ // some tests
+
+ fn inner_ignored() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ let _ = || unsf();
+ };
+ };
+ }
+
+ fn multi_level_unused() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ fn granularity() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); };
+ let _ = || unsafe { let _ = || unsf(); };
+ let _ = || unsafe { let _ = || unsf(); };
+ };
+ }
+
+ fn top_level_used() {
+ let _ = || unsafe {
+ let _ = || unsf();
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ };
+
+ }
+
+ fn top_level_ignored() {
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ #[deny(unused_unsafe)]
+ {
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ }
+ };
+
+ }
+
+ // same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn inner_ignored_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ let _ = || unsf();
+ };
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn multi_level_unused_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn granularity_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); };
+ let _ = || unsafe { let _ = || unsf(); };
+ let _ = || unsafe { let _ = || unsf(); };
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_used_1() {
+ let _ = || unsafe {
+ let _ = || unsf();
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ };
+
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_ignored_1() {
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ #[deny(unused_unsafe)]
+ {
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ }
+ };
+ }
+
+ // same tests, but unsafe_op_in_unsafe_fn allowed,
+ // so that *all* unsafe blocks are unused
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn inner_ignored_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ let _ = || unsf();
+ };
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn multi_level_unused_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granularity_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_used_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsf();
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ };
+
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_ignored_2() {
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ #[deny(unused_unsafe)]
+ {
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+ }
+ };
+ }
+
+ // additional tests when using unsafe_op_in_unsafe_fn
+ // in more complex ways
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn() {
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ let _ = || unsf();
+ }
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ let _ = || unsf();
+ }
+ };
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ let _ = || unsf();
+ }
+ };
+ let _ = || unsf();
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_4() {
+ let _ = || unsafe {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsf();
+ };
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ let _ = || unsf();
+ }
+ };
+ }
+}
+
+mod item_likes {
+ unsafe fn unsf() {}
+
+ struct S;
+ impl S {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn inner_ignored_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ unsf()
+ };
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn multi_level_unused_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn granularity_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_used_1() {
+ let _ = || unsafe {
+ unsf();
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ };
+
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_ignored_1() {
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ #[deny(unused_unsafe)]
+ {
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ }
+ };
+ }
+
+ // same tests, but unsafe_op_in_unsafe_fn allowed,
+ // so that *all* unsafe blocks are unused
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn inner_ignored_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ unsf()
+ };
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn multi_level_unused_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granularity_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_used_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf();
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ };
+
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_ignored_2() {
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ #[deny(unused_unsafe)]
+ {
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ }
+ };
+ }
+
+ // additional tests when using unsafe_op_in_unsafe_fn
+ // in more complex ways
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn() {
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ unsf();
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_4() {
+ let _ = || unsafe {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf();
+ };
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ }
+ }
+
+ trait T {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn inner_ignored_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ unsf()
+ };
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn multi_level_unused_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn granularity_1() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ let _ = || unsafe { unsf() };
+ };
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_used_1() {
+ let _ = || unsafe {
+ unsf();
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ };
+
+ }
+
+ #[deny(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_ignored_1() {
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ #[deny(unused_unsafe)]
+ {
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ }
+ };
+ }
+
+ // same tests, but unsafe_op_in_unsafe_fn allowed,
+ // so that *all* unsafe blocks are unused
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn inner_ignored_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ unsf()
+ };
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn multi_level_unused_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granularity_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_used_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf();
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ };
+
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn top_level_ignored_2() {
+ #[allow(unused_unsafe)]
+ let _ = || unsafe {
+ #[deny(unused_unsafe)]
+ {
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+ }
+ };
+ }
+
+ // additional tests when using unsafe_op_in_unsafe_fn
+ // in more complex ways
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn() {
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_2() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = || unsafe {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ unsf();
+ };
+ }
+
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn_4() {
+ let _ = || unsafe {
+ let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+ unsf();
+ };
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ }
+ }
+}
+
+mod additional_tests_extra {
+ unsafe fn unsf() {}
+
+ // multiple uses with different `unsafe_op_in_unsafe_fn` in the same closure
+ #[allow(unsafe_op_in_unsafe_fn)]
+ unsafe fn granular_disallow_op_in_unsafe_fn() {
+ let _ = || unsafe {
+ let _ = || {
+ unsf();
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ };
+ };
+ }
+
+ #[warn(unsafe_op_in_unsafe_fn)]
+ unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() {
+ unsafe { //~ ERROR: unnecessary `unsafe` block
+ #[allow(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ #[allow(unsafe_op_in_unsafe_fn)]
+ {
+ unsf();
+ }
+ }
+ }
+
+ async unsafe fn async_blocks() {
+ #[deny(unsafe_op_in_unsafe_fn)]
+ {
+ let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsafe { let _ = async { unsf() }; }};
+ let _ = async { unsafe { let _ = async { unsf() }; }};
+ let _ = async { unsafe { let _ = async { unsf() }; }};
+ }};
+ let _ = async { unsafe {
+ let _ = async { unsf() };
+ let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+ }};
+ }
+ #[allow(unsafe_op_in_unsafe_fn)]
+ {
+ let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+ }};
+ let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsf() };
+ let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+ let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+ }};
+ }
+ }
+
+ fn used_unsafe_in_const() {
+ let _x: [(); unsafe { size() }] = [];
+ }
+
+ fn unused_unsafe_in_const_1() {
+ let _x: [(); unsafe { 0 }] = []; //~ ERROR: unnecessary `unsafe` block
+ }
+
+ fn unused_unsafe_in_const_2() {
+ let _x: [(); unsafe { unsafe { size() } }] = []; //~ ERROR: unnecessary `unsafe` block
+ }
+
+ const unsafe fn size() -> usize { 0 }
+}
diff --git a/src/test/ui/span/macro-span-replacement.rs b/src/test/ui/span/macro-span-replacement.rs
new file mode 100644
index 000000000..66973c58d
--- /dev/null
+++ b/src/test/ui/span/macro-span-replacement.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+#![warn(unused)]
+
+macro_rules! m {
+ ($a:tt $b:tt) => {
+ $b $a; //~ WARN struct `S` is never constructed
+ }
+}
+
+fn main() {
+ m!(S struct);
+}
diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr
new file mode 100644
index 000000000..5dd563428
--- /dev/null
+++ b/src/test/ui/span/macro-span-replacement.stderr
@@ -0,0 +1,19 @@
+warning: struct `S` is never constructed
+ --> $DIR/macro-span-replacement.rs:7:12
+ |
+LL | $b $a;
+ | ^^
+...
+LL | m!(S struct);
+ | ------------ in this macro invocation
+ |
+note: the lint level is defined here
+ --> $DIR/macro-span-replacement.rs:3:9
+ |
+LL | #![warn(unused)]
+ | ^^^^^^
+ = note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
+ = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/span/macro-ty-params.rs b/src/test/ui/span/macro-ty-params.rs
new file mode 100644
index 000000000..0a93105b6
--- /dev/null
+++ b/src/test/ui/span/macro-ty-params.rs
@@ -0,0 +1,13 @@
+macro_rules! m {
+ ($p1: path) => {
+ #[derive($p1)] struct U;
+ }
+}
+
+macro_rules! foo { () => () }
+
+fn main() {
+ foo::<T>!(); //~ ERROR generic arguments in macro path
+ foo::<>!(); //~ ERROR generic arguments in macro path
+ m!(Default<>); //~ ERROR unexpected generic arguments in path
+}
diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr
new file mode 100644
index 000000000..138cd2598
--- /dev/null
+++ b/src/test/ui/span/macro-ty-params.stderr
@@ -0,0 +1,20 @@
+error: generic arguments in macro path
+ --> $DIR/macro-ty-params.rs:10:10
+ |
+LL | foo::<T>!();
+ | ^^^
+
+error: generic arguments in macro path
+ --> $DIR/macro-ty-params.rs:11:10
+ |
+LL | foo::<>!();
+ | ^^
+
+error: unexpected generic arguments in path
+ --> $DIR/macro-ty-params.rs:12:15
+ |
+LL | m!(Default<>);
+ | ^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/span/method-and-field-eager-resolution.rs b/src/test/ui/span/method-and-field-eager-resolution.rs
new file mode 100644
index 000000000..a0f0d8810
--- /dev/null
+++ b/src/test/ui/span/method-and-field-eager-resolution.rs
@@ -0,0 +1,15 @@
+// Test that spans get only base in eager type resolution (structurally_resolve_type).
+
+fn main() {
+ let mut x = Default::default();
+ //~^ ERROR type annotations needed
+ x.0;
+ x = 1;
+}
+
+fn foo() {
+ let mut x = Default::default();
+ //~^ ERROR type annotations needed
+ x[0];
+ x = 1;
+}
diff --git a/src/test/ui/span/method-and-field-eager-resolution.stderr b/src/test/ui/span/method-and-field-eager-resolution.stderr
new file mode 100644
index 000000000..7d240589a
--- /dev/null
+++ b/src/test/ui/span/method-and-field-eager-resolution.stderr
@@ -0,0 +1,31 @@
+error[E0282]: type annotations needed
+ --> $DIR/method-and-field-eager-resolution.rs:4:9
+ |
+LL | let mut x = Default::default();
+ | ^^^^^
+LL |
+LL | x.0;
+ | - type must be known at this point
+ |
+help: consider giving `x` an explicit type
+ |
+LL | let mut x: _ = Default::default();
+ | +++
+
+error[E0282]: type annotations needed
+ --> $DIR/method-and-field-eager-resolution.rs:11:9
+ |
+LL | let mut x = Default::default();
+ | ^^^^^
+LL |
+LL | x[0];
+ | - type must be known at this point
+ |
+help: consider giving `x` an explicit type
+ |
+LL | let mut x: _ = Default::default();
+ | +++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/span/missing-unit-argument.rs b/src/test/ui/span/missing-unit-argument.rs
new file mode 100644
index 000000000..5b9861da6
--- /dev/null
+++ b/src/test/ui/span/missing-unit-argument.rs
@@ -0,0 +1,17 @@
+fn foo(():(), ():()) {}
+fn bar(():()) {}
+
+struct S;
+impl S {
+ fn baz(self, (): ()) { }
+ fn generic<T>(self, _: T) { }
+}
+
+fn main() {
+ let _: Result<(), String> = Ok(); //~ ERROR this enum variant takes
+ foo(); //~ ERROR this function takes
+ foo(()); //~ ERROR this function takes
+ bar(); //~ ERROR this function takes
+ S.baz(); //~ ERROR this function takes
+ S.generic::<()>(); //~ ERROR this function takes
+}
diff --git a/src/test/ui/span/missing-unit-argument.stderr b/src/test/ui/span/missing-unit-argument.stderr
new file mode 100644
index 000000000..e68260e4a
--- /dev/null
+++ b/src/test/ui/span/missing-unit-argument.stderr
@@ -0,0 +1,99 @@
+error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
+ --> $DIR/missing-unit-argument.rs:11:33
+ |
+LL | let _: Result<(), String> = Ok();
+ | ^^-- an argument of type `()` is missing
+ |
+note: tuple variant defined here
+ --> $SRC_DIR/core/src/result.rs:LL:COL
+ |
+LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
+ | ^^
+help: provide the argument
+ |
+LL | let _: Result<(), String> = Ok(());
+ | ~~~~~~
+
+error[E0061]: this function takes 2 arguments but 0 arguments were supplied
+ --> $DIR/missing-unit-argument.rs:12:5
+ |
+LL | foo();
+ | ^^^-- two arguments of type `()` and `()` are missing
+ |
+note: function defined here
+ --> $DIR/missing-unit-argument.rs:1:4
+ |
+LL | fn foo(():(), ():()) {}
+ | ^^^ ----- -----
+help: provide the arguments
+ |
+LL | foo((), ());
+ | ~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 1 argument was supplied
+ --> $DIR/missing-unit-argument.rs:13:5
+ |
+LL | foo(());
+ | ^^^---- an argument of type `()` is missing
+ |
+note: function defined here
+ --> $DIR/missing-unit-argument.rs:1:4
+ |
+LL | fn foo(():(), ():()) {}
+ | ^^^ ----- -----
+help: provide the argument
+ |
+LL | foo((), ());
+ | ~~~~~~~~~~~
+
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
+ --> $DIR/missing-unit-argument.rs:14:5
+ |
+LL | bar();
+ | ^^^-- an argument of type `()` is missing
+ |
+note: function defined here
+ --> $DIR/missing-unit-argument.rs:2:4
+ |
+LL | fn bar(():()) {}
+ | ^^^ -----
+help: provide the argument
+ |
+LL | bar(());
+ | ~~~~~~~
+
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
+ --> $DIR/missing-unit-argument.rs:15:7
+ |
+LL | S.baz();
+ | ^^^-- an argument of type `()` is missing
+ |
+note: associated function defined here
+ --> $DIR/missing-unit-argument.rs:6:8
+ |
+LL | fn baz(self, (): ()) { }
+ | ^^^ ---- ------
+help: provide the argument
+ |
+LL | S.baz(());
+ | ~~~~~~~
+
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
+ --> $DIR/missing-unit-argument.rs:16:7
+ |
+LL | S.generic::<()>();
+ | ^^^^^^^^^^^^^-- an argument of type `()` is missing
+ |
+note: associated function defined here
+ --> $DIR/missing-unit-argument.rs:7:8
+ |
+LL | fn generic<T>(self, _: T) { }
+ | ^^^^^^^ ---- ----
+help: provide the argument
+ |
+LL | S.generic::<()>(());
+ | ~~~~~~~~~~~~~~~~~
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/span/move-closure.rs b/src/test/ui/span/move-closure.rs
new file mode 100644
index 000000000..bdd7951b3
--- /dev/null
+++ b/src/test/ui/span/move-closure.rs
@@ -0,0 +1,6 @@
+// Regression test for issue #24986
+// Make sure that the span of a closure marked `move` begins at the `move` keyword.
+
+fn main() {
+ let x: () = move || (); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/span/move-closure.stderr b/src/test/ui/span/move-closure.stderr
new file mode 100644
index 000000000..dcc607896
--- /dev/null
+++ b/src/test/ui/span/move-closure.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+ --> $DIR/move-closure.rs:5:17
+ |
+LL | let x: () = move || ();
+ | -- ^^^^^^^^^^ expected `()`, found closure
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found closure `[closure@$DIR/move-closure.rs:5:17: 5:24]`
+help: use parentheses to call this closure
+ |
+LL | let x: () = (move || ())();
+ | + +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/span/multiline-span-E0072.rs b/src/test/ui/span/multiline-span-E0072.rs
new file mode 100644
index 000000000..728b47d65
--- /dev/null
+++ b/src/test/ui/span/multiline-span-E0072.rs
@@ -0,0 +1,10 @@
+// It should just use the entire body instead of pointing at the next two lines
+struct //~ ERROR has infinite size
+ListNode
+{
+ head: u8,
+ tail: Option<ListNode>,
+}
+
+fn main() {
+}
diff --git a/src/test/ui/span/multiline-span-E0072.stderr b/src/test/ui/span/multiline-span-E0072.stderr
new file mode 100644
index 000000000..79b13f45f
--- /dev/null
+++ b/src/test/ui/span/multiline-span-E0072.stderr
@@ -0,0 +1,18 @@
+error[E0072]: recursive type `ListNode` has infinite size
+ --> $DIR/multiline-span-E0072.rs:2:1
+ |
+LL | / struct
+LL | | ListNode
+ | |________^ recursive type has infinite size
+...
+LL | tail: Option<ListNode>,
+ | ---------------- recursive without indirection
+ |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `ListNode` representable
+ |
+LL | tail: Option<Box<ListNode>>,
+ | ++++ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0072`.
diff --git a/src/test/ui/span/multiline-span-simple.rs b/src/test/ui/span/multiline-span-simple.rs
new file mode 100644
index 000000000..204a7f6b1
--- /dev/null
+++ b/src/test/ui/span/multiline-span-simple.rs
@@ -0,0 +1,20 @@
+fn foo(a: u32, b: u32) {
+ a + b;
+}
+
+fn bar(a: u32, b: u32) {
+ a + b;
+}
+
+fn main() {
+ let x = 1;
+ let y = 2;
+ let z = 3;
+ foo(1 as u32 + //~ ERROR cannot add `()` to `u32`
+
+ bar(x,
+
+ y),
+
+ z)
+}
diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr
new file mode 100644
index 000000000..c0d9a8634
--- /dev/null
+++ b/src/test/ui/span/multiline-span-simple.stderr
@@ -0,0 +1,21 @@
+error[E0277]: cannot add `()` to `u32`
+ --> $DIR/multiline-span-simple.rs:13:18
+ |
+LL | foo(1 as u32 +
+ | ^ no implementation for `u32 + ()`
+ |
+ = help: the trait `Add<()>` is not implemented for `u32`
+ = help: the following other types implement trait `Add<Rhs>`:
+ <&'a f32 as Add<f32>>
+ <&'a f64 as Add<f64>>
+ <&'a i128 as Add<i128>>
+ <&'a i16 as Add<i16>>
+ <&'a i32 as Add<i32>>
+ <&'a i64 as Add<i64>>
+ <&'a i8 as Add<i8>>
+ <&'a isize as Add<isize>>
+ and 48 others
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/span/multispan-import-lint.rs b/src/test/ui/span/multispan-import-lint.rs
new file mode 100644
index 000000000..3ce7f2ce3
--- /dev/null
+++ b/src/test/ui/span/multispan-import-lint.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+#![warn(unused)]
+
+use std::cmp::{Eq, Ord, min, PartialEq, PartialOrd};
+//~^ WARN unused imports
+
+fn main() {
+ let _ = min(1, 2);
+}
diff --git a/src/test/ui/span/multispan-import-lint.stderr b/src/test/ui/span/multispan-import-lint.stderr
new file mode 100644
index 000000000..4a955d1b3
--- /dev/null
+++ b/src/test/ui/span/multispan-import-lint.stderr
@@ -0,0 +1,15 @@
+warning: unused imports: `Eq`, `Ord`, `PartialEq`, `PartialOrd`
+ --> $DIR/multispan-import-lint.rs:5:16
+ |
+LL | use std::cmp::{Eq, Ord, min, PartialEq, PartialOrd};
+ | ^^ ^^^ ^^^^^^^^^ ^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/multispan-import-lint.rs:3:9
+ |
+LL | #![warn(unused)]
+ | ^^^^^^
+ = note: `#[warn(unused_imports)]` implied by `#[warn(unused)]`
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/span/mut-arg-hint.rs b/src/test/ui/span/mut-arg-hint.rs
new file mode 100644
index 000000000..d7ff1f0de
--- /dev/null
+++ b/src/test/ui/span/mut-arg-hint.rs
@@ -0,0 +1,22 @@
+trait B {
+ fn foo(mut a: &String) {
+ a.push_str("bar"); //~ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference
+ }
+}
+
+pub fn foo<'a>(mut a: &'a String) {
+ a.push_str("foo"); //~ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference
+}
+
+struct A {}
+
+impl A {
+ pub fn foo(mut a: &String) {
+ a.push_str("foo"); //~ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference
+ }
+}
+
+fn main() {
+ foo(&"a".to_string());
+ A::foo(&"a".to_string());
+}
diff --git a/src/test/ui/span/mut-arg-hint.stderr b/src/test/ui/span/mut-arg-hint.stderr
new file mode 100644
index 000000000..8a7c504f0
--- /dev/null
+++ b/src/test/ui/span/mut-arg-hint.stderr
@@ -0,0 +1,27 @@
+error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
+ --> $DIR/mut-arg-hint.rs:3:9
+ |
+LL | fn foo(mut a: &String) {
+ | ------- help: consider changing this to be a mutable reference: `&mut String`
+LL | a.push_str("bar");
+ | ^^^^^^^^^^^^^^^^^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
+ --> $DIR/mut-arg-hint.rs:8:5
+ |
+LL | pub fn foo<'a>(mut a: &'a String) {
+ | ---------- help: consider changing this to be a mutable reference: `&'a mut String`
+LL | a.push_str("foo");
+ | ^^^^^^^^^^^^^^^^^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
+ --> $DIR/mut-arg-hint.rs:15:9
+ |
+LL | pub fn foo(mut a: &String) {
+ | ------- help: consider changing this to be a mutable reference: `&mut String`
+LL | a.push_str("foo");
+ | ^^^^^^^^^^^^^^^^^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/span/mut-ptr-cant-outlive-ref.rs b/src/test/ui/span/mut-ptr-cant-outlive-ref.rs
new file mode 100644
index 000000000..b8c752d73
--- /dev/null
+++ b/src/test/ui/span/mut-ptr-cant-outlive-ref.rs
@@ -0,0 +1,15 @@
+use std::cell::RefCell;
+
+fn main() {
+ let m = RefCell::new(0);
+ let p;
+ {
+ let b = m.borrow();
+ p = &*b;
+ }
+ //~^^ ERROR `b` does not live long enough
+ p.use_ref();
+}
+
+trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } }
+impl<T> Fake for T { }
diff --git a/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr b/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr
new file mode 100644
index 000000000..4d976a7bb
--- /dev/null
+++ b/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr
@@ -0,0 +1,14 @@
+error[E0597]: `b` does not live long enough
+ --> $DIR/mut-ptr-cant-outlive-ref.rs:8:15
+ |
+LL | p = &*b;
+ | ^ borrowed value does not live long enough
+LL | }
+ | - `b` dropped here while still borrowed
+LL |
+LL | p.use_ref();
+ | ----------- borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/non-existing-module-import.rs b/src/test/ui/span/non-existing-module-import.rs
new file mode 100644
index 000000000..d2ce7ec4f
--- /dev/null
+++ b/src/test/ui/span/non-existing-module-import.rs
@@ -0,0 +1,3 @@
+use std::bar::{foo1, foo2}; //~ ERROR unresolved import
+
+fn main() {}
diff --git a/src/test/ui/span/non-existing-module-import.stderr b/src/test/ui/span/non-existing-module-import.stderr
new file mode 100644
index 000000000..25c099590
--- /dev/null
+++ b/src/test/ui/span/non-existing-module-import.stderr
@@ -0,0 +1,9 @@
+error[E0432]: unresolved import `std::bar`
+ --> $DIR/non-existing-module-import.rs:1:10
+ |
+LL | use std::bar::{foo1, foo2};
+ | ^^^ could not find `bar` in `std`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/src/test/ui/span/pub-struct-field.rs b/src/test/ui/span/pub-struct-field.rs
new file mode 100644
index 000000000..e149b9dbf
--- /dev/null
+++ b/src/test/ui/span/pub-struct-field.rs
@@ -0,0 +1,10 @@
+// Regression test for issue #26083 and #35435
+// Test that span for public struct fields start at `pub`
+
+struct Foo {
+ bar: u8,
+ pub bar: u8, //~ ERROR is already declared
+ pub(crate) bar: u8, //~ ERROR is already declared
+}
+
+fn main() {}
diff --git a/src/test/ui/span/pub-struct-field.stderr b/src/test/ui/span/pub-struct-field.stderr
new file mode 100644
index 000000000..065340f44
--- /dev/null
+++ b/src/test/ui/span/pub-struct-field.stderr
@@ -0,0 +1,20 @@
+error[E0124]: field `bar` is already declared
+ --> $DIR/pub-struct-field.rs:6:5
+ |
+LL | bar: u8,
+ | ------- `bar` first declared here
+LL | pub bar: u8,
+ | ^^^^^^^^^^^ field already declared
+
+error[E0124]: field `bar` is already declared
+ --> $DIR/pub-struct-field.rs:7:5
+ |
+LL | bar: u8,
+ | ------- `bar` first declared here
+LL | pub bar: u8,
+LL | pub(crate) bar: u8,
+ | ^^^^^^^^^^^^^^^^^^ field already declared
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0124`.
diff --git a/src/test/ui/span/range-2.rs b/src/test/ui/span/range-2.rs
new file mode 100644
index 000000000..c4bb16f44
--- /dev/null
+++ b/src/test/ui/span/range-2.rs
@@ -0,0 +1,15 @@
+// Test range syntax - borrow errors.
+#![feature(rustc_attrs)]
+pub fn main() { #![rustc_error] // rust-lang/rust#49855
+ let r = {
+ let a = 42;
+ let b = 42;
+ &a..&b
+ };
+ //~^^ ERROR `a` does not live long enough
+ //~| ERROR `b` does not live long enough
+ r.use_ref();
+}
+
+trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } }
+impl<T> Fake for T { }
diff --git a/src/test/ui/span/range-2.stderr b/src/test/ui/span/range-2.stderr
new file mode 100644
index 000000000..8ca8156b0
--- /dev/null
+++ b/src/test/ui/span/range-2.stderr
@@ -0,0 +1,25 @@
+error[E0597]: `a` does not live long enough
+ --> $DIR/range-2.rs:7:9
+ |
+LL | let r = {
+ | - borrow later stored here
+...
+LL | &a..&b
+ | ^^ borrowed value does not live long enough
+LL | };
+ | - `a` dropped here while still borrowed
+
+error[E0597]: `b` does not live long enough
+ --> $DIR/range-2.rs:7:13
+ |
+LL | let r = {
+ | - borrow later stored here
+...
+LL | &a..&b
+ | ^^ borrowed value does not live long enough
+LL | };
+ | - `b` dropped here while still borrowed
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/recursive-type-field.rs b/src/test/ui/span/recursive-type-field.rs
new file mode 100644
index 000000000..58ea81b83
--- /dev/null
+++ b/src/test/ui/span/recursive-type-field.rs
@@ -0,0 +1,18 @@
+use std::rc::Rc;
+
+struct Foo<'a> { //~ ERROR recursive type
+ bar: Bar<'a>,
+ b: Rc<Bar<'a>>,
+}
+
+struct Bar<'a> { //~ ERROR recursive type
+ y: (Foo<'a>, Foo<'a>),
+ z: Option<Bar<'a>>,
+ a: &'a Foo<'a>,
+ c: &'a [Bar<'a>],
+ d: [Bar<'a>; 1],
+ e: Foo<'a>,
+ x: Bar<'a>,
+}
+
+fn main() {}
diff --git a/src/test/ui/span/recursive-type-field.stderr b/src/test/ui/span/recursive-type-field.stderr
new file mode 100644
index 000000000..08e97e750
--- /dev/null
+++ b/src/test/ui/span/recursive-type-field.stderr
@@ -0,0 +1,35 @@
+error[E0072]: recursive type `Foo` has infinite size
+ --> $DIR/recursive-type-field.rs:3:1
+ |
+LL | struct Foo<'a> {
+ | ^^^^^^^^^^^^^^ recursive type has infinite size
+LL | bar: Bar<'a>,
+ | ------- recursive without indirection
+ |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable
+ |
+LL | bar: Box<Bar<'a>>,
+ | ++++ +
+
+error[E0072]: recursive type `Bar` has infinite size
+ --> $DIR/recursive-type-field.rs:8:1
+ |
+LL | struct Bar<'a> {
+ | ^^^^^^^^^^^^^^ recursive type has infinite size
+LL | y: (Foo<'a>, Foo<'a>),
+ | ------------------ recursive without indirection
+LL | z: Option<Bar<'a>>,
+ | --------------- recursive without indirection
+...
+LL | d: [Bar<'a>; 1],
+ | ------------ recursive without indirection
+LL | e: Foo<'a>,
+ | ------- recursive without indirection
+LL | x: Bar<'a>,
+ | ------- recursive without indirection
+ |
+ = help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Bar` representable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0072`.
diff --git a/src/test/ui/span/regionck-unboxed-closure-lifetimes.rs b/src/test/ui/span/regionck-unboxed-closure-lifetimes.rs
new file mode 100644
index 000000000..60ccaa872
--- /dev/null
+++ b/src/test/ui/span/regionck-unboxed-closure-lifetimes.rs
@@ -0,0 +1,16 @@
+#![feature(rustc_attrs)]
+use std::ops::FnMut;
+
+fn main() { #![rustc_error] // rust-lang/rust#49855
+ let mut f;
+ {
+ let c = 1;
+ let c_ref = &c;
+ //~^ ERROR `c` does not live long enough
+ f = move |a: isize, b: isize| { a + b + *c_ref };
+ }
+ f.use_mut();
+}
+
+trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } }
+impl<T> Fake for T { }
diff --git a/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr b/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr
new file mode 100644
index 000000000..0b985de60
--- /dev/null
+++ b/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr
@@ -0,0 +1,14 @@
+error[E0597]: `c` does not live long enough
+ --> $DIR/regionck-unboxed-closure-lifetimes.rs:8:21
+ |
+LL | let c_ref = &c;
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c` dropped here while still borrowed
+LL | f.use_mut();
+ | ----------- borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs
new file mode 100644
index 000000000..16b4cc258
--- /dev/null
+++ b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs
@@ -0,0 +1,16 @@
+fn id<T>(x: T) -> T { x }
+
+trait Foo { }
+
+impl<'a> Foo for &'a isize { }
+
+fn main() {
+
+ let blah;
+
+ {
+ let ss: &isize = &id(1);
+ //~^ ERROR temporary value dropped while borrowed
+ blah = Box::new(ss) as Box<dyn Foo>;
+ }
+}
diff --git a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr
new file mode 100644
index 000000000..ba0c45acf
--- /dev/null
+++ b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr
@@ -0,0 +1,16 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/regions-close-over-borrowed-ref-in-obj.rs:12:27
+ |
+LL | let ss: &isize = &id(1);
+ | ^^^^^ creates a temporary which is freed while still in use
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+LL | }
+ | - borrow might be used here, when `blah` is dropped and runs the destructor for type `Box<dyn Foo>`
+ |
+ = note: consider using a `let` binding to create a longer lived value
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/src/test/ui/span/regions-close-over-type-parameter-2.rs b/src/test/ui/span/regions-close-over-type-parameter-2.rs
new file mode 100644
index 000000000..aca3972cb
--- /dev/null
+++ b/src/test/ui/span/regions-close-over-type-parameter-2.rs
@@ -0,0 +1,27 @@
+// Test for what happens when a type parameter `A` is closed over into
+// an object. This should yield errors unless `A` (and the object)
+// both have suitable bounds.
+
+trait Foo { fn get(&self); }
+
+impl<A> Foo for A {
+ fn get(&self) {
+ }
+}
+
+fn repeater3<'a,A:'a>(v: A) -> Box<dyn Foo + 'a> {
+ Box::new(v) as Box<dyn Foo+'a>
+}
+
+fn main() {
+
+ // Error results because the type of is inferred to be
+ // ~Repeat<&'blk isize> where blk is the lifetime of the block below.
+
+ let _ = {
+ let tmp0 = 3;
+ let tmp1 = &tmp0;
+ repeater3(tmp1)
+ };
+ //~^^^ ERROR `tmp0` does not live long enough
+}
diff --git a/src/test/ui/span/regions-close-over-type-parameter-2.stderr b/src/test/ui/span/regions-close-over-type-parameter-2.stderr
new file mode 100644
index 000000000..2e584d9a8
--- /dev/null
+++ b/src/test/ui/span/regions-close-over-type-parameter-2.stderr
@@ -0,0 +1,13 @@
+error[E0597]: `tmp0` does not live long enough
+ --> $DIR/regions-close-over-type-parameter-2.rs:23:20
+ |
+LL | let tmp1 = &tmp0;
+ | ^^^^^ borrowed value does not live long enough
+LL | repeater3(tmp1)
+ | --------------- borrow later captured here by trait object
+LL | };
+ | - `tmp0` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/regions-escape-loop-via-variable.rs b/src/test/ui/span/regions-escape-loop-via-variable.rs
new file mode 100644
index 000000000..ad468896b
--- /dev/null
+++ b/src/test/ui/span/regions-escape-loop-via-variable.rs
@@ -0,0 +1,14 @@
+fn main() {
+ let x = 3;
+
+ // Here, the variable `p` gets inferred to a type with a lifetime
+ // of the loop body. The regionck then determines that this type
+ // is invalid.
+ let mut p = &x;
+
+ loop {
+ let x = 1 + *p;
+ p = &x;
+ }
+ //~^^ ERROR `x` does not live long enough
+}
diff --git a/src/test/ui/span/regions-escape-loop-via-variable.stderr b/src/test/ui/span/regions-escape-loop-via-variable.stderr
new file mode 100644
index 000000000..42df66852
--- /dev/null
+++ b/src/test/ui/span/regions-escape-loop-via-variable.stderr
@@ -0,0 +1,13 @@
+error[E0597]: `x` does not live long enough
+ --> $DIR/regions-escape-loop-via-variable.rs:11:13
+ |
+LL | let x = 1 + *p;
+ | -- borrow later used here
+LL | p = &x;
+ | ^^ borrowed value does not live long enough
+LL | }
+ | - `x` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/regions-escape-loop-via-vec.rs b/src/test/ui/span/regions-escape-loop-via-vec.rs
new file mode 100644
index 000000000..1fceb0969
--- /dev/null
+++ b/src/test/ui/span/regions-escape-loop-via-vec.rs
@@ -0,0 +1,13 @@
+// The type of `y` ends up getting inferred to the type of the block.
+fn broken() {
+ let mut x = 3;
+ let mut _y = vec![&mut x];
+ while x < 10 { //~ ERROR cannot use `x` because it was mutably borrowed
+ let mut z = x; //~ ERROR cannot use `x` because it was mutably borrowed
+ _y.push(&mut z);
+ //~^ ERROR `z` does not live long enough
+ x += 1; //~ ERROR cannot use `x` because it was mutably borrowed
+ }
+}
+
+fn main() { }
diff --git a/src/test/ui/span/regions-escape-loop-via-vec.stderr b/src/test/ui/span/regions-escape-loop-via-vec.stderr
new file mode 100644
index 000000000..2b6493077
--- /dev/null
+++ b/src/test/ui/span/regions-escape-loop-via-vec.stderr
@@ -0,0 +1,50 @@
+error[E0503]: cannot use `x` because it was mutably borrowed
+ --> $DIR/regions-escape-loop-via-vec.rs:5:11
+ |
+LL | let mut _y = vec![&mut x];
+ | ------ borrow of `x` occurs here
+LL | while x < 10 {
+ | ^ use of borrowed `x`
+LL | let mut z = x;
+LL | _y.push(&mut z);
+ | --------------- borrow later used here
+
+error[E0503]: cannot use `x` because it was mutably borrowed
+ --> $DIR/regions-escape-loop-via-vec.rs:6:21
+ |
+LL | let mut _y = vec![&mut x];
+ | ------ borrow of `x` occurs here
+LL | while x < 10 {
+LL | let mut z = x;
+ | ^ use of borrowed `x`
+LL | _y.push(&mut z);
+ | --------------- borrow later used here
+
+error[E0597]: `z` does not live long enough
+ --> $DIR/regions-escape-loop-via-vec.rs:7:17
+ |
+LL | _y.push(&mut z);
+ | --------^^^^^^-
+ | | |
+ | | borrowed value does not live long enough
+ | borrow later used here
+...
+LL | }
+ | - `z` dropped here while still borrowed
+
+error[E0503]: cannot use `x` because it was mutably borrowed
+ --> $DIR/regions-escape-loop-via-vec.rs:9:9
+ |
+LL | let mut _y = vec![&mut x];
+ | ------ borrow of `x` occurs here
+...
+LL | _y.push(&mut z);
+ | --------------- borrow later used here
+LL |
+LL | x += 1;
+ | ^^^^^^ use of borrowed `x`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0503, E0597.
+For more information about an error, try `rustc --explain E0503`.
diff --git a/src/test/ui/span/regions-infer-borrow-scope-within-loop.rs b/src/test/ui/span/regions-infer-borrow-scope-within-loop.rs
new file mode 100644
index 000000000..3b20285b1
--- /dev/null
+++ b/src/test/ui/span/regions-infer-borrow-scope-within-loop.rs
@@ -0,0 +1,22 @@
+fn borrow<T>(x: &T) -> &T {x}
+
+fn foo<C, M>(mut cond: C, mut make_box: M) where
+ C: FnMut() -> bool,
+ M: FnMut() -> Box<isize>,
+{
+ let mut y: &isize;
+ loop {
+ let x = make_box();
+
+ // Here we complain because the resulting region
+ // of this borrow is the fn body as a whole.
+ y = borrow(&*x);
+ //~^ ERROR `*x` does not live long enough
+
+ assert_eq!(*x, *y);
+ if cond() { break; }
+ }
+ assert!(*y != 0);
+}
+
+fn main() {}
diff --git a/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr b/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr
new file mode 100644
index 000000000..fd67c65c4
--- /dev/null
+++ b/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr
@@ -0,0 +1,14 @@
+error[E0597]: `*x` does not live long enough
+ --> $DIR/regions-infer-borrow-scope-within-loop.rs:13:20
+ |
+LL | y = borrow(&*x);
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `*x` dropped here while still borrowed
+LL | assert!(*y != 0);
+ | -- borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/send-is-not-static-ensures-scoping.rs b/src/test/ui/span/send-is-not-static-ensures-scoping.rs
new file mode 100644
index 000000000..2aecc2a7e
--- /dev/null
+++ b/src/test/ui/span/send-is-not-static-ensures-scoping.rs
@@ -0,0 +1,26 @@
+struct Guard<'a> {
+ f: Box<dyn Fn() + Send + 'a>,
+}
+
+fn scoped<'a, F: Fn() + Send + 'a>(f: F) -> Guard<'a> {
+ Guard { f: Box::new(f) }
+}
+
+impl<'a> Guard<'a> {
+ fn join(self) {}
+}
+
+fn main() {
+ let bad = {
+ let x = 1;
+ let y = &x;
+ //~^ ERROR `x` does not live long enough
+
+ scoped(|| {
+ let _z = y;
+ //~^ ERROR `y` does not live long enough
+ })
+ };
+
+ bad.join();
+}
diff --git a/src/test/ui/span/send-is-not-static-ensures-scoping.stderr b/src/test/ui/span/send-is-not-static-ensures-scoping.stderr
new file mode 100644
index 000000000..65d10c130
--- /dev/null
+++ b/src/test/ui/span/send-is-not-static-ensures-scoping.stderr
@@ -0,0 +1,29 @@
+error[E0597]: `x` does not live long enough
+ --> $DIR/send-is-not-static-ensures-scoping.rs:16:17
+ |
+LL | let bad = {
+ | --- borrow later stored here
+LL | let x = 1;
+LL | let y = &x;
+ | ^^ borrowed value does not live long enough
+...
+LL | };
+ | - `x` dropped here while still borrowed
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/send-is-not-static-ensures-scoping.rs:20:22
+ |
+LL | let bad = {
+ | --- borrow later stored here
+...
+LL | scoped(|| {
+ | -- value captured here
+LL | let _z = y;
+ | ^ borrowed value does not live long enough
+...
+LL | };
+ | - `y` dropped here while still borrowed
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/send-is-not-static-std-sync-2.rs b/src/test/ui/span/send-is-not-static-std-sync-2.rs
new file mode 100644
index 000000000..38746d4cb
--- /dev/null
+++ b/src/test/ui/span/send-is-not-static-std-sync-2.rs
@@ -0,0 +1,39 @@
+// basic tests to see that certain "obvious" errors are caught by
+// these types no longer requiring `'static` (RFC 458)
+
+#![allow(dead_code)]
+
+use std::sync::{Mutex, RwLock, mpsc};
+
+fn mutex() {
+ let lock = {
+ let x = 1;
+ Mutex::new(&x)
+ };
+ //~^^ ERROR `x` does not live long enough
+
+ let _dangling = *lock.lock().unwrap();
+}
+
+fn rwlock() {
+ let lock = {
+ let x = 1;
+ RwLock::new(&x)
+ };
+ //~^^ ERROR `x` does not live long enough
+ let _dangling = *lock.read().unwrap();
+}
+
+fn channel() {
+ let (_tx, rx) = {
+ let x = 1;
+ let (tx, rx) = mpsc::channel();
+ let _ = tx.send(&x);
+ (tx, rx)
+ };
+ //~^^^ ERROR `x` does not live long enough
+
+ let _dangling = rx.recv();
+}
+
+fn main() {}
diff --git a/src/test/ui/span/send-is-not-static-std-sync-2.stderr b/src/test/ui/span/send-is-not-static-std-sync-2.stderr
new file mode 100644
index 000000000..bcd07e116
--- /dev/null
+++ b/src/test/ui/span/send-is-not-static-std-sync-2.stderr
@@ -0,0 +1,37 @@
+error[E0597]: `x` does not live long enough
+ --> $DIR/send-is-not-static-std-sync-2.rs:11:20
+ |
+LL | let lock = {
+ | ---- borrow later stored here
+LL | let x = 1;
+LL | Mutex::new(&x)
+ | ^^ borrowed value does not live long enough
+LL | };
+ | - `x` dropped here while still borrowed
+
+error[E0597]: `x` does not live long enough
+ --> $DIR/send-is-not-static-std-sync-2.rs:21:21
+ |
+LL | let lock = {
+ | ---- borrow later stored here
+LL | let x = 1;
+LL | RwLock::new(&x)
+ | ^^ borrowed value does not live long enough
+LL | };
+ | - `x` dropped here while still borrowed
+
+error[E0597]: `x` does not live long enough
+ --> $DIR/send-is-not-static-std-sync-2.rs:31:25
+ |
+LL | let (_tx, rx) = {
+ | --- borrow later used here
+...
+LL | let _ = tx.send(&x);
+ | ^^ borrowed value does not live long enough
+LL | (tx, rx)
+LL | };
+ | - `x` dropped here while still borrowed
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/send-is-not-static-std-sync.rs b/src/test/ui/span/send-is-not-static-std-sync.rs
new file mode 100644
index 000000000..f8ab5243c
--- /dev/null
+++ b/src/test/ui/span/send-is-not-static-std-sync.rs
@@ -0,0 +1,55 @@
+// basic tests to see that certain "obvious" errors are caught by
+// these types no longer requiring `'static` (RFC 458)
+
+#![allow(dead_code)]
+
+use std::sync::{Mutex, RwLock, mpsc};
+
+fn mutex() {
+ let x = 1;
+ let y = Box::new(1);
+ let lock = Mutex::new(&x);
+ *lock.lock().unwrap() = &*y;
+ drop(y); //~ ERROR cannot move out
+ {
+ let z = 2;
+ *lock.lock().unwrap() = &z;
+ }
+ //~^^ ERROR `z` does not live long enough
+ lock.use_ref(); // (Mutex is #[may_dangle] so its dtor does not use `z` => needs explicit use)
+}
+
+fn rwlock() {
+ let x = 1;
+ let y = Box::new(1);
+ let lock = RwLock::new(&x);
+ *lock.write().unwrap() = &*y;
+ drop(y); //~ ERROR cannot move out
+ {
+ let z = 2;
+ *lock.write().unwrap() = &z;
+ }
+ //~^^ ERROR `z` does not live long enough
+ lock.use_ref(); // (RwLock is #[may_dangle] so its dtor does not use `z` => needs explicit use)
+}
+
+fn channel() {
+ let x = 1;
+ let y = Box::new(1);
+ let (tx, rx) = mpsc::channel();
+
+ tx.send(&x).unwrap();
+ tx.send(&*y);
+ drop(y); //~ ERROR cannot move out
+ {
+ let z = 2;
+ tx.send(&z).unwrap();
+ }
+ //~^^ ERROR `z` does not live long enough
+ // (channels lack #[may_dangle], thus their dtors are implicit uses of `z`)
+}
+
+fn main() {}
+
+trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } }
+impl<T> Fake for T { }
diff --git a/src/test/ui/span/send-is-not-static-std-sync.stderr b/src/test/ui/span/send-is-not-static-std-sync.stderr
new file mode 100644
index 000000000..5d493a3e4
--- /dev/null
+++ b/src/test/ui/span/send-is-not-static-std-sync.stderr
@@ -0,0 +1,72 @@
+error[E0505]: cannot move out of `y` because it is borrowed
+ --> $DIR/send-is-not-static-std-sync.rs:13:10
+ |
+LL | *lock.lock().unwrap() = &*y;
+ | --- borrow of `*y` occurs here
+LL | drop(y);
+ | ^ move out of `y` occurs here
+...
+LL | *lock.lock().unwrap() = &z;
+ | ----------- borrow later used here
+
+error[E0597]: `z` does not live long enough
+ --> $DIR/send-is-not-static-std-sync.rs:16:33
+ |
+LL | *lock.lock().unwrap() = &z;
+ | ^^ borrowed value does not live long enough
+LL | }
+ | - `z` dropped here while still borrowed
+LL |
+LL | lock.use_ref(); // (Mutex is #[may_dangle] so its dtor does not use `z` => needs explicit use)
+ | -------------- borrow later used here
+
+error[E0505]: cannot move out of `y` because it is borrowed
+ --> $DIR/send-is-not-static-std-sync.rs:27:10
+ |
+LL | *lock.write().unwrap() = &*y;
+ | --- borrow of `*y` occurs here
+LL | drop(y);
+ | ^ move out of `y` occurs here
+...
+LL | *lock.write().unwrap() = &z;
+ | ------------ borrow later used here
+
+error[E0597]: `z` does not live long enough
+ --> $DIR/send-is-not-static-std-sync.rs:30:34
+ |
+LL | *lock.write().unwrap() = &z;
+ | ^^ borrowed value does not live long enough
+LL | }
+ | - `z` dropped here while still borrowed
+LL |
+LL | lock.use_ref(); // (RwLock is #[may_dangle] so its dtor does not use `z` => needs explicit use)
+ | -------------- borrow later used here
+
+error[E0505]: cannot move out of `y` because it is borrowed
+ --> $DIR/send-is-not-static-std-sync.rs:43:10
+ |
+LL | tx.send(&*y);
+ | --- borrow of `*y` occurs here
+LL | drop(y);
+ | ^ move out of `y` occurs here
+...
+LL | tx.send(&z).unwrap();
+ | ----------- borrow later used here
+
+error[E0597]: `z` does not live long enough
+ --> $DIR/send-is-not-static-std-sync.rs:46:17
+ |
+LL | tx.send(&z).unwrap();
+ | ^^ borrowed value does not live long enough
+LL | }
+ | - `z` dropped here while still borrowed
+...
+LL | }
+ | - borrow might be used here, when `tx` is dropped and runs the `Drop` code for type `Sender`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0505, E0597.
+For more information about an error, try `rustc --explain E0505`.
diff --git a/src/test/ui/span/slice-borrow.rs b/src/test/ui/span/slice-borrow.rs
new file mode 100644
index 000000000..38cd7acbd
--- /dev/null
+++ b/src/test/ui/span/slice-borrow.rs
@@ -0,0 +1,14 @@
+// Test slicing expressions doesn't defeat the borrow checker.
+
+fn main() {
+ let y;
+ {
+ let x: &[isize] = &vec![1, 2, 3, 4, 5];
+ //~^ ERROR temporary value dropped while borrowed
+ y = &x[1..];
+ }
+ y.use_ref();
+}
+
+trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } }
+impl<T> Fake for T { }
diff --git a/src/test/ui/span/slice-borrow.stderr b/src/test/ui/span/slice-borrow.stderr
new file mode 100644
index 000000000..27df25be3
--- /dev/null
+++ b/src/test/ui/span/slice-borrow.stderr
@@ -0,0 +1,17 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/slice-borrow.rs:6:28
+ |
+LL | let x: &[isize] = &vec![1, 2, 3, 4, 5];
+ | ^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+LL | y.use_ref();
+ | ----------- borrow later used here
+ |
+ = note: consider using a `let` binding to create a longer lived value
+ = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/src/test/ui/span/suggestion-non-ascii.rs b/src/test/ui/span/suggestion-non-ascii.rs
new file mode 100644
index 000000000..914efd85a
--- /dev/null
+++ b/src/test/ui/span/suggestion-non-ascii.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let tup = (1,);
+ println!("☃{}", tup[0]); //~ ERROR cannot index into a value of type
+}
diff --git a/src/test/ui/span/suggestion-non-ascii.stderr b/src/test/ui/span/suggestion-non-ascii.stderr
new file mode 100644
index 000000000..b14632d4e
--- /dev/null
+++ b/src/test/ui/span/suggestion-non-ascii.stderr
@@ -0,0 +1,9 @@
+error[E0608]: cannot index into a value of type `({integer},)`
+ --> $DIR/suggestion-non-ascii.rs:3:21
+ |
+LL | println!("☃{}", tup[0]);
+ | ^^^^^^ help: to access tuple elements, use: `tup.0`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0608`.
diff --git a/src/test/ui/span/transitive-dep-span.rs b/src/test/ui/span/transitive-dep-span.rs
new file mode 100644
index 000000000..2d46f74ad
--- /dev/null
+++ b/src/test/ui/span/transitive-dep-span.rs
@@ -0,0 +1,15 @@
+// Tests that we properly serialize/deserialize spans from transitive dependencies
+// (e.g. imported SourceFiles)
+//
+// The order of these next lines is important, since we need
+// transitive_dep_two.rs to be able to reference transitive_dep_three.rs
+//
+// aux-build: transitive_dep_three.rs
+// aux-build: transitive_dep_two.rs
+// compile-flags: -Z macro-backtrace
+
+extern crate transitive_dep_two;
+
+transitive_dep_two::parse_error!(); //~ ERROR expected one of
+
+fn main() {}
diff --git a/src/test/ui/span/transitive-dep-span.stderr b/src/test/ui/span/transitive-dep-span.stderr
new file mode 100644
index 000000000..4dc3e5721
--- /dev/null
+++ b/src/test/ui/span/transitive-dep-span.stderr
@@ -0,0 +1,18 @@
+error: expected one of `!` or `::`, found `error`
+ --> $DIR/auxiliary/transitive_dep_three.rs:6:27
+ |
+LL | macro_rules! parse_error {
+ | ------------------------ in this expansion of `transitive_dep_two::parse_error!`
+LL | () => { parse error }
+ | ^^^^^ expected one of `!` or `::`
+ |
+ ::: $DIR/transitive-dep-span.rs:13:1
+ |
+LL | transitive_dep_two::parse_error!();
+ | ----------------------------------
+ | |
+ | in this macro invocation
+ | in this macro invocation
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/span/type-annotations-needed-expr.rs b/src/test/ui/span/type-annotations-needed-expr.rs
new file mode 100644
index 000000000..f64dab4d7
--- /dev/null
+++ b/src/test/ui/span/type-annotations-needed-expr.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let _ = (vec![1,2,3]).into_iter().sum() as f64; //~ ERROR E0282
+}
diff --git a/src/test/ui/span/type-annotations-needed-expr.stderr b/src/test/ui/span/type-annotations-needed-expr.stderr
new file mode 100644
index 000000000..9dff6c64d
--- /dev/null
+++ b/src/test/ui/span/type-annotations-needed-expr.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/type-annotations-needed-expr.rs:2:39
+ |
+LL | let _ = (vec![1,2,3]).into_iter().sum() as f64;
+ | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
+ |
+help: consider specifying the generic argument
+ |
+LL | let _ = (vec![1,2,3]).into_iter().sum::<S>() as f64;
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/span/type-binding.rs b/src/test/ui/span/type-binding.rs
new file mode 100644
index 000000000..32016e127
--- /dev/null
+++ b/src/test/ui/span/type-binding.rs
@@ -0,0 +1,9 @@
+// Regression test for issue #28158
+// Test the type binding span doesn't include >>
+
+use std::ops::Deref;
+
+fn homura<T: Deref<Trget = i32>>(_: T) {}
+//~^ ERROR not found
+
+fn main() {}
diff --git a/src/test/ui/span/type-binding.stderr b/src/test/ui/span/type-binding.stderr
new file mode 100644
index 000000000..cb0aefe06
--- /dev/null
+++ b/src/test/ui/span/type-binding.stderr
@@ -0,0 +1,9 @@
+error[E0220]: associated type `Trget` not found for `Deref`
+ --> $DIR/type-binding.rs:6:20
+ |
+LL | fn homura<T: Deref<Trget = i32>>(_: T) {}
+ | ^^^^^ help: there is an associated type with a similar name: `Target`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/src/test/ui/span/typo-suggestion.rs b/src/test/ui/span/typo-suggestion.rs
new file mode 100644
index 000000000..e9d7bc65e
--- /dev/null
+++ b/src/test/ui/span/typo-suggestion.rs
@@ -0,0 +1,9 @@
+fn main() {
+ let foo = 1;
+
+ // `foo` shouldn't be suggested, it is too dissimilar from `bar`.
+ println!("Hello {}", bar); //~ ERROR cannot find value
+
+ // But this is close enough.
+ println!("Hello {}", fob); //~ ERROR cannot find value
+}
diff --git a/src/test/ui/span/typo-suggestion.stderr b/src/test/ui/span/typo-suggestion.stderr
new file mode 100644
index 000000000..61d4e0611
--- /dev/null
+++ b/src/test/ui/span/typo-suggestion.stderr
@@ -0,0 +1,15 @@
+error[E0425]: cannot find value `bar` in this scope
+ --> $DIR/typo-suggestion.rs:5:26
+ |
+LL | println!("Hello {}", bar);
+ | ^^^ not found in this scope
+
+error[E0425]: cannot find value `fob` in this scope
+ --> $DIR/typo-suggestion.rs:8:26
+ |
+LL | println!("Hello {}", fob);
+ | ^^^ help: a local variable with a similar name exists: `foo`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/span/unused-warning-point-at-identifier.rs b/src/test/ui/span/unused-warning-point-at-identifier.rs
new file mode 100644
index 000000000..af4834503
--- /dev/null
+++ b/src/test/ui/span/unused-warning-point-at-identifier.rs
@@ -0,0 +1,30 @@
+// run-pass
+
+#![warn(unused)]
+
+enum Enum { //~ WARN enum `Enum` is never used
+ A,
+ B,
+ C,
+ D,
+}
+
+struct Struct { //~ WARN struct `Struct` is never constructed
+ a: usize,
+ b: usize,
+ c: usize,
+ d: usize,
+}
+
+fn func() -> usize { //~ WARN function `func` is never used
+ 3
+}
+
+fn
+func_complete_span() //~ WARN function `func_complete_span` is never used
+-> usize
+{
+ 3
+}
+
+fn main() {}
diff --git a/src/test/ui/span/unused-warning-point-at-identifier.stderr b/src/test/ui/span/unused-warning-point-at-identifier.stderr
new file mode 100644
index 000000000..c2cb56231
--- /dev/null
+++ b/src/test/ui/span/unused-warning-point-at-identifier.stderr
@@ -0,0 +1,33 @@
+warning: enum `Enum` is never used
+ --> $DIR/unused-warning-point-at-identifier.rs:5:6
+ |
+LL | enum Enum {
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-warning-point-at-identifier.rs:3:9
+ |
+LL | #![warn(unused)]
+ | ^^^^^^
+ = note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
+
+warning: struct `Struct` is never constructed
+ --> $DIR/unused-warning-point-at-identifier.rs:12:8
+ |
+LL | struct Struct {
+ | ^^^^^^
+
+warning: function `func` is never used
+ --> $DIR/unused-warning-point-at-identifier.rs:19:4
+ |
+LL | fn func() -> usize {
+ | ^^^^
+
+warning: function `func_complete_span` is never used
+ --> $DIR/unused-warning-point-at-identifier.rs:24:1
+ |
+LL | func_complete_span()
+ | ^^^^^^^^^^^^^^^^^^
+
+warning: 4 warnings emitted
+
diff --git a/src/test/ui/span/vec-must-not-hide-type-from-dropck.rs b/src/test/ui/span/vec-must-not-hide-type-from-dropck.rs
new file mode 100644
index 000000000..9bfbfab06
--- /dev/null
+++ b/src/test/ui/span/vec-must-not-hide-type-from-dropck.rs
@@ -0,0 +1,125 @@
+// Checking that `Vec<T>` cannot hide lifetimes within `T` when `T`
+// implements `Drop` and might access methods of values that have
+// since been deallocated.
+//
+// In this case, the values in question hold (non-zero) unique-ids
+// that zero themselves out when dropped, and are wrapped in another
+// type with a destructor that asserts that the ids it references are
+// indeed non-zero (i.e., effectively checking that the id's are not
+// dropped while there are still any outstanding references).
+//
+// However, the values in question are also formed into a
+// cyclic-structure, ensuring that there is no way for all of the
+// conditions above to be satisfied, meaning that if the dropck is
+// sound, it should reject this code.
+
+
+
+use std::cell::Cell;
+use id::Id;
+
+mod s {
+ use std::sync::atomic::{AtomicUsize, Ordering};
+
+ static S_COUNT: AtomicUsize = AtomicUsize::new(0);
+
+ /// generates globally unique count (global across the current
+ /// process, that is)
+ pub fn next_count() -> usize {
+ S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
+ }
+}
+
+mod id {
+ use s;
+
+ /// Id represents a globally unique identifier (global across the
+ /// current process, that is). When dropped, it automatically
+ /// clears its `count` field, but leaves `orig_count` untouched,
+ /// so that if there are subsequent (erroneous) invocations of its
+ /// method (which is unsound), we can observe it by seeing that
+ /// the `count` is 0 while the `orig_count` is non-zero.
+ #[derive(Debug)]
+ pub struct Id {
+ orig_count: usize,
+ count: usize,
+ }
+
+ impl Id {
+ /// Creates an `Id` with a globally unique count.
+ pub fn new() -> Id {
+ let c = s::next_count();
+ println!("building Id {}", c);
+ Id { orig_count: c, count: c }
+ }
+ /// returns the `count` of self; should be non-zero if
+ /// everything is working.
+ pub fn count(&self) -> usize {
+ println!("Id::count on {} returns {}", self.orig_count, self.count);
+ self.count
+ }
+ }
+
+ impl Drop for Id {
+ fn drop(&mut self) {
+ println!("dropping Id {}", self.count);
+ self.count = 0;
+ }
+ }
+}
+
+trait HasId {
+ fn count(&self) -> usize;
+}
+
+#[derive(Debug)]
+struct CheckId<T:HasId> {
+ v: T
+}
+
+#[allow(non_snake_case)]
+fn CheckId<T:HasId>(t: T) -> CheckId<T> { CheckId{ v: t } }
+
+impl<T:HasId> Drop for CheckId<T> {
+ fn drop(&mut self) {
+ assert!(self.v.count() > 0);
+ }
+}
+
+#[derive(Debug)]
+struct C<'a> {
+ id: Id,
+ v: Vec<CheckId<Cell<Option<&'a C<'a>>>>>,
+}
+
+impl<'a> HasId for Cell<Option<&'a C<'a>>> {
+ fn count(&self) -> usize {
+ match self.get() {
+ None => 1,
+ Some(c) => c.id.count(),
+ }
+ }
+}
+
+impl<'a> C<'a> {
+ fn new() -> C<'a> {
+ C { id: Id::new(), v: Vec::new() }
+ }
+}
+
+fn f() {
+ let (mut c1, mut c2);
+ c1 = C::new();
+ c2 = C::new();
+
+ c1.v.push(CheckId(Cell::new(None)));
+ c2.v.push(CheckId(Cell::new(None)));
+ c1.v[0].v.set(Some(&c2));
+ //~^ ERROR `c2` does not live long enough
+ c2.v[0].v.set(Some(&c1));
+ //~^ ERROR `c1` does not live long enough
+}
+
+fn main() {
+ f();
+}
diff --git a/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr b/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr
new file mode 100644
index 000000000..f87c32d1a
--- /dev/null
+++ b/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr
@@ -0,0 +1,29 @@
+error[E0597]: `c2` does not live long enough
+ --> $DIR/vec-must-not-hide-type-from-dropck.rs:117:24
+ |
+LL | c1.v[0].v.set(Some(&c2));
+ | ^^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `c2` dropped here while still borrowed
+ | borrow might be used here, when `c1` is dropped and runs the destructor for type `C<'_>`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `c1` does not live long enough
+ --> $DIR/vec-must-not-hide-type-from-dropck.rs:119:24
+ |
+LL | c2.v[0].v.set(Some(&c1));
+ | ^^^ borrowed value does not live long enough
+LL |
+LL | }
+ | -
+ | |
+ | `c1` dropped here while still borrowed
+ | borrow might be used here, when `c1` is dropped and runs the destructor for type `C<'_>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/vec_refs_data_with_early_death.rs b/src/test/ui/span/vec_refs_data_with_early_death.rs
new file mode 100644
index 000000000..c23c52115
--- /dev/null
+++ b/src/test/ui/span/vec_refs_data_with_early_death.rs
@@ -0,0 +1,33 @@
+// This test is a simple example of code that violates the dropck
+// rules: it pushes `&x` and `&y` into a bag (with dtor), but the
+// referenced data will be dropped before the bag is.
+
+
+
+
+
+
+
+fn main() {
+ let mut v = Bag::new();
+
+ let x: i8 = 3;
+ let y: i8 = 4;
+
+ v.push(&x);
+ //~^ ERROR `x` does not live long enough
+ v.push(&y);
+ //~^ ERROR `y` does not live long enough
+
+ assert_eq!(v.0, [&3, &4]);
+}
+
+//`Vec<T>` is #[may_dangle] w.r.t. `T`; putting a bag over its head
+// forces borrowck to treat dropping the bag as a potential use.
+struct Bag<T>(Vec<T>);
+impl<T> Drop for Bag<T> { fn drop(&mut self) { } }
+
+impl<T> Bag<T> {
+ fn new() -> Self { Bag(Vec::new()) }
+ fn push(&mut self, t: T) { self.0.push(t); }
+}
diff --git a/src/test/ui/span/vec_refs_data_with_early_death.stderr b/src/test/ui/span/vec_refs_data_with_early_death.stderr
new file mode 100644
index 000000000..684e78453
--- /dev/null
+++ b/src/test/ui/span/vec_refs_data_with_early_death.stderr
@@ -0,0 +1,31 @@
+error[E0597]: `x` does not live long enough
+ --> $DIR/vec_refs_data_with_early_death.rs:17:12
+ |
+LL | v.push(&x);
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `x` dropped here while still borrowed
+ | borrow might be used here, when `v` is dropped and runs the `Drop` code for type `Bag`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/vec_refs_data_with_early_death.rs:19:12
+ |
+LL | v.push(&y);
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | -
+ | |
+ | `y` dropped here while still borrowed
+ | borrow might be used here, when `v` is dropped and runs the `Drop` code for type `Bag`
+ |
+ = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/visibility-ty-params.rs b/src/test/ui/span/visibility-ty-params.rs
new file mode 100644
index 000000000..d77febe0a
--- /dev/null
+++ b/src/test/ui/span/visibility-ty-params.rs
@@ -0,0 +1,13 @@
+macro_rules! m {
+ ($p: path) => (pub(in $p) struct Z;)
+}
+
+struct S<T>(T);
+m!{ S<u8> } //~ ERROR unexpected generic arguments in path
+ //~| ERROR expected module, found struct `S`
+
+mod m {
+ m!{ m<> } //~ ERROR unexpected generic arguments in path
+}
+
+fn main() {}
diff --git a/src/test/ui/span/visibility-ty-params.stderr b/src/test/ui/span/visibility-ty-params.stderr
new file mode 100644
index 000000000..067893fd2
--- /dev/null
+++ b/src/test/ui/span/visibility-ty-params.stderr
@@ -0,0 +1,21 @@
+error: unexpected generic arguments in path
+ --> $DIR/visibility-ty-params.rs:6:6
+ |
+LL | m!{ S<u8> }
+ | ^^^^
+
+error[E0577]: expected module, found struct `S`
+ --> $DIR/visibility-ty-params.rs:6:5
+ |
+LL | m!{ S<u8> }
+ | ^^^^^ not a module
+
+error: unexpected generic arguments in path
+ --> $DIR/visibility-ty-params.rs:10:10
+ |
+LL | m!{ m<> }
+ | ^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0577`.
diff --git a/src/test/ui/span/wf-method-late-bound-regions.rs b/src/test/ui/span/wf-method-late-bound-regions.rs
new file mode 100644
index 000000000..ca9f73d0a
--- /dev/null
+++ b/src/test/ui/span/wf-method-late-bound-regions.rs
@@ -0,0 +1,24 @@
+// A method's receiver must be well-formed, even if it has late-bound regions.
+// Because of this, a method's substs being well-formed does not imply that
+// the method's implied bounds are met.
+
+struct Foo<'b>(Option<&'b ()>);
+
+trait Bar<'b> {
+ fn xmute<'a>(&'a self, u: &'b u32) -> &'a u32;
+}
+
+impl<'b> Bar<'b> for Foo<'b> {
+ fn xmute<'a>(&'a self, u: &'b u32) -> &'a u32 { u }
+}
+
+fn main() {
+ let f = Foo(None);
+ let f2 = f;
+ let dangling = {
+ let pointer = Box::new(42);
+ f2.xmute(&pointer)
+ };
+ //~^^ ERROR `pointer` does not live long enough
+ println!("{}", dangling);
+}
diff --git a/src/test/ui/span/wf-method-late-bound-regions.stderr b/src/test/ui/span/wf-method-late-bound-regions.stderr
new file mode 100644
index 000000000..6b0b00820
--- /dev/null
+++ b/src/test/ui/span/wf-method-late-bound-regions.stderr
@@ -0,0 +1,14 @@
+error[E0597]: `pointer` does not live long enough
+ --> $DIR/wf-method-late-bound-regions.rs:20:18
+ |
+LL | let dangling = {
+ | -------- borrow later stored here
+LL | let pointer = Box::new(42);
+LL | f2.xmute(&pointer)
+ | ^^^^^^^^ borrowed value does not live long enough
+LL | };
+ | - `pointer` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.