Skip to content

Commit 45b0945

Browse files
authored
Rollup merge of rust-lang#60676 - davidtwco:issue-60674, r=cramertj
Fix async desugaring providing wrong input to procedural macros. Fixes rust-lang#60674. This PR fixes a minor oversight introduced by rust-lang#60535 where unused `mut` binding modes were removed from the arguments to an `async fn` (as they were added to the statement that we insert into the closure body). However, this meant that the input to procedural macros was incorrect. This removes that and instead fixes the `unused_mut` error that it avoided. r? @cramertj cc @taiki-e
2 parents f6df1f6 + d5e0406 commit 45b0945

File tree

6 files changed

+76
-43
lines changed

6 files changed

+76
-43
lines changed

src/librustc/hir/lowering.rs

+11-33
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ use errors::Applicability;
5050
use rustc_data_structures::fx::FxHashSet;
5151
use rustc_data_structures::indexed_vec::IndexVec;
5252
use rustc_data_structures::thin_vec::ThinVec;
53-
use rustc_data_structures::sync::Lrc;
5453

5554
use std::collections::{BTreeSet, BTreeMap};
5655
use std::mem;
@@ -59,10 +58,10 @@ use syntax::attr;
5958
use syntax::ast;
6059
use syntax::ast::*;
6160
use syntax::errors;
62-
use syntax::ext::hygiene::{Mark, SyntaxContext};
61+
use syntax::ext::hygiene::Mark;
6362
use syntax::print::pprust;
6463
use syntax::ptr::P;
65-
use syntax::source_map::{self, respan, CompilerDesugaringKind, Spanned};
64+
use syntax::source_map::{respan, CompilerDesugaringKind, Spanned};
6665
use syntax::std_inject;
6766
use syntax::symbol::{keywords, Symbol};
6867
use syntax::tokenstream::{TokenStream, TokenTree};
@@ -854,27 +853,6 @@ impl<'a> LoweringContext<'a> {
854853
Ident::with_empty_ctxt(Symbol::gensym(s))
855854
}
856855

857-
/// Reuses the span but adds information like the kind of the desugaring and features that are
858-
/// allowed inside this span.
859-
fn mark_span_with_reason(
860-
&self,
861-
reason: CompilerDesugaringKind,
862-
span: Span,
863-
allow_internal_unstable: Option<Lrc<[Symbol]>>,
864-
) -> Span {
865-
let mark = Mark::fresh(Mark::root());
866-
mark.set_expn_info(source_map::ExpnInfo {
867-
call_site: span,
868-
def_site: Some(span),
869-
format: source_map::CompilerDesugaring(reason),
870-
allow_internal_unstable,
871-
allow_internal_unsafe: false,
872-
local_inner_macros: false,
873-
edition: source_map::hygiene::default_edition(),
874-
});
875-
span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
876-
}
877-
878856
fn with_anonymous_lifetime_mode<R>(
879857
&mut self,
880858
anonymous_lifetime_mode: AnonymousLifetimeMode,
@@ -1162,7 +1140,7 @@ impl<'a> LoweringContext<'a> {
11621140
attrs: ThinVec::new(),
11631141
};
11641142

1165-
let unstable_span = self.mark_span_with_reason(
1143+
let unstable_span = self.sess.source_map().mark_span_with_reason(
11661144
CompilerDesugaringKind::Async,
11671145
span,
11681146
Some(vec![
@@ -1569,7 +1547,7 @@ impl<'a> LoweringContext<'a> {
15691547
// desugaring that explicitly states that we don't want to track that.
15701548
// Not tracking it makes lints in rustc and clippy very fragile as
15711549
// frequently opened issues show.
1572-
let exist_ty_span = self.mark_span_with_reason(
1550+
let exist_ty_span = self.sess.source_map().mark_span_with_reason(
15731551
CompilerDesugaringKind::ExistentialReturnType,
15741552
span,
15751553
None,
@@ -2443,7 +2421,7 @@ impl<'a> LoweringContext<'a> {
24432421
) -> hir::FunctionRetTy {
24442422
let span = output.span();
24452423

2446-
let exist_ty_span = self.mark_span_with_reason(
2424+
let exist_ty_span = self.sess.source_map().mark_span_with_reason(
24472425
CompilerDesugaringKind::Async,
24482426
span,
24492427
None,
@@ -4179,7 +4157,7 @@ impl<'a> LoweringContext<'a> {
41794157
}),
41804158
ExprKind::TryBlock(ref body) => {
41814159
self.with_catch_scope(body.id, |this| {
4182-
let unstable_span = this.mark_span_with_reason(
4160+
let unstable_span = this.sess.source_map().mark_span_with_reason(
41834161
CompilerDesugaringKind::TryBlock,
41844162
body.span,
41854163
Some(vec![
@@ -4612,7 +4590,7 @@ impl<'a> LoweringContext<'a> {
46124590
// expand <head>
46134591
let mut head = self.lower_expr(head);
46144592
let head_sp = head.span;
4615-
let desugared_span = self.mark_span_with_reason(
4593+
let desugared_span = self.sess.source_map().mark_span_with_reason(
46164594
CompilerDesugaringKind::ForLoop,
46174595
head_sp,
46184596
None,
@@ -4773,15 +4751,15 @@ impl<'a> LoweringContext<'a> {
47734751
// return Try::from_error(From::from(err)),
47744752
// }
47754753

4776-
let unstable_span = self.mark_span_with_reason(
4754+
let unstable_span = self.sess.source_map().mark_span_with_reason(
47774755
CompilerDesugaringKind::QuestionMark,
47784756
e.span,
47794757
Some(vec![
47804758
Symbol::intern("try_trait")
47814759
].into()),
47824760
);
47834761
let try_span = self.sess.source_map().end_point(e.span);
4784-
let try_span = self.mark_span_with_reason(
4762+
let try_span = self.sess.source_map().mark_span_with_reason(
47854763
CompilerDesugaringKind::QuestionMark,
47864764
try_span,
47874765
Some(vec![
@@ -5566,12 +5544,12 @@ impl<'a> LoweringContext<'a> {
55665544
);
55675545
self.sess.abort_if_errors();
55685546
}
5569-
let span = self.mark_span_with_reason(
5547+
let span = self.sess.source_map().mark_span_with_reason(
55705548
CompilerDesugaringKind::Await,
55715549
await_span,
55725550
None,
55735551
);
5574-
let gen_future_span = self.mark_span_with_reason(
5552+
let gen_future_span = self.sess.source_map().mark_span_with_reason(
55755553
CompilerDesugaringKind::Await,
55765554
await_span,
55775555
Some(vec![Symbol::intern("gen_future")].into()),

src/libsyntax/parse/parser.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ use crate::symbol::{Symbol, keywords};
5050

5151
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
5252
use rustc_target::spec::abi::{self, Abi};
53-
use syntax_pos::{Span, MultiSpan, BytePos, FileName};
53+
use syntax_pos::{
54+
Span, MultiSpan, BytePos, FileName,
55+
hygiene::CompilerDesugaringKind,
56+
};
5457
use log::{debug, trace};
5558

5659
use std::borrow::Cow;
@@ -8772,6 +8775,10 @@ impl<'a> Parser<'a> {
87728775
/// The arguments of the function are replaced in HIR lowering with the arguments created by
87738776
/// this function and the statements created here are inserted at the top of the closure body.
87748777
fn construct_async_arguments(&mut self, asyncness: &mut Spanned<IsAsync>, decl: &mut FnDecl) {
8778+
// FIXME(davidtwco): This function should really live in the HIR lowering but because
8779+
// the types constructed here need to be used in parts of resolve so that the correct
8780+
// locals are considered upvars, it is currently easier for it to live here in the parser,
8781+
// where it can be constructed once.
87758782
if let IsAsync::Async { ref mut arguments, .. } = asyncness.node {
87768783
for (index, input) in decl.inputs.iter_mut().enumerate() {
87778784
let id = ast::DUMMY_NODE_ID;
@@ -8786,6 +8793,15 @@ impl<'a> Parser<'a> {
87868793
// statement.
87878794
let (binding_mode, ident, is_simple_pattern) = match input.pat.node {
87888795
PatKind::Ident(binding_mode @ BindingMode::ByValue(_), ident, _) => {
8796+
// Simple patterns like this don't have a generated argument, but they are
8797+
// moved into the closure with a statement, so any `mut` bindings on the
8798+
// argument will be unused. This binding mode can't be removed, because
8799+
// this would affect the input to procedural macros, but they can have
8800+
// their span marked as being the result of a compiler desugaring so
8801+
// that they aren't linted against.
8802+
input.pat.span = self.sess.source_map().mark_span_with_reason(
8803+
CompilerDesugaringKind::Async, span, None);
8804+
87898805
(binding_mode, ident, true)
87908806
}
87918807
_ => (BindingMode::ByValue(Mutability::Mutable), ident, false),
@@ -8855,15 +8871,6 @@ impl<'a> Parser<'a> {
88558871
})
88568872
};
88578873

8858-
// Remove mutability from arguments. If this is not a simple pattern,
8859-
// those arguments are replaced by `__argN`, so there is no need to do this.
8860-
if let PatKind::Ident(BindingMode::ByValue(mutability @ Mutability::Mutable), ..) =
8861-
&mut input.pat.node
8862-
{
8863-
assert!(is_simple_pattern);
8864-
*mutability = Mutability::Immutable;
8865-
}
8866-
88678874
let move_stmt = Stmt { id, node: StmtKind::Local(P(move_local)), span };
88688875
arguments.push(AsyncArgument { ident, arg, pat_stmt, move_stmt });
88698876
}

src/libsyntax/source_map.rs

+21
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,27 @@ impl SourceMap {
930930

931931
None
932932
}
933+
934+
/// Reuses the span but adds information like the kind of the desugaring and features that are
935+
/// allowed inside this span.
936+
pub fn mark_span_with_reason(
937+
&self,
938+
reason: hygiene::CompilerDesugaringKind,
939+
span: Span,
940+
allow_internal_unstable: Option<Lrc<[symbol::Symbol]>>,
941+
) -> Span {
942+
let mark = Mark::fresh(Mark::root());
943+
mark.set_expn_info(ExpnInfo {
944+
call_site: span,
945+
def_site: Some(span),
946+
format: CompilerDesugaring(reason),
947+
allow_internal_unstable,
948+
allow_internal_unsafe: false,
949+
local_inner_macros: false,
950+
edition: hygiene::default_edition(),
951+
});
952+
span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
953+
}
933954
}
934955

935956
impl SourceMapper for SourceMap {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
#![crate_type = "proc-macro"]
4+
5+
extern crate proc_macro;
6+
use proc_macro::TokenStream;
7+
8+
#[proc_macro_attribute]
9+
pub fn attr(_args: TokenStream, input: TokenStream) -> TokenStream {
10+
println!("{}", input);
11+
TokenStream::new()
12+
}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// aux-build:issue-60674.rs
2+
// compile-pass
3+
// edition:2018
4+
#![feature(async_await)]
5+
6+
// This is a regression test that ensures that `mut` patterns are not lost when provided as input
7+
// to a proc macro.
8+
9+
extern crate issue_60674;
10+
11+
#[issue_60674::attr]
12+
async fn f(mut x: u8) {}
13+
14+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
async fn f(mut x: u8) { }

0 commit comments

Comments
 (0)