From 27893ddac516e7beac952ce0f73127964578d11c Mon Sep 17 00:00:00 2001 From: Bram van den Heuvel Date: Thu, 4 Nov 2021 10:57:42 +0100 Subject: [PATCH 1/6] Group commandline tests in a directory --- .../{ => commandline-argfile}/commandline-argfile-badutf8.args | 0 .../{ => commandline-argfile}/commandline-argfile-badutf8.rs | 2 +- .../commandline-argfile-badutf8.stderr | 0 .../commandline-argfile}/commandline-argfile-missing.rs | 2 +- .../commandline-argfile-missing.stderr | 0 .../{ => commandline-argfile}/commandline-argfile.args | 0 .../rustdoc-ui/{ => commandline-argfile}/commandline-argfile.rs | 2 +- .../ui/{ => command/argfile}/commandline-argfile-badutf8.args | 0 .../ui/{ => command/argfile}/commandline-argfile-badutf8.rs | 2 +- .../ui/{ => command/argfile}/commandline-argfile-badutf8.stderr | 0 .../command/argfile}/commandline-argfile-missing.rs | 2 +- .../ui/{ => command/argfile}/commandline-argfile-missing.stderr | 0 src/test/ui/{ => command/argfile}/commandline-argfile.args | 0 src/test/ui/{ => command/argfile}/commandline-argfile.rs | 2 +- src/test/ui/{ => command}/command-line-diagnostics.rs | 0 src/test/ui/{ => command}/command-line-diagnostics.stderr | 0 16 files changed, 6 insertions(+), 6 deletions(-) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile-badutf8.args (100%) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile-badutf8.rs (87%) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile-badutf8.stderr (100%) rename src/test/{ui => rustdoc-ui/commandline-argfile}/commandline-argfile-missing.rs (92%) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile-missing.stderr (100%) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile.args (100%) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile.rs (90%) rename src/test/ui/{ => command/argfile}/commandline-argfile-badutf8.args (100%) rename src/test/ui/{ => command/argfile}/commandline-argfile-badutf8.rs (67%) rename src/test/ui/{ => command/argfile}/commandline-argfile-badutf8.stderr (100%) rename src/test/{rustdoc-ui => ui/command/argfile}/commandline-argfile-missing.rs (79%) rename src/test/ui/{ => command/argfile}/commandline-argfile-missing.stderr (100%) rename src/test/ui/{ => command/argfile}/commandline-argfile.args (100%) rename src/test/ui/{ => command/argfile}/commandline-argfile.rs (70%) rename src/test/ui/{ => command}/command-line-diagnostics.rs (100%) rename src/test/ui/{ => command}/command-line-diagnostics.stderr (100%) diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.args b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.args similarity index 100% rename from src/test/rustdoc-ui/commandline-argfile-badutf8.args rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.args diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.rs b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.rs similarity index 87% rename from src/test/rustdoc-ui/commandline-argfile-badutf8.rs rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.rs index e2984e3ca97a..19e5dfb619c2 100644 --- a/src/test/rustdoc-ui/commandline-argfile-badutf8.rs +++ b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.rs @@ -1,6 +1,6 @@ // Check to see if we can get parameters from an @argsfile file // -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile/commandline-argfile-badutf8.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.stderr b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.stderr similarity index 100% rename from src/test/rustdoc-ui/commandline-argfile-badutf8.stderr rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.stderr diff --git a/src/test/ui/commandline-argfile-missing.rs b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-missing.rs similarity index 92% rename from src/test/ui/commandline-argfile-missing.rs rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile-missing.rs index 5a6465bd0646..e48e74cd9eed 100644 --- a/src/test/ui/commandline-argfile-missing.rs +++ b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-missing.rs @@ -2,7 +2,7 @@ // // normalize-stderr-test: "os error \d+" -> "os error $$ERR" // normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile/commandline-argfile-missing.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/rustdoc-ui/commandline-argfile-missing.stderr b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-missing.stderr similarity index 100% rename from src/test/rustdoc-ui/commandline-argfile-missing.stderr rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile-missing.stderr diff --git a/src/test/rustdoc-ui/commandline-argfile.args b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile.args similarity index 100% rename from src/test/rustdoc-ui/commandline-argfile.args rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile.args diff --git a/src/test/rustdoc-ui/commandline-argfile.rs b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile.rs similarity index 90% rename from src/test/rustdoc-ui/commandline-argfile.rs rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile.rs index cc8c8722c1c3..16184665d9e6 100644 --- a/src/test/rustdoc-ui/commandline-argfile.rs +++ b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile.rs @@ -1,7 +1,7 @@ // Check to see if we can get parameters from an @argsfile file // // check-pass -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile/commandline-argfile.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/ui/commandline-argfile-badutf8.args b/src/test/ui/command/argfile/commandline-argfile-badutf8.args similarity index 100% rename from src/test/ui/commandline-argfile-badutf8.args rename to src/test/ui/command/argfile/commandline-argfile-badutf8.args diff --git a/src/test/ui/commandline-argfile-badutf8.rs b/src/test/ui/command/argfile/commandline-argfile-badutf8.rs similarity index 67% rename from src/test/ui/commandline-argfile-badutf8.rs rename to src/test/ui/command/argfile/commandline-argfile-badutf8.rs index e2984e3ca97a..0e7407e2e207 100644 --- a/src/test/ui/commandline-argfile-badutf8.rs +++ b/src/test/ui/command/argfile/commandline-argfile-badutf8.rs @@ -1,6 +1,6 @@ // Check to see if we can get parameters from an @argsfile file // -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args +// compile-flags: --cfg cmdline_set @{{src-base}}/command/argfile/commandline-argfile-badutf8.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/ui/commandline-argfile-badutf8.stderr b/src/test/ui/command/argfile/commandline-argfile-badutf8.stderr similarity index 100% rename from src/test/ui/commandline-argfile-badutf8.stderr rename to src/test/ui/command/argfile/commandline-argfile-badutf8.stderr diff --git a/src/test/rustdoc-ui/commandline-argfile-missing.rs b/src/test/ui/command/argfile/commandline-argfile-missing.rs similarity index 79% rename from src/test/rustdoc-ui/commandline-argfile-missing.rs rename to src/test/ui/command/argfile/commandline-argfile-missing.rs index 5a6465bd0646..1cdead6f8e75 100644 --- a/src/test/rustdoc-ui/commandline-argfile-missing.rs +++ b/src/test/ui/command/argfile/commandline-argfile-missing.rs @@ -2,7 +2,7 @@ // // normalize-stderr-test: "os error \d+" -> "os error $$ERR" // normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args +// compile-flags: --cfg cmdline_set @{{src-base}}/command/argfile/commandline-argfile-missing.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/ui/commandline-argfile-missing.stderr b/src/test/ui/command/argfile/commandline-argfile-missing.stderr similarity index 100% rename from src/test/ui/commandline-argfile-missing.stderr rename to src/test/ui/command/argfile/commandline-argfile-missing.stderr diff --git a/src/test/ui/commandline-argfile.args b/src/test/ui/command/argfile/commandline-argfile.args similarity index 100% rename from src/test/ui/commandline-argfile.args rename to src/test/ui/command/argfile/commandline-argfile.args diff --git a/src/test/ui/commandline-argfile.rs b/src/test/ui/command/argfile/commandline-argfile.rs similarity index 70% rename from src/test/ui/commandline-argfile.rs rename to src/test/ui/command/argfile/commandline-argfile.rs index fc1ba0c8d677..40b8265cdecc 100644 --- a/src/test/ui/commandline-argfile.rs +++ b/src/test/ui/command/argfile/commandline-argfile.rs @@ -1,7 +1,7 @@ // Check to see if we can get parameters from an @argsfile file // // build-pass -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args +// compile-flags: --cfg cmdline_set @{{src-base}}/command/argfile/commandline-argfile.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/ui/command-line-diagnostics.rs b/src/test/ui/command/command-line-diagnostics.rs similarity index 100% rename from src/test/ui/command-line-diagnostics.rs rename to src/test/ui/command/command-line-diagnostics.rs diff --git a/src/test/ui/command-line-diagnostics.stderr b/src/test/ui/command/command-line-diagnostics.stderr similarity index 100% rename from src/test/ui/command-line-diagnostics.stderr rename to src/test/ui/command/command-line-diagnostics.stderr From 60767b8bcdbb5c30c0993376265beba166a64697 Mon Sep 17 00:00:00 2001 From: Lucas Kent Date: Sun, 7 Nov 2021 18:18:16 +1100 Subject: [PATCH 2/6] Improve diagnostics when a static lifetime is expected --- .../nice_region_error/named_anon_conflict.rs | 5 +++++ ...sure-bounds-static-cant-capture-borrowed.stderr | 2 ++ .../generator/generator-region-requirements.stderr | 3 +++ .../projection-type-lifetime-mismatch.stderr | 6 ++++++ .../issue-46983-expected-return-static.rs} | 0 .../issue-46983-expected-return-static.stderr} | 4 +++- .../issue-90600-expected-return-static-indirect.rs | 14 ++++++++++++++ ...ue-90600-expected-return-static-indirect.stderr | 12 ++++++++++++ .../region-lbr-anon-does-not-outlive-static.stderr | 2 ++ src/test/ui/nll/guarantor-issue-46974.stderr | 3 +++ .../ui/regions/regions-static-bound.migrate.stderr | 5 +++++ .../ui/regions/regions-static-bound.nll.stderr | 5 +++++ 12 files changed, 60 insertions(+), 1 deletion(-) rename src/test/ui/{issues/issue-46983.rs => lifetimes/issue-46983-expected-return-static.rs} (100%) rename src/test/ui/{issues/issue-46983.stderr => lifetimes/issue-46983-expected-return-static.stderr} (58%) create mode 100644 src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs create mode 100644 src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 0878f8550da3..98aab32763aa 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -123,6 +123,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { new_ty.to_string(), Applicability::Unspecified, ); + } else { + diag.span_label( + new_ty_span, + &format!("{} does not have lifetime `'static'`", span_label_var), + ); } Some(diag) diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr index a9add6184f13..2ef7b367e319 100644 --- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr +++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr @@ -1,6 +1,8 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5 | +LL | fn foo(x: &()) { + | --- the type of `x` does not have lifetime `'static'` LL | bar(|| { | ^^^ lifetime `'static` required diff --git a/src/test/ui/generator/generator-region-requirements.stderr b/src/test/ui/generator/generator-region-requirements.stderr index de90a599e76b..5603b6f96060 100644 --- a/src/test/ui/generator/generator-region-requirements.stderr +++ b/src/test/ui/generator/generator-region-requirements.stderr @@ -1,6 +1,9 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/generator-region-requirements.rs:12:51 | +LL | fn dangle(x: &mut i32) -> &'static mut i32 { + | -------- the type of `x` does not have lifetime `'static'` +... LL | GeneratorState::Complete(c) => return c, | ^ lifetime `'static` required diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr index 315bef16c5f1..00feb465786c 100644 --- a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr +++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr @@ -1,18 +1,24 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/projection-type-lifetime-mismatch.rs:17:5 | +LL | fn f(x: &impl for<'a> X = &'a ()>) -> &'static () { + | ------------------------------- the type of `x` does not have lifetime `'static'` LL | x.m() | ^^^^^ lifetime `'static` required error[E0621]: explicit lifetime required in the type of `x` --> $DIR/projection-type-lifetime-mismatch.rs:22:5 | +LL | fn g X = &'a ()>>(x: &T) -> &'static () { + | -- the type of `x` does not have lifetime `'static'` LL | x.m() | ^^^^^ lifetime `'static` required error[E0621]: explicit lifetime required in the type of `x` --> $DIR/projection-type-lifetime-mismatch.rs:27:5 | +LL | fn h(x: &()) -> &'static () { + | --- the type of `x` does not have lifetime `'static'` LL | x.m() | ^^^^^ lifetime `'static` required diff --git a/src/test/ui/issues/issue-46983.rs b/src/test/ui/lifetimes/issue-46983-expected-return-static.rs similarity index 100% rename from src/test/ui/issues/issue-46983.rs rename to src/test/ui/lifetimes/issue-46983-expected-return-static.rs diff --git a/src/test/ui/issues/issue-46983.stderr b/src/test/ui/lifetimes/issue-46983-expected-return-static.stderr similarity index 58% rename from src/test/ui/issues/issue-46983.stderr rename to src/test/ui/lifetimes/issue-46983-expected-return-static.stderr index d328329edad2..1b58e3b06353 100644 --- a/src/test/ui/issues/issue-46983.stderr +++ b/src/test/ui/lifetimes/issue-46983-expected-return-static.stderr @@ -1,6 +1,8 @@ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/issue-46983.rs:2:5 + --> $DIR/issue-46983-expected-return-static.rs:2:5 | +LL | fn foo(x: &u32) -> &'static u32 { + | ---- the type of `x` does not have lifetime `'static'` LL | &*x | ^^^ lifetime `'static` required diff --git a/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs new file mode 100644 index 000000000000..fc3911efeb1e --- /dev/null +++ b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs @@ -0,0 +1,14 @@ +use std::cell::RefCell; +use std::io::Read; + +fn main() {} + +fn inner(mut foo: &[u8]) { + let refcell = RefCell::new(&mut foo); + let read = &refcell as &RefCell; + + read_thing(read); + //~^ ERROR explicit lifetime required in the type of `foo` [E0621] +} + +fn read_thing(refcell: &RefCell) {} diff --git a/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr new file mode 100644 index 000000000000..eb51f5c747b4 --- /dev/null +++ b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr @@ -0,0 +1,12 @@ +error[E0621]: explicit lifetime required in the type of `foo` + --> $DIR/issue-90600-expected-return-static-indirect.rs:10:16 + | +LL | fn inner(mut foo: &[u8]) { + | ----- the type of `foo` does not have lifetime `'static'` +... +LL | read_thing(read); + | ^^^^ lifetime `'static` required + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr index 4c302d935db9..a055f1878311 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr @@ -1,6 +1,8 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/region-lbr-anon-does-not-outlive-static.rs:9:5 | +LL | fn foo(x: &u32) -> &'static u32 { + | ---- the type of `x` does not have lifetime `'static'` LL | &*x | ^^^ lifetime `ReStatic` required diff --git a/src/test/ui/nll/guarantor-issue-46974.stderr b/src/test/ui/nll/guarantor-issue-46974.stderr index eabc3105c029..e1772a55b518 100644 --- a/src/test/ui/nll/guarantor-issue-46974.stderr +++ b/src/test/ui/nll/guarantor-issue-46974.stderr @@ -12,6 +12,9 @@ LL | *x error[E0621]: explicit lifetime required in the type of `s` --> $DIR/guarantor-issue-46974.rs:15:5 | +LL | fn bar(s: &Box<(i32,)>) -> &'static i32 { + | ------------ the type of `s` does not have lifetime `'static'` +LL | // FIXME(#46983): error message should be better LL | &s.0 | ^^^^ lifetime `'static` required diff --git a/src/test/ui/regions/regions-static-bound.migrate.stderr b/src/test/ui/regions/regions-static-bound.migrate.stderr index 8f11e148220d..956ebd8cac23 100644 --- a/src/test/ui/regions/regions-static-bound.migrate.stderr +++ b/src/test/ui/regions/regions-static-bound.migrate.stderr @@ -14,12 +14,17 @@ LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { error[E0621]: explicit lifetime required in the type of `u` --> $DIR/regions-static-bound.rs:14:5 | +LL | fn error(u: &(), v: &()) { + | --- the type of `u` does not have lifetime `'static'` LL | static_id(&u); | ^^^^^^^^^ lifetime `'static` required error[E0621]: explicit lifetime required in the type of `v` --> $DIR/regions-static-bound.rs:16:5 | +LL | fn error(u: &(), v: &()) { + | --- the type of `v` does not have lifetime `'static'` +... LL | static_id_indirect(&v); | ^^^^^^^^^^^^^^^^^^ lifetime `'static` required diff --git a/src/test/ui/regions/regions-static-bound.nll.stderr b/src/test/ui/regions/regions-static-bound.nll.stderr index a280c6f0a02d..b2797b30e485 100644 --- a/src/test/ui/regions/regions-static-bound.nll.stderr +++ b/src/test/ui/regions/regions-static-bound.nll.stderr @@ -9,12 +9,17 @@ LL | t error[E0621]: explicit lifetime required in the type of `u` --> $DIR/regions-static-bound.rs:14:5 | +LL | fn error(u: &(), v: &()) { + | --- the type of `u` does not have lifetime `'static'` LL | static_id(&u); | ^^^^^^^^^^^^^ lifetime `'static` required error[E0621]: explicit lifetime required in the type of `v` --> $DIR/regions-static-bound.rs:16:5 | +LL | fn error(u: &(), v: &()) { + | --- the type of `v` does not have lifetime `'static'` +... LL | static_id_indirect(&v); | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required From 958de5a93864b90e7f90d7a5d0ce082c34232b59 Mon Sep 17 00:00:00 2001 From: Gus Wynn Date: Wed, 6 Oct 2021 13:19:39 -0700 Subject: [PATCH 3/6] warn on must_use use on async fn's --- compiler/rustc_passes/src/check_attr.rs | 32 +++++++++++++++ src/test/ui/lint/unused/unused-async.rs | 43 +++++++++++++++++++++ src/test/ui/lint/unused/unused-async.stderr | 26 +++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 src/test/ui/lint/unused/unused-async.rs create mode 100644 src/test/ui/lint/unused/unused-async.stderr diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 596d13d2d9ac..633a90dd0ec7 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -112,6 +112,7 @@ impl CheckAttrVisitor<'tcx> { self.check_default_method_body_is_const(attr, span, target) } sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target), + sym::must_use => self.check_must_use(hir_id, &attr, span, target), sym::rustc_const_unstable | sym::rustc_const_stable | sym::unstable @@ -1046,6 +1047,37 @@ impl CheckAttrVisitor<'tcx> { is_valid } + /// Warns against some misuses of `#[must_use]` + fn check_must_use( + &self, + hir_id: HirId, + attr: &Attribute, + span: &Span, + _target: Target, + ) -> bool { + let node = self.tcx.hir().get(hir_id); + if let Some(fn_node) = node.fn_kind() { + if let rustc_hir::IsAsync::Async = fn_node.asyncness() { + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build( + "`must_use` attribute on `async` functions \ + applies to the anonymous `Future` returned by the \ + function, not the value within.", + ) + .span_label( + *span, + "this attribute does nothing, the `Future`s \ + returned by async functions are already `must_use`", + ) + .emit(); + }); + } + } + + // For now, its always valid + true + } + /// Checks if `#[must_not_suspend]` is applied to a function. Returns `true` if valid. fn check_must_not_suspend(&self, attr: &Attribute, span: &Span, target: Target) -> bool { match target { diff --git a/src/test/ui/lint/unused/unused-async.rs b/src/test/ui/lint/unused/unused-async.rs new file mode 100644 index 000000000000..7d17af115737 --- /dev/null +++ b/src/test/ui/lint/unused/unused-async.rs @@ -0,0 +1,43 @@ +// edition:2018 +// run-pass +#![allow(dead_code)] + +#[must_use] +//~^ WARNING `must_use` +async fn test() -> i32 { + 1 +} + + +struct Wowee {} + +impl Wowee { + #[must_use] + //~^ WARNING `must_use` + async fn test_method() -> i32 { + 1 + } +} + +/* FIXME(guswynn) update this test when async-fn-in-traits works +trait Doer { + #[must_use] + async fn test_trait_method() -> i32; + WARNING must_use + async fn test_other_trait() -> i32; +} + +impl Doer for Wowee { + async fn test_trait_method() -> i32 { + 1 + } + #[must_use] + async fn test_other_trait() -> i32 { + WARNING must_use + 1 + } +} +*/ + +fn main() { +} diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr new file mode 100644 index 000000000000..e470b6dac947 --- /dev/null +++ b/src/test/ui/lint/unused/unused-async.stderr @@ -0,0 +1,26 @@ +warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within. + --> $DIR/unused-async.rs:5:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ +LL | +LL | / async fn test() -> i32 { +LL | | 1 +LL | | } + | |_- this attribute does nothing, the `Future`s returned by async functions are already `must_use` + | + = note: `#[warn(unused_attributes)]` on by default + +warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within. + --> $DIR/unused-async.rs:15:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ +LL | +LL | / async fn test_method() -> i32 { +LL | | 1 +LL | | } + | |_____- this attribute does nothing, the `Future`s returned by async functions are already `must_use` + +warning: 2 warnings emitted + From 26ca71fdb2070ae970ea9ce40a52a7b663897940 Mon Sep 17 00:00:00 2001 From: b-naber Date: Tue, 9 Nov 2021 20:21:51 +0100 Subject: [PATCH 4/6] normalize argument b in equate_normalized_inputs_output --- .../src/type_check/input_output.rs | 60 ++++++++++++------- compiler/rustc_borrowck/src/type_check/mod.rs | 5 +- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 24332690bec3..92d2d04f23f2 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -7,13 +7,16 @@ //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! contain revealed `impl Trait` values). +use crate::type_check::constraint_conversion::ConstraintConversion; use rustc_index::vec::Idx; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::mir::*; -use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::Ty; use rustc_span::Span; -use rustc_trait_selection::traits::query::normalize::AtExt; +use rustc_span::DUMMY_SP; +use rustc_trait_selection::traits::query::type_op::{self, TypeOp}; +use rustc_trait_selection::traits::query::Fallible; +use type_op::TypeOpOutput; use crate::universal_regions::UniversalRegions; @@ -30,6 +33,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let (&normalized_output_ty, normalized_input_tys) = normalized_inputs_and_output.split_last().unwrap(); + debug!(?normalized_output_ty); + debug!(?normalized_input_tys); + let mir_def_id = body.source.def_id().expect_local(); // If the user explicitly annotated the input types, extract @@ -75,10 +81,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .delay_span_bug(body.span, "found more normalized_input_ty than local_decls"); break; } + // In MIR, argument N is stored in local N+1. let local = Local::new(argument_index + 1); let mir_input_ty = body.local_decls[local].ty; + let mir_input_span = body.local_decls[local].source_info.span; self.equate_normalized_input_or_output( normalized_input_ty, @@ -100,6 +108,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // If the user explicitly annotated the input types, enforce those. let user_provided_input_ty = self.normalize(user_provided_input_ty, Locations::All(mir_input_span)); + self.equate_normalized_input_or_output( user_provided_input_ty, mir_input_ty, @@ -167,30 +176,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd // like to normalize *before* inserting into `local_decls`, but // doing so ends up causing some other trouble. - let b = match self - .infcx - .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) - .normalize(b) - { - Ok(n) => { - debug!("equate_inputs_and_outputs: {:?}", n); - if n.obligations.iter().all(|o| { - matches!( - o.predicate.kind().skip_binder(), - ty::PredicateKind::RegionOutlives(_) - | ty::PredicateKind::TypeOutlives(_) - ) - }) { - n.value - } else { - b - } - } + let b = match self.normalize_and_add_constraints(b) { + Ok(n) => n, Err(_) => { debug!("equate_inputs_and_outputs: NoSolution"); b } }; + // Note: if we have to introduce new placeholders during normalization above, then we won't have // added those universes to the universe info, which we would want in `relate_tys`. if let Err(terr) = @@ -207,4 +200,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } } + + pub(crate) fn normalize_and_add_constraints(&mut self, t: Ty<'tcx>) -> Fallible> { + let TypeOpOutput { output: norm_ty, constraints, .. } = + self.param_env.and(type_op::normalize::Normalize::new(t)).fully_perform(self.infcx)?; + + debug!("{:?} normalized to {:?}", t, norm_ty); + + for data in constraints.into_iter().collect::>() { + ConstraintConversion::new( + self.infcx, + &self.borrowck_context.universal_regions, + &self.region_bound_pairs, + Some(self.implicit_region_bound), + self.param_env, + Locations::All(DUMMY_SP), + ConstraintCategory::Internal, + &mut self.borrowck_context.constraints, + ) + .convert_all(&*data); + } + + Ok(norm_ty) + } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index ddd077c22faf..da26d9c7b877 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -893,11 +893,11 @@ struct TypeChecker<'a, 'tcx> { } struct BorrowCheckContext<'a, 'tcx> { - universal_regions: &'a UniversalRegions<'tcx>, + pub(crate) universal_regions: &'a UniversalRegions<'tcx>, location_table: &'a LocationTable, all_facts: &'a mut Option, borrow_set: &'a BorrowSet<'tcx>, - constraints: &'a mut MirTypeckRegionConstraints<'tcx>, + pub(crate) constraints: &'a mut MirTypeckRegionConstraints<'tcx>, upvars: &'a [Upvar<'tcx>], } @@ -1157,6 +1157,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category) } + #[instrument(skip(self, category), level = "debug")] fn eq_types( &mut self, expected: Ty<'tcx>, From 6b3695d480cfb6f61f59df1184239e16dc1c6795 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 12 Nov 2021 15:25:13 +0100 Subject: [PATCH 5/6] Remove unneeded FIXME: after testing the suggested changes, we reached the conclusion that the code readibility wasn't worth the almost unnoticeable perf improvement --- src/librustdoc/html/render/cache.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index ff1bd5e7ff28..e2b7b2147399 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -377,13 +377,9 @@ crate fn get_all_types<'tcx>( if arg.type_.is_self_type() { continue; } - // FIXME: performance wise, it'd be much better to move `args` declaration outside of the - // loop and replace this line with `args.clear()`. let mut args = Vec::new(); get_real_types(generics, &arg.type_, tcx, 0, &mut args); if !args.is_empty() { - // FIXME: once back to performance improvements, replace this line with: - // `all_types.extend(args.drain(..));`. all_types.extend(args); } else { if let Some(kind) = arg.type_.def_id_no_primitives().map(|did| tcx.def_kind(did).into()) From 7a4aa65810b1e77f5bbfa442ca36b6fd9530e4be Mon Sep 17 00:00:00 2001 From: b-naber Date: Tue, 9 Nov 2021 20:41:13 +0100 Subject: [PATCH 6/6] add tests --- .../normalize-under-binder/issue-90612.rs | 43 +++++++++++++++++++ .../normalize-under-binder/issue-90638.rs | 37 ++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs new file mode 100644 index 000000000000..e150ecfe9a0d --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs @@ -0,0 +1,43 @@ +// check-pass + +#![feature(generic_associated_types)] + +use std::marker::PhantomData; + +trait Family: Sized { + type Item<'a>; + + fn apply_all(&self, f: F) + where + F: FamilyItemFn { } +} + +struct Array(PhantomData); + +impl Family for Array { + type Item<'a> = &'a T; +} + +trait FamilyItemFn { + fn apply(&self, item: T::Item<'_>); +} + +impl FamilyItemFn for F +where + T: Family, + for<'a> F: Fn(T::Item<'a>) +{ + fn apply(&self, item: T::Item<'_>) { + (*self)(item); + } +} + +fn process(array: Array) { + // Works + array.apply_all(|x: &T| { }); + + // ICE: NoSolution + array.apply_all(|x: as Family>::Item<'_>| { }); +} + +fn main() {} diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs new file mode 100644 index 000000000000..18b7f383482a --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs @@ -0,0 +1,37 @@ +//check-pass + +#![feature(generic_associated_types)] + +trait Yokeable<'a>: 'static { + type Output: 'a; +} + +trait IsCovariant<'a> {} + +struct Yoke Yokeable<'a>> { + data: Y, +} + +impl Yokeable<'a>> Yoke { + fn project Yokeable<'a>>(&self, _f: for<'a> fn(>::Output, &'a ()) + -> >::Output) -> Yoke { + + unimplemented!() + } +} + +fn _upcast(x: Yoke) -> Yoke + 'static>> where + Y: for<'a> Yokeable<'a>, + for<'a> >::Output: IsCovariant<'a> + { + x.project(|data, _| { + Box::new(data) + }) +} + + +impl<'a> Yokeable<'a> for Box + 'static> { + type Output = Box + 'a>; +} + +fn main() {}