Skip to content

Commit c049e10

Browse files
committed
Auto merge of #65053 - Centril:rollup-nwp0wgf, r=Centril
Rollup of 5 pull requests Successful merges: - #64690 (proc_macro API: Expose `macro_rules` hygiene) - #64749 (Fix most remaining Polonius test differences) - #64938 (Avoid ICE on ReFree region on where clause) - #64999 (extract expected return type for async fn generators) - #65037 (`#[track_caller]` feature gate (RFC 2091)) Failed merges: r? @ghost
2 parents 0221e26 + 18ce550 commit c049e10

File tree

94 files changed

+1364
-1064
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+1364
-1064
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# `track_caller`
2+
3+
The tracking issue for this feature is: [#47809](https://github.com/rust-lang/rust/issues/47809).
4+
5+
------------------------

src/libproc_macro/bridge/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ macro_rules! with_api {
148148
fn debug($self: $S::Span) -> String;
149149
fn def_site() -> $S::Span;
150150
fn call_site() -> $S::Span;
151+
fn mixed_site() -> $S::Span;
151152
fn source_file($self: $S::Span) -> $S::SourceFile;
152153
fn parent($self: $S::Span) -> Option<$S::Span>;
153154
fn source($self: $S::Span) -> $S::Span;

src/libproc_macro/lib.rs

+9
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,15 @@ impl Span {
271271
Span(bridge::client::Span::call_site())
272272
}
273273

274+
/// A span that represents `macro_rules` hygiene, and sometimes resolves at the macro
275+
/// definition site (local variables, labels, `$crate`) and sometimes at the macro
276+
/// call site (everything else).
277+
/// The span location is taken from the call-site.
278+
#[unstable(feature = "proc_macro_mixed_site", issue = "65049")]
279+
pub fn mixed_site() -> Span {
280+
Span(bridge::client::Span::mixed_site())
281+
}
282+
274283
/// The original source file into which this span points.
275284
#[unstable(feature = "proc_macro_span", issue = "54725")]
276285
pub fn source_file(&self) -> SourceFile {

src/librustc/error_codes.rs

+10
Original file line numberDiff line numberDiff line change
@@ -2234,6 +2234,15 @@ These attributes are meant to only be used by the standard library and are
22342234
rejected in your own crates.
22352235
"##,
22362236

2237+
E0736: r##"
2238+
#[track_caller] and #[naked] cannot be applied to the same function.
2239+
2240+
This is primarily due to ABI incompatibilities between the two attributes.
2241+
See [RFC 2091] for details on this and other limitations.
2242+
2243+
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
2244+
"##,
2245+
22372246
;
22382247
// E0006, // merged with E0005
22392248
// E0101, // replaced with E0282
@@ -2296,4 +2305,5 @@ rejected in your own crates.
22962305
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
22972306
E0727, // `async` generators are not yet supported
22982307
E0728, // `await` must be in an `async` function or block
2308+
E0735, // invalid track_caller application/syntax
22992309
}

src/librustc/hir/check_attr.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::ty::TyCtxt;
1111
use crate::ty::query::Providers;
1212

1313
use std::fmt::{self, Display};
14-
use syntax::symbol::sym;
14+
use syntax::{attr, symbol::sym};
1515
use syntax_pos::Span;
1616

1717
#[derive(Copy, Clone, PartialEq)]
@@ -103,6 +103,8 @@ impl CheckAttrVisitor<'tcx> {
103103
self.check_marker(attr, item, target)
104104
} else if attr.check_name(sym::target_feature) {
105105
self.check_target_feature(attr, item, target)
106+
} else if attr.check_name(sym::track_caller) {
107+
self.check_track_caller(attr, &item, target)
106108
} else {
107109
true
108110
};
@@ -135,6 +137,32 @@ impl CheckAttrVisitor<'tcx> {
135137
}
136138
}
137139

140+
/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
141+
fn check_track_caller(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) -> bool {
142+
if target != Target::Fn {
143+
struct_span_err!(
144+
self.tcx.sess,
145+
attr.span,
146+
E0735,
147+
"attribute should be applied to function"
148+
)
149+
.span_label(item.span, "not a function")
150+
.emit();
151+
false
152+
} else if attr::contains_name(&item.attrs, sym::naked) {
153+
struct_span_err!(
154+
self.tcx.sess,
155+
attr.span,
156+
E0736,
157+
"cannot use `#[track_caller]` with `#[naked]`",
158+
)
159+
.emit();
160+
false
161+
} else {
162+
true
163+
}
164+
}
165+
138166
/// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid.
139167
fn check_non_exhaustive(
140168
&self,

src/librustc/hir/lowering/expr.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,14 @@ impl LoweringContext<'_> {
8989
hir::MatchSource::Normal,
9090
),
9191
ExprKind::Async(capture_clause, closure_node_id, ref block) => {
92-
self.make_async_expr(capture_clause, closure_node_id, None, block.span, |this| {
93-
this.with_new_scopes(|this| this.lower_block_expr(block))
94-
})
92+
self.make_async_expr(
93+
capture_clause,
94+
closure_node_id,
95+
None,
96+
block.span,
97+
hir::AsyncGeneratorKind::Block,
98+
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
99+
)
95100
}
96101
ExprKind::Await(ref expr) => self.lower_expr_await(e.span, expr),
97102
ExprKind::Closure(
@@ -457,6 +462,7 @@ impl LoweringContext<'_> {
457462
closure_node_id: NodeId,
458463
ret_ty: Option<AstP<Ty>>,
459464
span: Span,
465+
async_gen_kind: hir::AsyncGeneratorKind,
460466
body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
461467
) -> hir::ExprKind {
462468
let capture_clause = self.lower_capture_clause(capture_clause);
@@ -470,7 +476,7 @@ impl LoweringContext<'_> {
470476
};
471477
let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None);
472478
let body_id = self.lower_fn_body(&ast_decl, |this| {
473-
this.generator_kind = Some(hir::GeneratorKind::Async);
479+
this.generator_kind = Some(hir::GeneratorKind::Async(async_gen_kind));
474480
body(this)
475481
});
476482

@@ -522,7 +528,7 @@ impl LoweringContext<'_> {
522528
/// ```
523529
fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind {
524530
match self.generator_kind {
525-
Some(hir::GeneratorKind::Async) => {},
531+
Some(hir::GeneratorKind::Async(_)) => {},
526532
Some(hir::GeneratorKind::Gen) |
527533
None => {
528534
let mut err = struct_span_err!(
@@ -727,7 +733,7 @@ impl LoweringContext<'_> {
727733
Movability::Static => hir::GeneratorMovability::Static,
728734
})
729735
},
730-
Some(hir::GeneratorKind::Async) => {
736+
Some(hir::GeneratorKind::Async(_)) => {
731737
bug!("non-`async` closure body turned `async` during lowering");
732738
},
733739
None => {
@@ -786,10 +792,12 @@ impl LoweringContext<'_> {
786792
None
787793
};
788794
let async_body = this.make_async_expr(
789-
capture_clause, closure_id, async_ret_ty, body.span,
790-
|this| {
791-
this.with_new_scopes(|this| this.lower_expr(body))
792-
}
795+
capture_clause,
796+
closure_id,
797+
async_ret_ty,
798+
body.span,
799+
hir::AsyncGeneratorKind::Closure,
800+
|this| this.with_new_scopes(|this| this.lower_expr(body)),
793801
);
794802
this.expr(fn_decl_span, async_body, ThinVec::new())
795803
});
@@ -1005,7 +1013,7 @@ impl LoweringContext<'_> {
10051013
fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind {
10061014
match self.generator_kind {
10071015
Some(hir::GeneratorKind::Gen) => {},
1008-
Some(hir::GeneratorKind::Async) => {
1016+
Some(hir::GeneratorKind::Async(_)) => {
10091017
span_err!(
10101018
self.sess,
10111019
span,

src/librustc/hir/lowering/item.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,11 @@ impl LoweringContext<'_> {
12221222
}
12231223

12241224
let async_expr = this.make_async_expr(
1225-
CaptureBy::Value, closure_id, None, body.span,
1225+
CaptureBy::Value,
1226+
closure_id,
1227+
None,
1228+
body.span,
1229+
hir::AsyncGeneratorKind::Fn,
12261230
|this| {
12271231
// Create a block from the user's function body:
12281232
let user_body = this.lower_block_expr(body);

src/librustc/hir/mod.rs

+37-6
Original file line numberDiff line numberDiff line change
@@ -1362,21 +1362,49 @@ impl Body {
13621362
}
13631363

13641364
/// The type of source expression that caused this generator to be created.
1365-
// Not `IsAsync` because we want to eventually add support for `AsyncGen`
13661365
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
13671366
RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
13681367
pub enum GeneratorKind {
1369-
/// An `async` block or function.
1370-
Async,
1368+
/// An explicit `async` block or the body of an async function.
1369+
Async(AsyncGeneratorKind),
1370+
13711371
/// A generator literal created via a `yield` inside a closure.
13721372
Gen,
13731373
}
13741374

13751375
impl fmt::Display for GeneratorKind {
1376+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1377+
match self {
1378+
GeneratorKind::Async(k) => fmt::Display::fmt(k, f),
1379+
GeneratorKind::Gen => f.write_str("generator"),
1380+
}
1381+
}
1382+
}
1383+
1384+
/// In the case of a generator created as part of an async construct,
1385+
/// which kind of async construct caused it to be created?
1386+
///
1387+
/// This helps error messages but is also used to drive coercions in
1388+
/// type-checking (see #60424).
1389+
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
1390+
RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1391+
pub enum AsyncGeneratorKind {
1392+
/// An explicit `async` block written by the user.
1393+
Block,
1394+
1395+
/// An explicit `async` block written by the user.
1396+
Closure,
1397+
1398+
/// The `async` block generated as the body of an async function.
1399+
Fn,
1400+
}
1401+
1402+
impl fmt::Display for AsyncGeneratorKind {
13761403
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13771404
f.write_str(match self {
1378-
GeneratorKind::Async => "`async` object",
1379-
GeneratorKind::Gen => "generator",
1405+
AsyncGeneratorKind::Block => "`async` block",
1406+
AsyncGeneratorKind::Closure => "`async` closure body",
1407+
AsyncGeneratorKind::Fn => "`async fn` body",
13801408
})
13811409
}
13821410
}
@@ -1758,6 +1786,7 @@ pub struct Destination {
17581786
pub enum GeneratorMovability {
17591787
/// May contain self-references, `!Unpin`.
17601788
Static,
1789+
17611790
/// Must not contain self-references, `Unpin`.
17621791
Movable,
17631792
}
@@ -2687,7 +2716,9 @@ bitflags! {
26872716
const USED = 1 << 9;
26882717
/// #[ffi_returns_twice], indicates that an extern function can return
26892718
/// multiple times
2690-
const FFI_RETURNS_TWICE = 1 << 10;
2719+
const FFI_RETURNS_TWICE = 1 << 10;
2720+
/// #[track_caller]: allow access to the caller location
2721+
const TRACK_CALLER = 1 << 11;
26912722
}
26922723
}
26932724

src/librustc/infer/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13191319
}
13201320
}
13211321

1322+
/// Resolve any type variables found in `value` -- but only one
1323+
/// level. So, if the variable `?X` is bound to some type
1324+
/// `Foo<?Y>`, then this would return `Foo<?Y>` (but `?Y` may
1325+
/// itself be bound to a type).
1326+
///
1327+
/// Useful when you only need to inspect the outermost level of
1328+
/// the type and don't care about nested types (or perhaps you
1329+
/// will be resolving them as well, e.g. in a loop).
13221330
pub fn shallow_resolve<T>(&self, value: T) -> T
13231331
where
13241332
T: TypeFoldable<'tcx>,
@@ -1579,6 +1587,9 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
15791587
ShallowResolver { infcx }
15801588
}
15811589

1590+
/// If `typ` is a type variable of some kind, resolve it one level
1591+
/// (but do not resolve types found in the result). If `typ` is
1592+
/// not a type variable, just return it unmodified.
15821593
pub fn shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
15831594
match typ.kind {
15841595
ty::Infer(ty::TyVar(v)) => {

src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs

+4
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ impl LocalUseMap {
7070
appearances: IndexVec::new(),
7171
};
7272

73+
if live_locals.is_empty() {
74+
return local_use_map;
75+
}
76+
7377
let mut locals_with_use_data: IndexVec<Local, bool> =
7478
IndexVec::from_elem_n(false, body.local_decls.len());
7579
live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);

src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs

+30-22
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,39 @@ pub(super) fn generate<'tcx>(
3636
) {
3737
debug!("liveness::generate");
3838

39-
let live_locals: Vec<Local> = if AllFacts::enabled(typeck.tcx()) {
40-
// If "dump facts from NLL analysis" was requested perform
41-
// the liveness analysis for all `Local`s. This case opens
42-
// the possibility of the variables being analyzed in `trace`
43-
// to be *any* `Local`, not just the "live" ones, so we can't
44-
// make any assumptions past this point as to the characteristics
45-
// of the `live_locals`.
46-
// FIXME: Review "live" terminology past this point, we should
47-
// not be naming the `Local`s as live.
48-
body.local_decls.indices().collect()
39+
let free_regions = regions_that_outlive_free_regions(
40+
typeck.infcx.num_region_vars(),
41+
&typeck.borrowck_context.universal_regions,
42+
&typeck.borrowck_context.constraints.outlives_constraints,
43+
);
44+
let live_locals = compute_live_locals(typeck.tcx(), &free_regions, body);
45+
let facts_enabled = AllFacts::enabled(typeck.tcx());
46+
47+
48+
let polonius_drop_used = if facts_enabled {
49+
let mut drop_used = Vec::new();
50+
polonius::populate_access_facts(
51+
typeck,
52+
body,
53+
location_table,
54+
move_data,
55+
&mut drop_used,
56+
);
57+
Some(drop_used)
4958
} else {
50-
let free_regions = {
51-
regions_that_outlive_free_regions(
52-
typeck.infcx.num_region_vars(),
53-
&typeck.borrowck_context.universal_regions,
54-
&typeck.borrowck_context.constraints.outlives_constraints,
55-
)
56-
};
57-
compute_live_locals(typeck.tcx(), &free_regions, body)
59+
None
5860
};
5961

60-
if !live_locals.is_empty() {
61-
trace::trace(typeck, body, elements, flow_inits, move_data, live_locals);
62-
63-
polonius::populate_access_facts(typeck, body, location_table, move_data);
62+
if !live_locals.is_empty() || facts_enabled {
63+
trace::trace(
64+
typeck,
65+
body,
66+
elements,
67+
flow_inits,
68+
move_data,
69+
live_locals,
70+
polonius_drop_used,
71+
);
6472
}
6573
}
6674

0 commit comments

Comments
 (0)