about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-10-09 03:32:21 +0000
committerbors <bors@rust-lang.org>2019-10-09 03:32:21 +0000
commit275cf4bcacad3fbe5539ecd5840462793ae46eec (patch)
tree907f93d50a06e4997a8b0b29214bc219243810c6 /src
parentb5bd31ec6db6a249311888a93fc176f06dcb6aa6 (diff)
parente27f0298363f6ca60bb5761a8c74d52b3999a061 (diff)
downloadrust-275cf4bcacad3fbe5539ecd5840462793ae46eec.tar.gz
rust-275cf4bcacad3fbe5539ecd5840462793ae46eec.zip
Auto merge of #65229 - Centril:rollup-wnr46vg, r=Centril
Rollup of 4 pull requests

Successful merges:

 - #64656 (Implement (HashMap) Entry::insert as per #60142)
 - #65037 (`#[track_caller]` feature gate (RFC 2091 1/N))
 - #65166 (Suggest to add `move` keyword for generator capture)
 - #65175 (add more info in debug traces for gcu merging)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/doc/unstable-book/src/language-features/track-caller.md5
-rw-r--r--src/librustc/error_codes.rs20
-rw-r--r--src/librustc/hir/check_attr.rs30
-rw-r--r--src/librustc/hir/mod.rs4
-rw-r--r--src/librustc_mir/borrow_check/conflict_errors.rs26
-rw-r--r--src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs3
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs10
-rw-r--r--src/librustc_typeck/check/wfcheck.rs36
-rw-r--r--src/librustc_typeck/collect.rs10
-rw-r--r--src/librustc_typeck/error_codes.rs69
-rw-r--r--src/libstd/Cargo.toml2
-rw-r--r--src/libstd/collections/hash/map.rs47
-rw-r--r--src/libsyntax/feature_gate/active.rs4
-rw-r--r--src/libsyntax/feature_gate/builtin_attrs.rs1
-rw-r--r--src/libsyntax_pos/symbol.rs1
-rw-r--r--src/test/ui/async-await/async-borrowck-escaping-block-error.fixed12
-rw-r--r--src/test/ui/async-await/async-borrowck-escaping-block-error.rs12
-rw-r--r--src/test/ui/async-await/async-borrowck-escaping-block-error.stderr22
-rw-r--r--src/test/ui/feature-gates/feature-gate-track_caller.rs5
-rw-r--r--src/test/ui/feature-gates/feature-gate-track_caller.stderr12
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs7
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr16
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs7
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr17
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-naked.rs8
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-naked.stderr17
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-trait-decl.rs13
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-trait-decl.stderr17
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.rs9
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-trait-default-impl.stderr17
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.rs13
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.stderr17
-rw-r--r--src/test/ui/rfc-2091-track-caller/only-for-fns.rs7
-rw-r--r--src/test/ui/rfc-2091-track-caller/only-for-fns.stderr18
-rw-r--r--src/test/ui/rfc-2091-track-caller/pass.rs9
-rw-r--r--src/test/ui/rfc-2091-track-caller/pass.stderr8
36 files changed, 524 insertions, 7 deletions
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 00000000000..afc11a2b949
--- /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 0c9760b3c0f..e208e25f6ea 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -2120,6 +2120,25 @@ 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.
+
+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.
+
+[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
+"##,
+
 ;
 //  E0006, // merged with E0005
 //  E0101, // replaced with E0282
@@ -2179,4 +2198,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
+    E0739, // invalid track_caller application/syntax
 }
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index d5e956555bd..c37fec982b1 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)]
@@ -103,6 +103,8 @@ 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) {
+                self.check_track_caller(attr, &item, target)
             } else {
                 true
             };
@@ -135,6 +137,32 @@ impl CheckAttrVisitor<'tcx> {
         }
     }
 
+    /// 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!(
+                self.tcx.sess,
+                attr.span,
+                E0739,
+                "attribute should be applied to function"
+            )
+            .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,
+                E0736,
+                "cannot use `#[track_caller]` with `#[naked]`",
+            )
+            .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 1f792ecc2da..06bd4a42748 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -2734,7 +2734,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_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index ef459ef0c1b..2f9df7bd77e 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)
@@ -791,6 +796,24 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 &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 {
                     category: ConstraintCategory::Assignment,
@@ -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 ff4243df6e9..5354b45f92d 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/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index c193911247e..61868b24c0b 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("<no hash>");
 
-                debug!(" - {} [{:?}] [{}]",
+                debug!(" - {} [{:?}] [{}] estimated size {}",
                        mono_item.to_string(tcx, true),
                        linkage,
-                       symbol_hash);
+                       symbol_hash,
+                       mono_item.size_estimate(tcx));
             }
 
             debug!("");
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index e736a55a5f5..fa283904fe4 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 decls
+    for attr in &trait_item.attrs {
+        if attr.check_name(sym::track_caller) {
+            struct_span_err!(
+                tcx.sess,
+                attr.span,
+                E0738,
+                "`#[track_caller]` is not supported in trait declarations."
+            ).emit();
+        }
+    }
 }
 
 pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) {
@@ -182,6 +194,30 @@ 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_is_for_trait = match &containing_item.kind {
+                hir::ItemKind::Impl(_, _, _, _, tr, _, _) => tr.is_some(),
+                _ => bug!("parent of an ImplItem must be an Impl"),
+            };
+
+            if containing_impl_is_for_trait {
+                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/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 64eca137144..7f34aa354c9 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,
+                    E0737,
+                    "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 8bd899ae4d5..ef08e8d4f0b 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -4905,6 +4905,75 @@ fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
 The `Box<...>` ensures that the result is of known size,
 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 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 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.
+
+Erroneous example with a trait method implementation:
+
+```compile_fail,E0738
+#![feature(track_caller)]
+
+trait Foo {
+    fn bar(&self);
+}
+
+impl Foo for u64 {
+    #[track_caller]
+    fn bar(&self) {}
+}
+```
+
+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
+"##,
+
 ;
 //  E0035, merged into E0087/E0089
 //  E0036, merged into E0087/E0089
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index ee4b367b5c5..5309af6f4c3 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 ff50051ef50..fcca112563d 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")]
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index 19ef430318d..94f0995566f 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.40.0", Some(47809), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
@@ -540,4 +543,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
     sym::or_patterns,
     sym::let_chains,
     sym::raw_dylib,
+    sym::track_caller,
 ];
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index c12d0ce06ff..ae23cc5cb93 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:
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index c7230d5ca15..2b005c3fc42 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/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 00000000000..f004b4180dd
--- /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<impl std::future::Future<Output = u32>> {
+    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
new file mode 100644
index 00000000000..4f35fd52ca3
--- /dev/null
+++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.rs
@@ -0,0 +1,12 @@
+// edition:2018
+// run-rustfix
+
+fn foo() -> Box<impl std::future::Future<Output = u32>> {
+    let x = 0u32;
+    Box::new(async { x } )
+    //~^ ERROR E0373
+}
+
+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
new file mode 100644
index 00000000000..af17ecc86fb
--- /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:6: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:4:13
+   |
+LL | fn foo() -> Box<impl std::future::Future<Output = u32>> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+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`.
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 00000000000..5865cf0a4f7
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-track_caller.rs
@@ -0,0 +1,5 @@
+#[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 00000000000..b890019ee4f
--- /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:1: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 00000000000..d400db8575e
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs
@@ -0,0 +1,7 @@
+#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
+
+#[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 00000000000..a53a8ee2bed
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr
@@ -0,0 +1,16 @@
+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]`
+
+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
new file mode 100644
index 00000000000..2994f3c0621
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs
@@ -0,0 +1,7 @@
+#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
+
+#[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 00000000000..a34acf3fc61
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr
@@ -0,0 +1,17 @@
+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
+   |
+LL | #[track_caller]
+   | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0737`.
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 00000000000..bbbcec30e8d
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs
@@ -0,0 +1,8 @@
+#![feature(naked_functions, track_caller)] //~ WARN the feature `track_caller` is incomplete
+
+#[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 00000000000..93e6f7a4cd3
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr
@@ -0,0 +1,17 @@
+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
+   |
+LL | #[track_caller]
+   | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0736`.
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
new file mode 100644
index 00000000000..1cd45c8cdbc
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-decl.rs
@@ -0,0 +1,13 @@
+#![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.
+}
+
+impl Trait for u64 {
+    fn unwrap(&self) {}
+}
+
+fn main() {}
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 00000000000..fb3732b5970
--- /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 00000000000..0f2020d6fb2
--- /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 00000000000..c212a716c20
--- /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 trait declarations.
+  --> $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 00000000000..1378ebaa03f
--- /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-fn-impl.stderr b/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.stderr
new file mode 100644
index 00000000000..2662fbff7a2
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-with-trait-fn-impl.stderr
@@ -0,0 +1,17 @@
+warning: the feature `track_caller` is incomplete and may cause the compiler to crash
+  --> $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 in traits yet.
+  --> $DIR/error-with-trait-fn-impl.rs:8: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/only-for-fns.rs b/src/test/ui/rfc-2091-track-caller/only-for-fns.rs
new file mode 100644
index 00000000000..01ebf13b521
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/only-for-fns.rs
@@ -0,0 +1,7 @@
+#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
+
+#[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 00000000000..3301da7ff47
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/only-for-fns.stderr
@@ -0,0 +1,18 @@
+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[E0739]: 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
+
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 00000000000..f2c3f0dc59e
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/pass.rs
@@ -0,0 +1,9 @@
+// run-pass
+#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
+
+#[track_caller]
+fn f() {}
+
+fn main() {
+    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 00000000000..b1fd23a6a9d
--- /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
+