From dd2356fe7d8500a2b555a8b43761625e17223860 Mon Sep 17 00:00:00 2001 From: csmoe Date: Sun, 6 Oct 2019 21:57:23 +0800 Subject: [PATCH 01/17] add testcase for generator move suggestion --- .../async-borrowck-escaping-block-error.rs | 9 ++++++++ ...async-borrowck-escaping-block-error.stderr | 22 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/test/ui/async-await/async-borrowck-escaping-block-error.rs create mode 100644 src/test/ui/async-await/async-borrowck-escaping-block-error.stderr diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.rs b/src/test/ui/async-await/async-borrowck-escaping-block-error.rs new file mode 100644 index 0000000000000..49f59e4149313 --- /dev/null +++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.rs @@ -0,0 +1,9 @@ +// edition:2018 +#![feature(async_closure,async_await)] +fn foo() -> Box> { + let x = 0u32; + Box::new(async { x } ) + //~^ ERROR E0373 +} + +fn main() {} diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr new file mode 100644 index 0000000000000..5771ccbcf9d1e --- /dev/null +++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr @@ -0,0 +1,22 @@ +error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function + --> $DIR/async-borrowck-escaping-block-error.rs:5:20 + | +LL | Box::new(async { x } ) + | ^^-^^ + | | | + | | `x` is borrowed here + | may outlive borrowed value `x` + | +note: generator is returned here + --> $DIR/async-borrowck-escaping-block-error.rs:3:13 + | +LL | fn foo() -> Box> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword + | +LL | Box::new(async move { x } ) + | ^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0373`. From 50932ea1dae96a15e8f457e4e038d0e5218d2cad Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Sun, 6 Oct 2019 23:58:07 +0200 Subject: [PATCH 02/17] add more info in debug traces for gcu merging --- src/librustc_mir/monomorphize/partitioning.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index c193911247e2b..61868b24c0b8a 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -494,6 +494,9 @@ fn merge_codegen_units<'tcx>( for (k, v) in smallest.items_mut().drain() { second_smallest.items_mut().insert(k, v); } + debug!("CodegenUnit {} merged in to CodegenUnit {}", + smallest.name(), + second_smallest.name()); } let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); @@ -774,7 +777,7 @@ where if cfg!(debug_assertions) { debug!("{}", label); for cgu in cgus { - debug!("CodegenUnit {}:", cgu.name()); + debug!("CodegenUnit {} estimated size {} :", cgu.name(), cgu.size_estimate()); for (mono_item, linkage) in cgu.items() { let symbol_name = mono_item.symbol_name(tcx).name.as_str(); @@ -782,10 +785,11 @@ where let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..]) .unwrap_or(""); - debug!(" - {} [{:?}] [{}]", + debug!(" - {} [{:?}] [{}] estimated size {}", mono_item.to_string(tcx, true), linkage, - symbol_hash); + symbol_hash, + mono_item.size_estimate(tcx)); } debug!(""); From 543449d4fdf7bb7fd4a12c2fea96dafbe26eea90 Mon Sep 17 00:00:00 2001 From: Ayose Date: Sat, 20 Jul 2019 00:55:58 +0000 Subject: [PATCH 03/17] [RFC 2091] Add #[track_caller] attribute. - The attribute is behind a feature gate. - Error if both #[naked] and #[track_caller] are applied to the same function. - Error if #[track_caller] is applied to a non-function item. - Error if ABI is not "rust" - Error if #[track_caller] is applied to a trait function. Error codes and descriptions are pending. --- .../src/language-features/track-caller.md | 5 +++ src/librustc/error_codes.rs | 10 ++++++ src/librustc/hir/check_attr.rs | 34 +++++++++++++++++++ src/librustc/hir/mod.rs | 4 ++- src/librustc_typeck/check/wfcheck.rs | 12 +++++++ src/librustc_typeck/collect.rs | 10 ++++++ src/librustc_typeck/error_codes.rs | 11 ++++++ src/libsyntax/feature_gate/active.rs | 3 ++ src/libsyntax/feature_gate/builtin_attrs.rs | 4 +++ src/libsyntax_pos/symbol.rs | 1 + .../feature-gate-track_caller.rs | 6 ++++ .../feature-gate-track_caller.stderr | 12 +++++++ .../rfc-2091-track-caller/error-odd-syntax.rs | 7 ++++ .../error-odd-syntax.stderr | 8 +++++ .../error-with-invalid-abi.rs | 7 ++++ .../error-with-invalid-abi.stderr | 9 +++++ .../rfc-2091-track-caller/error-with-naked.rs | 8 +++++ .../error-with-naked.stderr | 9 +++++ .../error-with-trait-fns.rs | 13 +++++++ .../error-with-trait-fns.stderr | 9 +++++ .../ui/rfc-2091-track-caller/only-for-fns.rs | 7 ++++ .../rfc-2091-track-caller/only-for-fns.stderr | 11 ++++++ 22 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 src/doc/unstable-book/src/language-features/track-caller.md create mode 100644 src/test/ui/feature-gates/feature-gate-track_caller.rs create mode 100644 src/test/ui/feature-gates/feature-gate-track_caller.stderr create mode 100644 src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs create mode 100644 src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr create mode 100644 src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs create mode 100644 src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr create mode 100644 src/test/ui/rfc-2091-track-caller/error-with-naked.rs create mode 100644 src/test/ui/rfc-2091-track-caller/error-with-naked.stderr create mode 100644 src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs create mode 100644 src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr create mode 100644 src/test/ui/rfc-2091-track-caller/only-for-fns.rs create mode 100644 src/test/ui/rfc-2091-track-caller/only-for-fns.stderr diff --git a/src/doc/unstable-book/src/language-features/track-caller.md b/src/doc/unstable-book/src/language-features/track-caller.md new file mode 100644 index 0000000000000..afc11a2b9492c --- /dev/null +++ b/src/doc/unstable-book/src/language-features/track-caller.md @@ -0,0 +1,5 @@ +# `track_caller` + +The tracking issue for this feature is: [#47809](https://github.com/rust-lang/rust/issues/47809). + +------------------------ diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 502172db91c9b..959a06c2e32f6 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -1640,6 +1640,16 @@ each method; it is not possible to annotate the entire impl with an `#[inline]` attribute. "##, +E0900: r##" +TODO: change error number +TODO: track_caller: invalid syntax +"##, + +E0901: r##" +TODO: change error number +TODO: track_caller: no naked functions +"##, + E0522: r##" The lang attribute is intended for marking special items that are built-in to Rust itself. This includes special traits (like `Copy` and `Sized`) that affect diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index d5e956555bdfb..31a09645d1691 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -94,6 +94,7 @@ impl CheckAttrVisitor<'tcx> { /// Checks any attribute. fn check_attributes(&self, item: &hir::Item, target: Target) { let mut is_valid = true; + let mut track_caller_span = None; for attr in &item.attrs { is_valid &= if attr.check_name(sym::inline) { self.check_inline(attr, &item.span, target) @@ -103,6 +104,9 @@ impl CheckAttrVisitor<'tcx> { self.check_marker(attr, item, target) } else if attr.check_name(sym::target_feature) { self.check_target_feature(attr, item, target) + } else if attr.check_name(sym::track_caller) { + track_caller_span = Some(attr.span); + self.check_track_caller(attr, &item, target) } else { true }; @@ -118,6 +122,19 @@ impl CheckAttrVisitor<'tcx> { self.check_repr(item, target); self.check_used(item, target); + + // Checks if `#[track_caller]` and `#[naked]` are both used. + if let Some(span) = track_caller_span { + if item.attrs.iter().any(|attr| attr.check_name(sym::naked)) { + struct_span_err!( + self.tcx.sess, + span, + E0901, + "cannot use `#[track_caller]` with `#[naked]`", + ) + .emit(); + } + } } /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid. @@ -135,6 +152,23 @@ impl CheckAttrVisitor<'tcx> { } } + /// Checks if a `#[target_feature]` can be applied. + fn check_track_caller(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) -> bool { + if target != Target::Fn { + struct_span_err!( + self.tcx.sess, + attr.span, + E0900, + "attribute should be applied to function" + ) + .span_label(item.span, "not a function") + .emit(); + false + } else { + true + } + } + /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid. fn check_non_exhaustive( &self, diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 30b0503668877..f7240d6bf820e 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -2721,7 +2721,9 @@ bitflags! { const USED = 1 << 9; /// #[ffi_returns_twice], indicates that an extern function can return /// multiple times - const FFI_RETURNS_TWICE = 1 << 10; + const FFI_RETURNS_TWICE = 1 << 10; + /// #[track_caller]: allow access to the caller location + const TRACK_CALLER = 1 << 11; } } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index e736a55a5f51c..3c9010de5cb77 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -172,6 +172,18 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { _ => None }; check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig); + + // Prohibits applying `#[track_caller]` to trait methods + for attr in &trait_item.attrs { + if attr.check_name(sym::track_caller) { + struct_span_err!( + tcx.sess, + attr.span, + E0903, + "`#[track_caller]` is not supported for trait items yet." + ).emit(); + } + } } pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 64eca1371447b..0b98e4b781d77 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2594,6 +2594,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; } else if attr.check_name(sym::thread_local) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL; + } else if attr.check_name(sym::track_caller) { + if tcx.fn_sig(id).abi() != abi::Abi::Rust { + struct_span_err!( + tcx.sess, + attr.span, + E0902, + "rust ABI is required to use `#[track_caller]`" + ).emit(); + } + codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; } else if attr.check_name(sym::export_name) { if let Some(s) = attr.value_str() { if s.as_str().contains("\0") { diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index 3a07171b12fb8..f698427c78add 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -4907,6 +4907,17 @@ fn foo_recursive(n: usize) -> Pin>> { The `Box<...>` ensures that the result is of known size, and the pin is required to keep it in the same place in memory. "##, + +E0902: r##" +TODO: change error number +TODO: track_caller: require Rust ABI to use track_caller +"##, + +E0903: r##" +TODO: change error number +TODO: track_caller: can't apply in traits +"##, + ; // E0035, merged into E0087/E0089 // E0036, merged into E0087/E0089 diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index 19ef430318d3e..312a9bf6e755f 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -525,6 +525,9 @@ declare_features! ( // Allows the use of raw-dylibs (RFC 2627). (active, raw_dylib, "1.40.0", Some(58713), None), + /// Enable accurate caller location reporting during panic (RFC 2091). + (active, track_caller, "1.37.0", Some(47809), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs index c12d0ce06ffef..d6a6450e471bd 100644 --- a/src/libsyntax/feature_gate/builtin_attrs.rs +++ b/src/libsyntax/feature_gate/builtin_attrs.rs @@ -499,6 +499,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ cfg_fn!(no_debug) ) ), + gated!( + track_caller, Whitelisted, template!(Word), + "the `#[track_caller]` attribute is an experimental feature", + ), gated!( // Used in resolve: prelude_import, Whitelisted, template!(Word), diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index c7230d5ca1522..2b005c3fc421a 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -674,6 +674,7 @@ symbols! { tool_attributes, tool_lints, trace_macros, + track_caller, trait_alias, transmute, transparent, diff --git a/src/test/ui/feature-gates/feature-gate-track_caller.rs b/src/test/ui/feature-gates/feature-gate-track_caller.rs new file mode 100644 index 0000000000000..458df0b2b0281 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-track_caller.rs @@ -0,0 +1,6 @@ + +#[track_caller] +fn f() {} +//~^^ ERROR the `#[track_caller]` attribute is an experimental feature + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-track_caller.stderr b/src/test/ui/feature-gates/feature-gate-track_caller.stderr new file mode 100644 index 0000000000000..9a058736e5080 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-track_caller.stderr @@ -0,0 +1,12 @@ +error[E0658]: the `#[track_caller]` attribute is an experimental feature + --> $DIR/feature-gate-track_caller.rs:2:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/47809 + = help: add `#![feature(track_caller)]` 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/rfc-2091-track-caller/error-odd-syntax.rs b/src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs new file mode 100644 index 0000000000000..d6560231871c9 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs @@ -0,0 +1,7 @@ +#![feature(track_caller)] + +#[track_caller(1)] +fn f() {} +//~^^ ERROR malformed `track_caller` attribute input + +fn main() {} diff --git a/src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr b/src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr new file mode 100644 index 0000000000000..8906fa59506a7 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr @@ -0,0 +1,8 @@ +error: malformed `track_caller` attribute input + --> $DIR/error-odd-syntax.rs:3:1 + | +LL | #[track_caller(1)] + | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[track_caller]` + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs new file mode 100644 index 0000000000000..5c42a1b3faa2d --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs @@ -0,0 +1,7 @@ +#![feature(track_caller)] + +#[track_caller] +extern "C" fn f() {} +//~^^ ERROR rust ABI is required to use `#[track_caller]` + +fn main() {} diff --git a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr new file mode 100644 index 0000000000000..fc6f4d17dcc42 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr @@ -0,0 +1,9 @@ +error[E0902]: rust ABI is required to use `#[track_caller]` + --> $DIR/error-with-invalid-abi.rs:3:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0902`. diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs new file mode 100644 index 0000000000000..dd9e5d0413585 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs @@ -0,0 +1,8 @@ +#![feature(naked_functions, track_caller)] + +#[track_caller] +#[naked] +fn f() {} +//~^^^ ERROR cannot use `#[track_caller]` with `#[naked]` + +fn main() {} diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr new file mode 100644 index 0000000000000..3566d288ed10b --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr @@ -0,0 +1,9 @@ +error[E0901]: cannot use `#[track_caller]` with `#[naked]` + --> $DIR/error-with-naked.rs:3:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0901`. diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs b/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs new file mode 100644 index 0000000000000..c00cf7367ce54 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs @@ -0,0 +1,13 @@ +#![feature(track_caller)] + +trait Trait { + #[track_caller] + fn unwrap(&self); + //~^^ ERROR: `#[track_caller]` is not supported for trait items yet. +} + +impl Trait for u64 { + fn unwrap(&self) {} +} + +fn main() {} diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr b/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr new file mode 100644 index 0000000000000..bd3d4043a642b --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr @@ -0,0 +1,9 @@ +error[E0903]: `#[track_caller]` is not supported for trait items yet. + --> $DIR/error-with-trait-fns.rs:4:5 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0903`. diff --git a/src/test/ui/rfc-2091-track-caller/only-for-fns.rs b/src/test/ui/rfc-2091-track-caller/only-for-fns.rs new file mode 100644 index 0000000000000..0fd59b4bf4918 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/only-for-fns.rs @@ -0,0 +1,7 @@ +#![feature(track_caller)] + +#[track_caller] +struct S; +//~^^ ERROR attribute should be applied to function + +fn main() {} diff --git a/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr new file mode 100644 index 0000000000000..9ddc99c02bf9c --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr @@ -0,0 +1,11 @@ +error[E0900]: attribute should be applied to function + --> $DIR/only-for-fns.rs:3:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ +LL | struct S; + | --------- not a function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0900`. From 6c04c8eb8e361649fb541f918e373b23d2d7f772 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Wed, 2 Oct 2019 18:24:10 -0700 Subject: [PATCH 04/17] track_caller run-pass test, lint cleanup, PR review. --- src/librustc/error_codes.rs | 8 +++--- src/librustc/hir/check_attr.rs | 28 ++++++++----------- src/librustc_typeck/error_codes.rs | 8 +++--- src/libsyntax/feature_gate/active.rs | 2 +- src/libsyntax/feature_gate/builtin_attrs.rs | 5 +--- .../feature-gate-track_caller.rs | 1 - .../feature-gate-track_caller.stderr | 2 +- src/test/ui/rfc-2091-track-caller/pass.rs | 9 ++++++ 8 files changed, 31 insertions(+), 32 deletions(-) create mode 100644 src/test/ui/rfc-2091-track-caller/pass.rs diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 959a06c2e32f6..b2671e48be684 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -1641,13 +1641,13 @@ attribute. "##, E0900: r##" -TODO: change error number -TODO: track_caller: invalid syntax +FIXME(anp): change error number +FIXME(anp): track_caller: invalid syntax "##, E0901: r##" -TODO: change error number -TODO: track_caller: no naked functions +FIXME(anp): change error number +FIXME(anp): track_caller: no naked functions "##, E0522: r##" diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 31a09645d1691..66415e26281b3 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -11,7 +11,7 @@ use crate::ty::TyCtxt; use crate::ty::query::Providers; use std::fmt::{self, Display}; -use syntax::symbol::sym; +use syntax::{attr, symbol::sym}; use syntax_pos::Span; #[derive(Copy, Clone, PartialEq)] @@ -94,7 +94,6 @@ impl CheckAttrVisitor<'tcx> { /// Checks any attribute. fn check_attributes(&self, item: &hir::Item, target: Target) { let mut is_valid = true; - let mut track_caller_span = None; for attr in &item.attrs { is_valid &= if attr.check_name(sym::inline) { self.check_inline(attr, &item.span, target) @@ -105,7 +104,6 @@ impl CheckAttrVisitor<'tcx> { } else if attr.check_name(sym::target_feature) { self.check_target_feature(attr, item, target) } else if attr.check_name(sym::track_caller) { - track_caller_span = Some(attr.span); self.check_track_caller(attr, &item, target) } else { true @@ -122,19 +120,6 @@ impl CheckAttrVisitor<'tcx> { self.check_repr(item, target); self.check_used(item, target); - - // Checks if `#[track_caller]` and `#[naked]` are both used. - if let Some(span) = track_caller_span { - if item.attrs.iter().any(|attr| attr.check_name(sym::naked)) { - struct_span_err!( - self.tcx.sess, - span, - E0901, - "cannot use `#[track_caller]` with `#[naked]`", - ) - .emit(); - } - } } /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid. @@ -152,7 +137,7 @@ impl CheckAttrVisitor<'tcx> { } } - /// Checks if a `#[target_feature]` can be applied. + /// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid. fn check_track_caller(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) -> bool { if target != Target::Fn { struct_span_err!( @@ -164,6 +149,15 @@ impl CheckAttrVisitor<'tcx> { .span_label(item.span, "not a function") .emit(); false + } else if attr::contains_name(&item.attrs, sym::naked) { + struct_span_err!( + self.tcx.sess, + attr.span, + E0901, + "cannot use `#[track_caller]` with `#[naked]`", + ) + .emit(); + false } else { true } diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index f698427c78add..1ebae19c7d90b 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -4909,13 +4909,13 @@ and the pin is required to keep it in the same place in memory. "##, E0902: r##" -TODO: change error number -TODO: track_caller: require Rust ABI to use track_caller +FIXME(anp): change error number +FIXME(anp): track_caller: require Rust ABI to use track_caller "##, E0903: r##" -TODO: change error number -TODO: track_caller: can't apply in traits +FIXME(anp): change error number +FIXME(anp): track_caller: can't apply in traits "##, ; diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index 312a9bf6e755f..c90b18fc3976f 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -526,7 +526,7 @@ declare_features! ( (active, raw_dylib, "1.40.0", Some(58713), None), /// Enable accurate caller location reporting during panic (RFC 2091). - (active, track_caller, "1.37.0", Some(47809), None), + (active, track_caller, "1.39.0", Some(47809), None), // ------------------------------------------------------------------------- // feature-group-end: actual feature gates diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs index d6a6450e471bd..ae23cc5cb933c 100644 --- a/src/libsyntax/feature_gate/builtin_attrs.rs +++ b/src/libsyntax/feature_gate/builtin_attrs.rs @@ -324,6 +324,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)), + gated!(track_caller, Whitelisted, template!(Word), experimental!(track_caller)), // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: @@ -499,10 +500,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ cfg_fn!(no_debug) ) ), - gated!( - track_caller, Whitelisted, template!(Word), - "the `#[track_caller]` attribute is an experimental feature", - ), gated!( // Used in resolve: prelude_import, Whitelisted, template!(Word), diff --git a/src/test/ui/feature-gates/feature-gate-track_caller.rs b/src/test/ui/feature-gates/feature-gate-track_caller.rs index 458df0b2b0281..5865cf0a4f754 100644 --- a/src/test/ui/feature-gates/feature-gate-track_caller.rs +++ b/src/test/ui/feature-gates/feature-gate-track_caller.rs @@ -1,4 +1,3 @@ - #[track_caller] fn f() {} //~^^ ERROR the `#[track_caller]` attribute is an experimental feature diff --git a/src/test/ui/feature-gates/feature-gate-track_caller.stderr b/src/test/ui/feature-gates/feature-gate-track_caller.stderr index 9a058736e5080..b890019ee4f3c 100644 --- a/src/test/ui/feature-gates/feature-gate-track_caller.stderr +++ b/src/test/ui/feature-gates/feature-gate-track_caller.stderr @@ -1,5 +1,5 @@ error[E0658]: the `#[track_caller]` attribute is an experimental feature - --> $DIR/feature-gate-track_caller.rs:2:1 + --> $DIR/feature-gate-track_caller.rs:1:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2091-track-caller/pass.rs b/src/test/ui/rfc-2091-track-caller/pass.rs new file mode 100644 index 0000000000000..eef83b3d68f97 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/pass.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(track_caller)] + +#[track_caller] +fn f() {} + +fn main() { + f(); +} From 43d4b70417bb24f08584902e2f91e4eb0c703768 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Wed, 2 Oct 2019 21:32:59 -0700 Subject: [PATCH 05/17] track_caller feature gate starts in 1.40.0. Co-Authored-By: Mazdak Farrokhzad --- src/libsyntax/feature_gate/active.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index c90b18fc3976f..6c0d76de751bb 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -526,7 +526,7 @@ declare_features! ( (active, raw_dylib, "1.40.0", Some(58713), None), /// Enable accurate caller location reporting during panic (RFC 2091). - (active, track_caller, "1.39.0", Some(47809), None), + (active, track_caller, "1.40.0", Some(47809), None), // ------------------------------------------------------------------------- // feature-group-end: actual feature gates From d931afe47061cb27dfdb44727b0a6707868ea326 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Wed, 2 Oct 2019 22:09:18 -0700 Subject: [PATCH 06/17] Mark #![feature(track_caller)] as incomplete. --- src/libsyntax/feature_gate/active.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index 6c0d76de751bb..94f0995566f52 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -543,4 +543,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::or_patterns, sym::let_chains, sym::raw_dylib, + sym::track_caller, ]; From 9900211ea07a419289037b77eda218030dc32db3 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Wed, 2 Oct 2019 22:35:58 -0700 Subject: [PATCH 07/17] track_caller error numbers and text. --- src/librustc/error_codes.rs | 20 +++++++++---------- src/librustc/hir/check_attr.rs | 4 ++-- src/librustc_typeck/check/wfcheck.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- src/librustc_typeck/error_codes.rs | 16 +++++++++------ .../error-with-invalid-abi.stderr | 4 ++-- .../error-with-naked.stderr | 4 ++-- .../error-with-trait-fns.stderr | 4 ++-- .../rfc-2091-track-caller/only-for-fns.stderr | 4 ++-- 9 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index b2671e48be684..6be1b6a54fb3f 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -1640,16 +1640,6 @@ each method; it is not possible to annotate the entire impl with an `#[inline]` attribute. "##, -E0900: r##" -FIXME(anp): change error number -FIXME(anp): track_caller: invalid syntax -"##, - -E0901: r##" -FIXME(anp): change error number -FIXME(anp): track_caller: no naked functions -"##, - E0522: r##" The lang attribute is intended for marking special items that are built-in to Rust itself. This includes special traits (like `Copy` and `Sized`) that affect @@ -2085,6 +2075,15 @@ These attributes are meant to only be used by the standard library and are rejected in your own crates. "##, +E0736: r##" +#[track_caller] and #[naked] cannot be applied to the same function. + +This is primarily due to ABI incompatibilities between the two attributes. +See [RFC 2091] for details on this and other limitations. + +[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md +"##, + ; // E0006, // merged with E0005 // E0101, // replaced with E0282 @@ -2146,4 +2145,5 @@ rejected in your own crates. E0726, // non-explicit (not `'_`) elided lifetime in unsupported position E0727, // `async` generators are not yet supported E0728, // `await` must be in an `async` function or block + E0735, // invalid track_caller application/syntax } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 66415e26281b3..35c7ffbf14ef3 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -143,7 +143,7 @@ impl CheckAttrVisitor<'tcx> { struct_span_err!( self.tcx.sess, attr.span, - E0900, + E0735, "attribute should be applied to function" ) .span_label(item.span, "not a function") @@ -153,7 +153,7 @@ impl CheckAttrVisitor<'tcx> { struct_span_err!( self.tcx.sess, attr.span, - E0901, + E0736, "cannot use `#[track_caller]` with `#[naked]`", ) .emit(); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 3c9010de5cb77..b8d1da2bbed85 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -179,7 +179,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { struct_span_err!( tcx.sess, attr.span, - E0903, + E0738, "`#[track_caller]` is not supported for trait items yet." ).emit(); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 0b98e4b781d77..7f34aa354c9e8 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2599,7 +2599,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { struct_span_err!( tcx.sess, attr.span, - E0902, + E0737, "rust ABI is required to use `#[track_caller]`" ).emit(); } diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index 1ebae19c7d90b..be1e34661fd1a 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -4908,14 +4908,18 @@ The `Box<...>` ensures that the result is of known size, and the pin is required to keep it in the same place in memory. "##, -E0902: r##" -FIXME(anp): change error number -FIXME(anp): track_caller: require Rust ABI to use track_caller +E0737: r##" +#[track_caller] requires functions to have the "Rust" ABI for passing caller +location. See [RFC 2091] for details on this and other restrictions. + +[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md "##, -E0903: r##" -FIXME(anp): change error number -FIXME(anp): track_caller: can't apply in traits +E0738: r##" +#[track_caller] cannot be applied to trait methods. See [RFC 2091] +for details on this and other restrictions. + +[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md "##, ; diff --git a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr index fc6f4d17dcc42..e39e4bee5cf9c 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr @@ -1,4 +1,4 @@ -error[E0902]: rust ABI is required to use `#[track_caller]` +error[E0737]: rust ABI is required to use `#[track_caller]` --> $DIR/error-with-invalid-abi.rs:3:1 | LL | #[track_caller] @@ -6,4 +6,4 @@ LL | #[track_caller] error: aborting due to previous error -For more information about this error, try `rustc --explain E0902`. +For more information about this error, try `rustc --explain E0737`. diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr index 3566d288ed10b..2f5003cfdb7a5 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr @@ -1,4 +1,4 @@ -error[E0901]: cannot use `#[track_caller]` with `#[naked]` +error[E0736]: cannot use `#[track_caller]` with `#[naked]` --> $DIR/error-with-naked.rs:3:1 | LL | #[track_caller] @@ -6,4 +6,4 @@ LL | #[track_caller] error: aborting due to previous error -For more information about this error, try `rustc --explain E0901`. +For more information about this error, try `rustc --explain E0736`. diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr b/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr index bd3d4043a642b..e3f3135cd7366 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr @@ -1,4 +1,4 @@ -error[E0903]: `#[track_caller]` is not supported for trait items yet. +error[E0738]: `#[track_caller]` is not supported for trait items yet. --> $DIR/error-with-trait-fns.rs:4:5 | LL | #[track_caller] @@ -6,4 +6,4 @@ LL | #[track_caller] error: aborting due to previous error -For more information about this error, try `rustc --explain E0903`. +For more information about this error, try `rustc --explain E0738`. diff --git a/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr index 9ddc99c02bf9c..ac5ba0bfbaac6 100644 --- a/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr +++ b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr @@ -1,4 +1,4 @@ -error[E0900]: attribute should be applied to function +error[E0735]: attribute should be applied to function --> $DIR/only-for-fns.rs:3:1 | LL | #[track_caller] @@ -8,4 +8,4 @@ LL | struct S; error: aborting due to previous error -For more information about this error, try `rustc --explain E0900`. +For more information about this error, try `rustc --explain E0735`. From 53096c575d0e17449e3b86919b96aa0e66ca9c48 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Wed, 2 Oct 2019 23:01:52 -0700 Subject: [PATCH 08/17] track_caller tests account for incomplete feature warning. --- src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs | 2 +- .../ui/rfc-2091-track-caller/error-odd-syntax.stderr | 8 ++++++++ .../ui/rfc-2091-track-caller/error-with-invalid-abi.rs | 2 +- .../rfc-2091-track-caller/error-with-invalid-abi.stderr | 8 ++++++++ src/test/ui/rfc-2091-track-caller/error-with-naked.rs | 2 +- .../ui/rfc-2091-track-caller/error-with-naked.stderr | 8 ++++++++ .../ui/rfc-2091-track-caller/error-with-trait-fns.rs | 2 +- .../ui/rfc-2091-track-caller/error-with-trait-fns.stderr | 8 ++++++++ src/test/ui/rfc-2091-track-caller/only-for-fns.rs | 2 +- src/test/ui/rfc-2091-track-caller/only-for-fns.stderr | 9 ++++++++- src/test/ui/rfc-2091-track-caller/pass.rs | 2 +- src/test/ui/rfc-2091-track-caller/pass.stderr | 8 ++++++++ 12 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/rfc-2091-track-caller/pass.stderr diff --git a/src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs b/src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs index d6560231871c9..d400db8575e0a 100644 --- a/src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs +++ b/src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs @@ -1,4 +1,4 @@ -#![feature(track_caller)] +#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete #[track_caller(1)] fn f() {} diff --git a/src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr b/src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr index 8906fa59506a7..a53a8ee2bedc6 100644 --- a/src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr @@ -4,5 +4,13 @@ error: malformed `track_caller` attribute input LL | #[track_caller(1)] | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[track_caller]` +warning: the feature `track_caller` is incomplete and may cause the compiler to crash + --> $DIR/error-odd-syntax.rs:1:12 + | +LL | #![feature(track_caller)] + | ^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + error: aborting due to previous error diff --git a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs index 5c42a1b3faa2d..2994f3c06212f 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs +++ b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs @@ -1,4 +1,4 @@ -#![feature(track_caller)] +#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete #[track_caller] extern "C" fn f() {} diff --git a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr index e39e4bee5cf9c..a34acf3fc6142 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr @@ -1,3 +1,11 @@ +warning: the feature `track_caller` is incomplete and may cause the compiler to crash + --> $DIR/error-with-invalid-abi.rs:1:12 + | +LL | #![feature(track_caller)] + | ^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + error[E0737]: rust ABI is required to use `#[track_caller]` --> $DIR/error-with-invalid-abi.rs:3:1 | diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs index dd9e5d0413585..bbbcec30e8d51 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs @@ -1,4 +1,4 @@ -#![feature(naked_functions, track_caller)] +#![feature(naked_functions, track_caller)] //~ WARN the feature `track_caller` is incomplete #[track_caller] #[naked] diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr index 2f5003cfdb7a5..93e6f7a4cd32c 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr @@ -1,3 +1,11 @@ +warning: the feature `track_caller` is incomplete and may cause the compiler to crash + --> $DIR/error-with-naked.rs:1:29 + | +LL | #![feature(naked_functions, track_caller)] + | ^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + error[E0736]: cannot use `#[track_caller]` with `#[naked]` --> $DIR/error-with-naked.rs:3:1 | diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs b/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs index c00cf7367ce54..e42568076b9dc 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs @@ -1,4 +1,4 @@ -#![feature(track_caller)] +#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete trait Trait { #[track_caller] diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr b/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr index e3f3135cd7366..c5c2f136a3a81 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr @@ -1,3 +1,11 @@ +warning: the feature `track_caller` is incomplete and may cause the compiler to crash + --> $DIR/error-with-trait-fns.rs:1:12 + | +LL | #![feature(track_caller)] + | ^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + error[E0738]: `#[track_caller]` is not supported for trait items yet. --> $DIR/error-with-trait-fns.rs:4:5 | diff --git a/src/test/ui/rfc-2091-track-caller/only-for-fns.rs b/src/test/ui/rfc-2091-track-caller/only-for-fns.rs index 0fd59b4bf4918..01ebf13b521b2 100644 --- a/src/test/ui/rfc-2091-track-caller/only-for-fns.rs +++ b/src/test/ui/rfc-2091-track-caller/only-for-fns.rs @@ -1,4 +1,4 @@ -#![feature(track_caller)] +#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete #[track_caller] struct S; diff --git a/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr index ac5ba0bfbaac6..e2d3d57f0adf4 100644 --- a/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr +++ b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr @@ -1,3 +1,11 @@ +warning: the feature `track_caller` is incomplete and may cause the compiler to crash + --> $DIR/only-for-fns.rs:1:12 + | +LL | #![feature(track_caller)] + | ^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + error[E0735]: attribute should be applied to function --> $DIR/only-for-fns.rs:3:1 | @@ -8,4 +16,3 @@ LL | struct S; error: aborting due to previous error -For more information about this error, try `rustc --explain E0735`. diff --git a/src/test/ui/rfc-2091-track-caller/pass.rs b/src/test/ui/rfc-2091-track-caller/pass.rs index eef83b3d68f97..f2c3f0dc59e01 100644 --- a/src/test/ui/rfc-2091-track-caller/pass.rs +++ b/src/test/ui/rfc-2091-track-caller/pass.rs @@ -1,5 +1,5 @@ // run-pass -#![feature(track_caller)] +#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete #[track_caller] fn f() {} diff --git a/src/test/ui/rfc-2091-track-caller/pass.stderr b/src/test/ui/rfc-2091-track-caller/pass.stderr new file mode 100644 index 0000000000000..b1fd23a6a9ddb --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/pass.stderr @@ -0,0 +1,8 @@ +warning: the feature `track_caller` is incomplete and may cause the compiler to crash + --> $DIR/pass.rs:2:12 + | +LL | #![feature(track_caller)] + | ^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + From 8992c30db41ceda8eb07c36080f2f1926013c2ac Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Thu, 3 Oct 2019 18:49:35 -0700 Subject: [PATCH 09/17] E0735 -> E0739 Prevents number collision with another approved PR. --- src/librustc/error_codes.rs | 2 +- src/librustc/hir/check_attr.rs | 2 +- src/test/ui/rfc-2091-track-caller/only-for-fns.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 6be1b6a54fb3f..8bc472aa0284e 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -2145,5 +2145,5 @@ See [RFC 2091] for details on this and other limitations. E0726, // non-explicit (not `'_`) elided lifetime in unsupported position E0727, // `async` generators are not yet supported E0728, // `await` must be in an `async` function or block - E0735, // invalid track_caller application/syntax + E0739, // invalid track_caller application/syntax } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 35c7ffbf14ef3..c37fec982b116 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -143,7 +143,7 @@ impl CheckAttrVisitor<'tcx> { struct_span_err!( self.tcx.sess, attr.span, - E0735, + E0739, "attribute should be applied to function" ) .span_label(item.span, "not a function") diff --git a/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr index e2d3d57f0adf4..3301da7ff47bf 100644 --- a/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr +++ b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr @@ -6,7 +6,7 @@ LL | #![feature(track_caller)] | = note: `#[warn(incomplete_features)]` on by default -error[E0735]: attribute should be applied to function +error[E0739]: attribute should be applied to function --> $DIR/only-for-fns.rs:3:1 | LL | #[track_caller] From bdc4bd142b3a452d5e7456cf30e9fc67106ec01b Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Fri, 4 Oct 2019 14:19:05 -0700 Subject: [PATCH 10/17] E073[6-8] include failing code examples. --- src/librustc/error_codes.rs | 10 ++++++++ src/librustc_typeck/error_codes.rs | 37 ++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 8bc472aa0284e..e3ef58a0f81f4 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -2078,6 +2078,16 @@ rejected in your own crates. E0736: r##" #[track_caller] and #[naked] cannot be applied to the same function. +Erroneous code example: + +```compile_fail,E0736 +#![feature(track_caller)] + +#[naked] +#[track_caller] +fn foo() {} +``` + This is primarily due to ABI incompatibilities between the two attributes. See [RFC 2091] for details on this and other limitations. diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index be1e34661fd1a..1fb5b59261631 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -4909,15 +4909,44 @@ and the pin is required to keep it in the same place in memory. "##, E0737: r##" -#[track_caller] requires functions to have the "Rust" ABI for passing caller -location. See [RFC 2091] for details on this and other restrictions. +#[track_caller] requires functions to have the "Rust" ABI for implicitly +receiving caller location. See [RFC 2091] for details on this and other +restrictions. + +Erroneous code example: + +```compile_fail,E0737 +#![feature(track_caller)] + +#[track_caller] +extern "C" fn foo() {} +``` [RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md "##, E0738: r##" -#[track_caller] cannot be applied to trait methods. See [RFC 2091] -for details on this and other restrictions. +#[track_caller] cannot be applied to trait methods. + +This is due to limitations in the compiler which are likely to be temporary. +See [RFC 2091] for details on this and other restrictions. + +Erroneous code example: + +```compile_fail,E0738 +#![feature(track_caller)] + +trait Foo { + fn bar(&self); +} + +struct Bar; + +impl Foo for Bar { + #[track_caller] + fn bar(&self) {} +} +``` [RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md "##, From 130be6d4b8015b32a3e68678dd75459b2a3de3ab Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Fri, 4 Oct 2019 15:55:39 -0700 Subject: [PATCH 11/17] Expand E0738 to cover different cases. --- src/librustc_typeck/check/wfcheck.rs | 2 +- src/librustc_typeck/error_codes.rs | 39 +++++++++++++++---- ...-trait-fns.rs => error-with-trait-decl.rs} | 2 +- .../error-with-trait-decl.stderr | 17 ++++++++ .../error-with-trait-default-impl.rs | 9 +++++ .../error-with-trait-default-impl.stderr | 17 ++++++++ .../error-with-trait-fn-impl.rs | 13 +++++++ ...stderr => error-with-trait-fn-impl.stderr} | 6 +-- 8 files changed, 93 insertions(+), 12 deletions(-) rename src/test/ui/rfc-2091-track-caller/{error-with-trait-fns.rs => error-with-trait-decl.rs} (72%) create mode 100644 src/test/ui/rfc-2091-track-caller/error-with-trait-decl.stderr create mode 100644 src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.rs create mode 100644 src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.stderr create mode 100644 src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.rs rename src/test/ui/rfc-2091-track-caller/{error-with-trait-fns.stderr => error-with-trait-fn-impl.stderr} (71%) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index b8d1da2bbed85..4f9c686bd39c6 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -180,7 +180,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { tcx.sess, attr.span, E0738, - "`#[track_caller]` is not supported for trait items yet." + "`#[track_caller]` is not supported in trait declarations." ).emit(); } } diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index 1fb5b59261631..026aff7a96468 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -4926,12 +4926,11 @@ extern "C" fn foo() {} "##, E0738: r##" -#[track_caller] cannot be applied to trait methods. +#[track_caller] cannot be used in traits yet. This is due to limitations in the +compiler which are likely to be temporary. See [RFC 2091] for details on this +and other restrictions. -This is due to limitations in the compiler which are likely to be temporary. -See [RFC 2091] for details on this and other restrictions. - -Erroneous code example: +Erroneous example with a trait method implementation: ```compile_fail,E0738 #![feature(track_caller)] @@ -4940,14 +4939,40 @@ trait Foo { fn bar(&self); } -struct Bar; +impl Foo for u64 { + #[track_caller] + fn bar(&self) {} +} +``` -impl Foo for Bar { +Erroneous example with a blanket trait method implementation: + +```compile_fail,E0738 +#![feature(track_caller)] + +trait Foo { #[track_caller] fn bar(&self) {} + fn baz(&self); +} +``` + +Erroneous example with a trait method declaration: + +```compile_fail,E0738 +#[!feature(track_caller)] + +trait Foo { + fn bar(&self) {} + + #[track_caller] + fn baz(&self); } ``` +Note that while the compiler may be able to support the attribute in traits in +the future, [RFC 2091] prohibits their implementation without a follow-up RFC. + [RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md "##, diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs b/src/test/ui/rfc-2091-track-caller/error-with-trait-decl.rs similarity index 72% rename from src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs rename to src/test/ui/rfc-2091-track-caller/error-with-trait-decl.rs index e42568076b9dc..72f690777da21 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-decl.rs @@ -3,7 +3,7 @@ trait Trait { #[track_caller] fn unwrap(&self); - //~^^ ERROR: `#[track_caller]` is not supported for trait items yet. + //~^^ ERROR: `#[track_caller]` is not supported in traits yet. } impl Trait for u64 { diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-decl.stderr b/src/test/ui/rfc-2091-track-caller/error-with-trait-decl.stderr new file mode 100644 index 0000000000000..fb3732b597083 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-decl.stderr @@ -0,0 +1,17 @@ +warning: the feature `track_caller` is incomplete and may cause the compiler to crash + --> $DIR/error-with-trait-decl.rs:1:12 + | +LL | #![feature(track_caller)] + | ^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error[E0738]: `#[track_caller]` is not supported in trait declarations. + --> $DIR/error-with-trait-decl.rs:4:5 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0738`. diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.rs b/src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.rs new file mode 100644 index 0000000000000..0f2020d6fb26b --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.rs @@ -0,0 +1,9 @@ +#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete + +trait Trait { + #[track_caller] + fn unwrap(&self) {} + //~^^ ERROR: `#[track_caller]` is not supported in trait declarations. +} + +fn main() {} diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.stderr b/src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.stderr new file mode 100644 index 0000000000000..f7faeba189b5e --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.stderr @@ -0,0 +1,17 @@ +warning: the feature `track_caller` is incomplete and may cause the compiler to crash + --> $DIR/error-with-trait-default-impl.rs:1:12 + | +LL | #![feature(track_caller)] + | ^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error[E0738]: `#[track_caller]` is not supported in traits yet. + --> $DIR/error-with-trait-default-impl.rs:4:5 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0738`. diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.rs b/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.rs new file mode 100644 index 0000000000000..1378ebaa03ffa --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.rs @@ -0,0 +1,13 @@ +#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete + +trait Trait { + fn unwrap(&self); +} + +impl Trait for u64 { + #[track_caller] + fn unwrap(&self) {} + //~^^ ERROR: `#[track_caller]` is not supported in traits yet. +} + +fn main() {} diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr b/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.stderr similarity index 71% rename from src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr rename to src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.stderr index c5c2f136a3a81..1e6c2eeca4736 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.stderr @@ -1,13 +1,13 @@ warning: the feature `track_caller` is incomplete and may cause the compiler to crash - --> $DIR/error-with-trait-fns.rs:1:12 + --> $DIR/error-with-trait-fn-impl.rs:1:12 | LL | #![feature(track_caller)] | ^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default -error[E0738]: `#[track_caller]` is not supported for trait items yet. - --> $DIR/error-with-trait-fns.rs:4:5 +error[E0738]: `#[track_caller]` is not supported in traits yet. + --> $DIR/error-with-trait-fn-impl.rs:4:5 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ From f70ed29fbd2b58dd1ebfcff878134fd3876a0dea Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Sat, 5 Oct 2019 08:12:48 -0700 Subject: [PATCH 12/17] Update expected error output. --- src/test/ui/rfc-2091-track-caller/error-with-trait-decl.rs | 2 +- .../rfc-2091-track-caller/error-with-trait-default-impl.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-decl.rs b/src/test/ui/rfc-2091-track-caller/error-with-trait-decl.rs index 72f690777da21..1cd45c8cdbc91 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-trait-decl.rs +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-decl.rs @@ -3,7 +3,7 @@ trait Trait { #[track_caller] fn unwrap(&self); - //~^^ ERROR: `#[track_caller]` is not supported in traits yet. + //~^^ ERROR: `#[track_caller]` is not supported in trait declarations. } impl Trait for u64 { diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.stderr b/src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.stderr index f7faeba189b5e..c212a716c2024 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.stderr @@ -6,7 +6,7 @@ LL | #![feature(track_caller)] | = note: `#[warn(incomplete_features)]` on by default -error[E0738]: `#[track_caller]` is not supported in traits yet. +error[E0738]: `#[track_caller]` is not supported in trait declarations. --> $DIR/error-with-trait-default-impl.rs:4:5 | LL | #[track_caller] From 190212c6bf1588fb4349a16caa9c2796f9a795f4 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Sat, 5 Oct 2019 08:21:30 -0700 Subject: [PATCH 13/17] Prohibit #[track_caller] within trait impls as well as decls. --- src/librustc_typeck/check/wfcheck.rs | 27 ++++++++++++++++++- .../error-with-trait-fn-impl.stderr | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 4f9c686bd39c6..051bd671d445b 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -173,7 +173,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { }; check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig); - // Prohibits applying `#[track_caller]` to trait methods + // Prohibits applying `#[track_caller]` to trait decls for attr in &trait_item.attrs { if attr.check_name(sym::track_caller) { struct_span_err!( @@ -194,6 +194,31 @@ pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) { hir::ImplItemKind::Method(ref sig, _) => Some(sig), _ => None }; + + // Prohibits applying `#[track_caller]` to trait impls + if method_sig.is_some() { + let track_caller_attr = impl_item.attrs.iter() + .find(|a| a.check_name(sym::track_caller)); + if let Some(tc_attr) = track_caller_attr { + let parent_hir_id = tcx.hir().get_parent_item(hir_id); + let containing_item = tcx.hir().expect_item(parent_hir_id); + let containing_impl_trait_ref = match &containing_item.kind { + hir::ItemKind::Impl(_, _, _, _, tr, _, _) => tr, + _ => bug!("parent of an ImplItem must be an Impl"), + }; + + // if the impl block this item is within is for a trait... + if containing_impl_trait_ref.is_some() { + struct_span_err!( + tcx.sess, + tc_attr.span, + E0738, + "`#[track_caller]` is not supported in traits yet." + ).emit(); + } + } + } + check_associated_item(tcx, impl_item.hir_id, impl_item.span, method_sig); } diff --git a/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.stderr b/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.stderr index 1e6c2eeca4736..2662fbff7a2c2 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.stderr @@ -7,7 +7,7 @@ LL | #![feature(track_caller)] = note: `#[warn(incomplete_features)]` on by default error[E0738]: `#[track_caller]` is not supported in traits yet. - --> $DIR/error-with-trait-fn-impl.rs:4:5 + --> $DIR/error-with-trait-fn-impl.rs:8:5 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ From c49966bb1bc66cb14d66e2c116d187e781ee6776 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Sat, 5 Oct 2019 08:28:38 -0700 Subject: [PATCH 14/17] Clarify variable names when checking track_caller methods. --- src/librustc_typeck/check/wfcheck.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 051bd671d445b..fa283904fe474 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -196,19 +196,18 @@ pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) { }; // Prohibits applying `#[track_caller]` to trait impls - if method_sig.is_some() { + if method_sig.is_some() { let track_caller_attr = impl_item.attrs.iter() .find(|a| a.check_name(sym::track_caller)); if let Some(tc_attr) = track_caller_attr { let parent_hir_id = tcx.hir().get_parent_item(hir_id); let containing_item = tcx.hir().expect_item(parent_hir_id); - let containing_impl_trait_ref = match &containing_item.kind { - hir::ItemKind::Impl(_, _, _, _, tr, _, _) => tr, + let containing_impl_is_for_trait = match &containing_item.kind { + hir::ItemKind::Impl(_, _, _, _, tr, _, _) => tr.is_some(), _ => bug!("parent of an ImplItem must be an Impl"), }; - // if the impl block this item is within is for a trait... - if containing_impl_trait_ref.is_some() { + if containing_impl_is_for_trait { struct_span_err!( tcx.sess, tc_attr.span, From cca58d1321b6de3098884d4af7bbff57f0f65101 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Mon, 7 Oct 2019 08:04:26 -0700 Subject: [PATCH 15/17] Fix syntax typo in error message. --- src/librustc_typeck/error_codes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index 026aff7a96468..0736d69a731e1 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -4960,7 +4960,7 @@ trait Foo { Erroneous example with a trait method declaration: ```compile_fail,E0738 -#[!feature(track_caller)] +#![feature(track_caller)] trait Foo { fn bar(&self) {} From d1d256592bcd3f05d00fe7ad80d1a1ed22c9e7d7 Mon Sep 17 00:00:00 2001 From: csmoe Date: Sun, 6 Oct 2019 21:58:32 +0800 Subject: [PATCH 16/17] suggest to add move keyword for generator --- .../borrow_check/conflict_errors.rs | 26 +++++++++++++++++++ .../borrow_check/nll/explain_borrow/mod.rs | 3 ++- .../async-borrowck-escaping-block-error.fixed | 12 +++++++++ .../async-borrowck-escaping-block-error.rs | 7 +++-- ...async-borrowck-escaping-block-error.stderr | 4 +-- 5 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/async-await/async-borrowck-escaping-block-error.fixed diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index ef459ef0c1b70..2f9df7bd77e84 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -750,6 +750,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let kind_place = kind.filter(|_| place_desc.is_some()).map(|k| (k, place_span.0)); let explanation = self.explain_why_borrow_contains_point(location, &borrow, kind_place); + debug!( + "report_borrowed_value_does_not_live_long_enough(place_desc: {:?}, explanation: {:?})", + place_desc, + explanation + ); let err = match (place_desc, explanation) { (Some(_), _) if self.is_place_thread_local(root_place) => { self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span) @@ -790,6 +795,24 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { span, &format!("`{}`", name), ), + ( + Some(ref name), + BorrowExplanation::MustBeValidFor { + category: category @ ConstraintCategory::OpaqueType, + from_closure: false, + ref region_name, + span, + .. + }, + + ) if borrow_spans.for_generator() => self.report_escaping_closure_capture( + borrow_spans.args_or_use(), + borrow_span, + region_name, + category, + span, + &format!("`{}`", name), + ), ( ref name, BorrowExplanation::MustBeValidFor { @@ -1214,6 +1237,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ConstraintCategory::Return => { err.span_note(constraint_span, "closure is returned here"); } + ConstraintCategory::OpaqueType => { + err.span_note(constraint_span, "generator is returned here"); + } ConstraintCategory::CallArgument => { fr_name.highlight_region_name(&mut err); err.span_note( diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index ff4243df6e9b8..5354b45f92d0a 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -17,6 +17,7 @@ use syntax_pos::Span; mod find_use; +#[derive(Debug)] pub(in crate::borrow_check) enum BorrowExplanation { UsedLater(LaterUseKind, Span), UsedLaterInLoop(LaterUseKind, Span), @@ -35,7 +36,7 @@ pub(in crate::borrow_check) enum BorrowExplanation { Unexplained, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub(in crate::borrow_check) enum LaterUseKind { TraitCapture, ClosureCapture, diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.fixed b/src/test/ui/async-await/async-borrowck-escaping-block-error.fixed new file mode 100644 index 0000000000000..f004b4180ddc9 --- /dev/null +++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.fixed @@ -0,0 +1,12 @@ +// edition:2018 +// run-rustfix + +fn foo() -> Box> { + let x = 0u32; + Box::new(async move { x } ) + //~^ ERROR E0373 +} + +fn main() { + let _foo = foo(); +} diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.rs b/src/test/ui/async-await/async-borrowck-escaping-block-error.rs index 49f59e4149313..4f35fd52ca39b 100644 --- a/src/test/ui/async-await/async-borrowck-escaping-block-error.rs +++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.rs @@ -1,9 +1,12 @@ // edition:2018 -#![feature(async_closure,async_await)] +// run-rustfix + fn foo() -> Box> { let x = 0u32; Box::new(async { x } ) //~^ ERROR E0373 } -fn main() {} +fn main() { + let _foo = foo(); +} diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr index 5771ccbcf9d1e..af17ecc86fbf9 100644 --- a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr +++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr @@ -1,5 +1,5 @@ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function - --> $DIR/async-borrowck-escaping-block-error.rs:5:20 + --> $DIR/async-borrowck-escaping-block-error.rs:6:20 | LL | Box::new(async { x } ) | ^^-^^ @@ -8,7 +8,7 @@ LL | Box::new(async { x } ) | may outlive borrowed value `x` | note: generator is returned here - --> $DIR/async-borrowck-escaping-block-error.rs:3:13 + --> $DIR/async-borrowck-escaping-block-error.rs:4:13 | LL | fn foo() -> Box> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From bdcc21cbc4dabe73662634ffada8d0f353bc1ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Sat, 21 Sep 2019 22:56:05 +1200 Subject: [PATCH 17/17] Implement (HashMap) Entry::insert as per #60142 --- Cargo.lock | 21 +++++++++++-- src/libstd/Cargo.toml | 2 +- src/libstd/collections/hash/map.rs | 47 ++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80364515a7cca..6c05efcbec5e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,6 +107,12 @@ dependencies = [ "winapi 0.3.6", ] +[[package]] +name = "autocfg" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" + [[package]] name = "backtrace" version = "0.3.37" @@ -1259,7 +1265,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df044dd42cdb7e32f28557b661406fc0f2494be75199779998810dbc35030e0d" dependencies = [ - "hashbrown", + "hashbrown 0.5.0", "lazy_static 1.3.0", "log", "pest", @@ -1276,10 +1282,19 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353" dependencies = [ + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6587d09be37fb98a11cb08b9000a3f592451c1b1b613ca69d949160e313a430a" +dependencies = [ + "autocfg", "compiler_builtins", "rustc-std-workspace-alloc", "rustc-std-workspace-core", - "serde", ] [[package]] @@ -4073,7 +4088,7 @@ dependencies = [ "core", "dlmalloc", "fortanix-sgx-abi", - "hashbrown", + "hashbrown 0.6.1", "libc", "panic_abort", "panic_unwind", diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index ee4b367b5c5b9..5309af6f4c342 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -23,7 +23,7 @@ libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of compiler_builtins = { version = "0.1.16" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } -hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] } +hashbrown = { version = "0.6.1", default-features = false, features = ['rustc-dep-of-std'] } [dependencies.backtrace_rs] package = "backtrace" diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index ff50051ef5040..fcca112563d2d 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2030,6 +2030,31 @@ impl<'a, K, V> Entry<'a, K, V> { Vacant(entry) => Vacant(entry), } } + + /// Sets the value of the entry, and returns an OccupiedEntry. + /// + /// # Examples + /// + /// ``` + /// #![feature(entry_insert)] + /// use std::collections::HashMap; + /// + /// let mut map: HashMap<&str, String> = HashMap::new(); + /// let entry = map.entry("poneyland").insert("hoho".to_string()); + /// + /// assert_eq!(entry.key(), &"poneyland"); + /// ``` + #[inline] + #[unstable(feature = "entry_insert", issue = "65225")] + pub fn insert(self, value: V) -> OccupiedEntry<'a, K, V> { + match self { + Occupied(mut entry) => { + entry.insert(value); + entry + }, + Vacant(entry) => entry.insert_entry(value), + } + } } impl<'a, K, V: Default> Entry<'a, K, V> { @@ -2347,6 +2372,28 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { pub fn insert(self, value: V) -> &'a mut V { self.base.insert(value) } + + /// Sets the value of the entry with the VacantEntry's key, + /// and returns an OccupiedEntry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::Entry; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// + /// if let Entry::Vacant(o) = map.entry("poneyland") { + /// o.insert(37); + /// } + /// assert_eq!(map["poneyland"], 37); + /// ``` + #[inline] + fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> { + let base = self.base.insert_entry(value); + OccupiedEntry { base } + } } #[stable(feature = "rust1", since = "1.0.0")]