提交 275cf4bc 编写于 作者: B bors

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
......@@ -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"
......@@ -1269,7 +1275,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",
......@@ -1286,10 +1292,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]]
......@@ -4109,7 +4124,7 @@ dependencies = [
"core",
"dlmalloc",
"fortanix-sgx-abi",
"hashbrown",
"hashbrown 0.6.1",
"libc",
"panic_abort",
"panic_unwind",
......
# `track_caller`
The tracking issue for this feature is: [#47809](https://github.com/rust-lang/rust/issues/47809).
------------------------
......@@ -2120,6 +2120,25 @@ fn foo(){}
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 @@ fn foo(){}
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
}
......@@ -11,7 +11,7 @@
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 @@ fn check_attributes(&self, item: &hir::Item, target: Target) {
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 @@ fn check_inline(&self, attr: &hir::Attribute, span: &Span, target: Target) -> bo
}
}
/// 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,
......
......@@ -2734,7 +2734,9 @@ pub struct CodegenFnAttrFlags: u32 {
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;
}
}
......
......@@ -750,6 +750,11 @@ pub(super) fn report_borrowed_value_does_not_live_long_enough(
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 @@ pub(super) fn report_borrowed_value_does_not_live_long_enough(
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 @@ fn report_escaping_closure_capture(
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(
......
......@@ -17,6 +17,7 @@
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,
......
......@@ -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 @@ fn debug_dump<'a, 'tcx, I>(tcx: TyCtxt<'tcx>, label: &str, cgus: I)
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 @@ fn debug_dump<'a, 'tcx, I>(tcx: TyCtxt<'tcx>, label: &str, cgus: I)
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!("");
......
......@@ -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);
}
......
......@@ -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") {
......
......@@ -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
......
......@@ -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"
......
......@@ -2030,6 +2030,31 @@ pub fn and_modify<F>(self, f: F) -> Self
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 @@ pub fn into_key(self) -> K {
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")]
......
......@@ -525,6 +525,9 @@ pub fn set(&self, features: &mut Features, span: Span) {
// 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 fn set(&self, features: &mut Features, span: Span) {
sym::or_patterns,
sym::let_chains,
sym::raw_dylib,
sym::track_caller,
];
......@@ -324,6 +324,7 @@ fn is_deprecated(&self) -> bool {
),
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:
......
......@@ -674,6 +674,7 @@
tool_attributes,
tool_lints,
trace_macros,
track_caller,
trait_alias,
transmute,
transparent,
......
// 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();
}
// 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();
}
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`.
#[track_caller]
fn f() {}
//~^^ ERROR the `#[track_caller]` attribute is an experimental feature
fn main() {}
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`.
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
#[track_caller(1)]
fn f() {}
//~^^ ERROR malformed `track_caller` attribute input
fn main() {}
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
#![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() {}
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`.
#![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() {}
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`.
#![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() {}
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`.
#![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() {}
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`.
#![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() {}
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`.
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
#[track_caller]
struct S;
//~^^ ERROR attribute should be applied to function
fn main() {}
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
// run-pass
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete
#[track_caller]
fn f() {}
fn main() {
f();
}
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册