diff options
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_ast_lowering/Cargo.toml | 2 | ||||
-rw-r--r-- | compiler/rustc_ast_lowering/src/asm.rs | 43 | ||||
-rw-r--r-- | compiler/rustc_ast_lowering/src/block.rs | 10 | ||||
-rw-r--r-- | compiler/rustc_ast_lowering/src/errors.rs | 3 | ||||
-rw-r--r-- | compiler/rustc_ast_lowering/src/expr.rs | 439 | ||||
-rw-r--r-- | compiler/rustc_ast_lowering/src/index.rs | 10 | ||||
-rw-r--r-- | compiler/rustc_ast_lowering/src/item.rs | 343 | ||||
-rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 365 | ||||
-rw-r--r-- | compiler/rustc_ast_lowering/src/pat.rs | 59 | ||||
-rw-r--r-- | compiler/rustc_ast_lowering/src/path.rs | 58 |
10 files changed, 626 insertions, 706 deletions
diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index ce1c8d499..6a59b9e61 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -21,5 +21,5 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 450cdf246..dfef6ec70 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -11,7 +11,7 @@ use super::LoweringContext; use rustc_ast::ptr::P; use rustc_ast::*; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::definitions::DefPathData; @@ -71,7 +71,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .emit(); } - let mut clobber_abis = FxHashMap::default(); + let mut clobber_abis = FxIndexMap::default(); if let Some(asm_arch) = asm_arch { for (abi_name, abi_span) in &asm.clobber_abis { match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) { @@ -123,7 +123,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .operands .iter() .map(|(op, op_sp)| { - let lower_reg = |reg| match reg { + let lower_reg = |®: &_| match reg { InlineAsmRegOrRegClass::Reg(reg) => { asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch { asm::InlineAsmReg::parse(asm_arch, reg).unwrap_or_else(|error| { @@ -152,32 +152,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } }; - let op = match *op { - InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In { + let op = match op { + InlineAsmOperand::In { reg, expr } => hir::InlineAsmOperand::In { reg: lower_reg(reg), expr: self.lower_expr(expr), }, - InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out { + InlineAsmOperand::Out { reg, late, expr } => hir::InlineAsmOperand::Out { reg: lower_reg(reg), - late, + late: *late, expr: expr.as_ref().map(|expr| self.lower_expr(expr)), }, - InlineAsmOperand::InOut { reg, late, ref expr } => { - hir::InlineAsmOperand::InOut { - reg: lower_reg(reg), - late, - expr: self.lower_expr(expr), - } - } - InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => { + InlineAsmOperand::InOut { reg, late, expr } => hir::InlineAsmOperand::InOut { + reg: lower_reg(reg), + late: *late, + expr: self.lower_expr(expr), + }, + InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => { hir::InlineAsmOperand::SplitInOut { reg: lower_reg(reg), - late, + late: *late, in_expr: self.lower_expr(in_expr), out_expr: out_expr.as_ref().map(|expr| self.lower_expr(expr)), } } - InlineAsmOperand::Const { ref anon_const } => { + InlineAsmOperand::Const { anon_const } => { if !self.tcx.features().asm_const { feature_err( &sess.parse_sess, @@ -191,7 +189,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { anon_const: self.lower_anon_const(anon_const), } } - InlineAsmOperand::Sym { ref sym } => { + InlineAsmOperand::Sym { sym } => { let static_def_id = self .resolver .get_partial_res(sym.id) @@ -224,7 +222,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Wrap the expression in an AnonConst. let parent_def_id = self.current_hir_id_owner; let node_id = self.next_node_id(); - self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst); + self.create_def( + parent_def_id.def_id, + node_id, + DefPathData::AnonConst, + *op_sp, + ); let anon_const = AnonConst { id: node_id, value: P(expr) }; hir::InlineAsmOperand::SymFn { anon_const: self.lower_anon_const(&anon_const), @@ -347,7 +350,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { skip = true; let idx2 = *o.get(); - let &(ref op2, op_sp2) = &operands[idx2]; + let (ref op2, op_sp2) = operands[idx2]; let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg() else { unreachable!(); }; diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index 12a0cc0d2..d310f72f7 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -31,8 +31,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let mut stmts = SmallVec::<[hir::Stmt<'hir>; 8]>::new(); let mut expr = None; while let [s, tail @ ..] = ast_stmts { - match s.kind { - StmtKind::Local(ref local) => { + match &s.kind { + StmtKind::Local(local) => { let hir_id = self.lower_node_id(s.id); let local = self.lower_local(local); self.alias_attrs(hir_id, local.hir_id); @@ -40,7 +40,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let span = self.lower_span(s.span); stmts.push(hir::Stmt { hir_id, kind, span }); } - StmtKind::Item(ref it) => { + StmtKind::Item(it) => { stmts.extend(self.lower_item_ref(it).into_iter().enumerate().map( |(i, item_id)| { let hir_id = match i { @@ -53,7 +53,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }, )); } - StmtKind::Expr(ref e) => { + StmtKind::Expr(e) => { let e = self.lower_expr(e); if tail.is_empty() { expr = Some(e); @@ -65,7 +65,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { stmts.push(hir::Stmt { hir_id, kind, span }); } } - StmtKind::Semi(ref e) => { + StmtKind::Semi(e) => { let e = self.lower_expr(e); let hir_id = self.lower_node_id(s.id); self.alias_attrs(hir_id, e.hir_id); diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 157f46501..21c6a2d26 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -277,8 +277,9 @@ pub struct RegisterConflict<'a> { pub struct SubTupleBinding<'a> { #[primary_span] #[label] - #[suggestion_verbose( + #[suggestion( ast_lowering_sub_tuple_binding_suggestion, + style = "verbose", code = "..", applicability = "maybe-incorrect" )] diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index ec9c39350..7dd6d5acc 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -14,6 +14,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::definitions::DefPathData; +use rustc_session::errors::report_lit_error; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; use rustc_span::symbol::{sym, Ident}; use rustc_span::DUMMY_SP; @@ -30,20 +31,20 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> { ensure_sufficient_stack(|| { - let kind = match e.kind { - ExprKind::Box(ref inner) => hir::ExprKind::Box(self.lower_expr(inner)), - ExprKind::Array(ref exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), - ExprKind::ConstBlock(ref anon_const) => { + let kind = match &e.kind { + ExprKind::Box(inner) => hir::ExprKind::Box(self.lower_expr(inner)), + ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), + ExprKind::ConstBlock(anon_const) => { let anon_const = self.lower_anon_const(anon_const); hir::ExprKind::ConstBlock(anon_const) } - ExprKind::Repeat(ref expr, ref count) => { + ExprKind::Repeat(expr, count) => { let expr = self.lower_expr(expr); let count = self.lower_array_length(count); hir::ExprKind::Repeat(expr, count) } - ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)), - ExprKind::Call(ref f, ref args) => { + ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)), + ExprKind::Call(f, args) => { if e.attrs.get(0).map_or(false, |a| a.has_name(sym::rustc_box)) { if let [inner] = &args[..] && e.attrs.len() == 1 { let kind = hir::ExprKind::Box(self.lower_expr(&inner)); @@ -60,7 +61,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::Call(f, self.lower_exprs(args)) } } - ExprKind::MethodCall(ref seg, ref receiver, ref args, span) => { + ExprKind::MethodCall(box MethodCall { seg, receiver, args, span }) => { let hir_seg = self.arena.alloc(self.lower_path_segment( e.span, seg, @@ -71,81 +72,89 @@ impl<'hir> LoweringContext<'_, 'hir> { let receiver = self.lower_expr(receiver); let args = self.arena.alloc_from_iter(args.iter().map(|x| self.lower_expr_mut(x))); - hir::ExprKind::MethodCall(hir_seg, receiver, args, self.lower_span(span)) + hir::ExprKind::MethodCall(hir_seg, receiver, args, self.lower_span(*span)) } - ExprKind::Binary(binop, ref lhs, ref rhs) => { - let binop = self.lower_binop(binop); + ExprKind::Binary(binop, lhs, rhs) => { + let binop = self.lower_binop(*binop); let lhs = self.lower_expr(lhs); let rhs = self.lower_expr(rhs); hir::ExprKind::Binary(binop, lhs, rhs) } - ExprKind::Unary(op, ref ohs) => { - let op = self.lower_unop(op); + ExprKind::Unary(op, ohs) => { + let op = self.lower_unop(*op); let ohs = self.lower_expr(ohs); hir::ExprKind::Unary(op, ohs) } - ExprKind::Lit(ref l) => { - hir::ExprKind::Lit(respan(self.lower_span(l.span), l.kind.clone())) + ExprKind::Lit(token_lit) => { + let lit_kind = match LitKind::from_token_lit(*token_lit) { + Ok(lit_kind) => lit_kind, + Err(err) => { + report_lit_error(&self.tcx.sess.parse_sess, err, *token_lit, e.span); + LitKind::Err + } + }; + hir::ExprKind::Lit(respan(self.lower_span(e.span), lit_kind)) } - ExprKind::Cast(ref expr, ref ty) => { + ExprKind::IncludedBytes(bytes) => hir::ExprKind::Lit(respan( + self.lower_span(e.span), + LitKind::ByteStr(bytes.clone()), + )), + ExprKind::Cast(expr, ty) => { let expr = self.lower_expr(expr); let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); hir::ExprKind::Cast(expr, ty) } - ExprKind::Type(ref expr, ref ty) => { + ExprKind::Type(expr, ty) => { let expr = self.lower_expr(expr); let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); hir::ExprKind::Type(expr, ty) } - ExprKind::AddrOf(k, m, ref ohs) => { + ExprKind::AddrOf(k, m, ohs) => { let ohs = self.lower_expr(ohs); - hir::ExprKind::AddrOf(k, m, ohs) + hir::ExprKind::AddrOf(*k, *m, ohs) } - ExprKind::Let(ref pat, ref scrutinee, span) => { + ExprKind::Let(pat, scrutinee, span) => { hir::ExprKind::Let(self.arena.alloc(hir::Let { hir_id: self.next_id(), - span: self.lower_span(span), + span: self.lower_span(*span), pat: self.lower_pat(pat), ty: None, init: self.lower_expr(scrutinee), })) } - ExprKind::If(ref cond, ref then, ref else_opt) => { + ExprKind::If(cond, then, else_opt) => { self.lower_expr_if(cond, then, else_opt.as_deref()) } - ExprKind::While(ref cond, ref body, opt_label) => { - self.with_loop_scope(e.id, |this| { - let span = - this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None); - this.lower_expr_while_in_loop_scope(span, cond, body, opt_label) - }) - } - ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| { + ExprKind::While(cond, body, opt_label) => self.with_loop_scope(e.id, |this| { + let span = this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None); + this.lower_expr_while_in_loop_scope(span, cond, body, *opt_label) + }), + ExprKind::Loop(body, opt_label, span) => self.with_loop_scope(e.id, |this| { hir::ExprKind::Loop( this.lower_block(body, false), - this.lower_label(opt_label), + this.lower_label(*opt_label), hir::LoopSource::Loop, - DUMMY_SP, + this.lower_span(*span), ) }), - ExprKind::TryBlock(ref body) => self.lower_expr_try_block(body), - ExprKind::Match(ref expr, ref arms) => hir::ExprKind::Match( + ExprKind::TryBlock(body) => self.lower_expr_try_block(body), + ExprKind::Match(expr, arms) => hir::ExprKind::Match( self.lower_expr(expr), self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))), hir::MatchSource::Normal, ), - ExprKind::Async(capture_clause, closure_node_id, ref block) => self - .make_async_expr( - capture_clause, - closure_node_id, - None, - block.span, - hir::AsyncGeneratorKind::Block, - |this| this.with_new_scopes(|this| this.lower_block_expr(block)), - ), - ExprKind::Await(ref expr) => { + ExprKind::Async(capture_clause, closure_node_id, block) => self.make_async_expr( + *capture_clause, + None, + *closure_node_id, + None, + e.span, + hir::AsyncGeneratorKind::Block, + |this| this.with_new_scopes(|this| this.lower_block_expr(block)), + ), + ExprKind::Await(expr) => { let dot_await_span = if expr.span.hi() < e.span.hi() { let span_with_whitespace = self .tcx @@ -160,66 +169,67 @@ impl<'hir> LoweringContext<'_, 'hir> { }; self.lower_expr_await(dot_await_span, expr) } - ExprKind::Closure( - ref binder, + ExprKind::Closure(box Closure { + binder, capture_clause, asyncness, movability, - ref decl, - ref body, + fn_decl, + body, fn_decl_span, - ) => { + fn_arg_span, + }) => { if let Async::Yes { closure_id, .. } = asyncness { self.lower_expr_async_closure( binder, - capture_clause, + *capture_clause, e.id, - closure_id, - decl, + *closure_id, + fn_decl, body, - fn_decl_span, + *fn_decl_span, + *fn_arg_span, ) } else { self.lower_expr_closure( binder, - capture_clause, + *capture_clause, e.id, - movability, - decl, + *movability, + fn_decl, body, - fn_decl_span, + *fn_decl_span, + *fn_arg_span, ) } } - ExprKind::Block(ref blk, opt_label) => { - let opt_label = self.lower_label(opt_label); + ExprKind::Block(blk, opt_label) => { + let opt_label = self.lower_label(*opt_label); hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label) } - ExprKind::Assign(ref el, ref er, span) => { - self.lower_expr_assign(el, er, span, e.span) - } - ExprKind::AssignOp(op, ref el, ref er) => hir::ExprKind::AssignOp( - self.lower_binop(op), + ExprKind::Assign(el, er, span) => self.lower_expr_assign(el, er, *span, e.span), + ExprKind::AssignOp(op, el, er) => hir::ExprKind::AssignOp( + self.lower_binop(*op), self.lower_expr(el), self.lower_expr(er), ), - ExprKind::Field(ref el, ident) => { - hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(ident)) + ExprKind::Field(el, ident) => { + hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(*ident)) } - ExprKind::Index(ref el, ref er) => { + ExprKind::Index(el, er) => { hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er)) } - ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => { + ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => { self.lower_expr_range_closed(e.span, e1, e2) } - ExprKind::Range(ref e1, ref e2, lims) => { - self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims) + ExprKind::Range(e1, e2, lims) => { + self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), *lims) } ExprKind::Underscore => { self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span }); hir::ExprKind::Err } - ExprKind::Path(ref qself, ref path) => { + ExprKind::Path(qself, path) => { let qpath = self.lower_qpath( e.id, qself, @@ -229,22 +239,22 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ExprKind::Path(qpath) } - ExprKind::Break(opt_label, ref opt_expr) => { + ExprKind::Break(opt_label, opt_expr) => { let opt_expr = opt_expr.as_ref().map(|x| self.lower_expr(x)); - hir::ExprKind::Break(self.lower_jump_destination(e.id, opt_label), opt_expr) + hir::ExprKind::Break(self.lower_jump_destination(e.id, *opt_label), opt_expr) } ExprKind::Continue(opt_label) => { - hir::ExprKind::Continue(self.lower_jump_destination(e.id, opt_label)) + hir::ExprKind::Continue(self.lower_jump_destination(e.id, *opt_label)) } - ExprKind::Ret(ref e) => { + ExprKind::Ret(e) => { let e = e.as_ref().map(|x| self.lower_expr(x)); hir::ExprKind::Ret(e) } - ExprKind::Yeet(ref sub_expr) => self.lower_expr_yeet(e.span, sub_expr.as_deref()), - ExprKind::InlineAsm(ref asm) => { + ExprKind::Yeet(sub_expr) => self.lower_expr_yeet(e.span, sub_expr.as_deref()), + ExprKind::InlineAsm(asm) => { hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm)) } - ExprKind::Struct(ref se) => { + ExprKind::Struct(se) => { let rest = match &se.rest { StructRest::Base(e) => Some(self.lower_expr(e)), StructRest::Rest(sp) => { @@ -266,10 +276,10 @@ impl<'hir> LoweringContext<'_, 'hir> { rest, ) } - ExprKind::Yield(ref opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()), + ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()), ExprKind::Err => hir::ExprKind::Err, - ExprKind::Try(ref sub_expr) => self.lower_expr_try(e.span, sub_expr), - ExprKind::Paren(ref ex) => { + ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr), + ExprKind::Paren(ex) => { let mut ex = self.lower_expr_mut(ex); // Include parens in span, but only if it is a super-span. if e.span.contains(ex.span) { @@ -294,8 +304,8 @@ impl<'hir> LoweringContext<'_, 'hir> { // Desugar `ExprForLoop` // from: `[opt_ident]: for <pat> in <head> <body>` - ExprKind::ForLoop(ref pat, ref head, ref body, opt_label) => { - return self.lower_expr_for(e, pat, head, body, opt_label); + ExprKind::ForLoop(pat, head, body, opt_label) => { + return self.lower_expr_for(e, pat, head, body, *opt_label); } ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span), }; @@ -346,7 +356,7 @@ impl<'hir> LoweringContext<'_, 'hir> { args: Vec<AstP<Expr>>, legacy_args_idx: &[usize], ) -> hir::ExprKind<'hir> { - let ExprKind::Path(None, ref mut path) = f.kind else { + let ExprKind::Path(None, path) = &mut f.kind else { unreachable!(); }; @@ -359,7 +369,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let node_id = self.next_node_id(); // Add a definition for the in-band const def. - self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst); + self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst, f.span); let anon_const = AnonConst { id: node_id, value: arg }; generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const))); @@ -426,18 +436,14 @@ impl<'hir> LoweringContext<'_, 'hir> { let lhs = self.lower_cond(lhs); let rhs = self.lower_cond(rhs); - self.arena.alloc(self.expr( - cond.span, - hir::ExprKind::Binary(op, lhs, rhs), - AttrVec::new(), - )) + self.arena.alloc(self.expr(cond.span, hir::ExprKind::Binary(op, lhs, rhs))) } ExprKind::Let(..) => self.lower_expr(cond), _ => { let cond = self.lower_expr(cond); let reason = DesugaringKind::CondTemporary; let span_block = self.mark_span_with_reason(reason, cond.span, None); - self.expr_drop_temps(span_block, cond, AttrVec::new()) + self.expr_drop_temps(span_block, cond) } } } @@ -467,12 +473,12 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::ExprKind<'hir> { let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond)); let then = self.lower_block_expr(body); - let expr_break = self.expr_break(span, AttrVec::new()); + let expr_break = self.expr_break(span); let stmt_break = self.stmt_expr(span, expr_break); let else_blk = self.block_all(span, arena_vec![self; stmt_break], None); - let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new())); + let else_expr = self.arena.alloc(self.expr_block(else_blk)); let if_kind = hir::ExprKind::If(lowered_cond, self.arena.alloc(then), Some(else_expr)); - let if_expr = self.expr(span, if_kind, AttrVec::new()); + let if_expr = self.expr(span, if_kind); let block = self.block_expr(self.arena.alloc(if_expr)); let span = self.lower_span(span.with_hi(cond.span.hi())); let opt_label = self.lower_label(opt_label); @@ -528,22 +534,17 @@ impl<'hir> LoweringContext<'_, 'hir> { expr: &'hir hir::Expr<'hir>, overall_span: Span, ) -> &'hir hir::Expr<'hir> { - let constructor = self.arena.alloc(self.expr_lang_item_path( - method_span, - lang_item, - AttrVec::new(), - None, - )); + let constructor = self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, None)); self.expr_call(overall_span, constructor, std::slice::from_ref(expr)) } fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> { let pat = self.lower_pat(&arm.pat); let guard = arm.guard.as_ref().map(|cond| { - if let ExprKind::Let(ref pat, ref scrutinee, span) = cond.kind { + if let ExprKind::Let(pat, scrutinee, span) = &cond.kind { hir::Guard::IfLet(self.arena.alloc(hir::Let { hir_id: self.next_id(), - span: self.lower_span(span), + span: self.lower_span(*span), pat: self.lower_pat(pat), ty: None, init: self.lower_expr(scrutinee), @@ -563,37 +564,35 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - /// Lower an `async` construct to a generator that is then wrapped so it implements `Future`. + /// Lower an `async` construct to a generator that implements `Future`. /// /// This results in: /// /// ```text - /// std::future::from_generator(static move? |_task_context| -> <ret_ty> { + /// std::future::identity_future(static move? |_task_context| -> <ret_ty> { /// <body> /// }) /// ``` pub(super) fn make_async_expr( &mut self, capture_clause: CaptureBy, + outer_hir_id: Option<hir::HirId>, closure_node_id: NodeId, - ret_ty: Option<AstP<Ty>>, + ret_ty: Option<hir::FnRetTy<'hir>>, span: Span, async_gen_kind: hir::AsyncGeneratorKind, body: impl FnOnce(&mut Self) -> hir::Expr<'hir>, ) -> hir::ExprKind<'hir> { - let output = match ret_ty { - Some(ty) => hir::FnRetTy::Return( - self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)), - ), - None => hir::FnRetTy::DefaultReturn(self.lower_span(span)), - }; + let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span))); - // Resume argument type. We let the compiler infer this to simplify the lowering. It is - // fully constrained by `future::from_generator`. + // Resume argument type: `ResumeTy` + let unstable_span = + self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); + let resume_ty = hir::QPath::LangItem(hir::LangItem::ResumeTy, unstable_span, None); let input_ty = hir::Ty { hir_id: self.next_id(), - kind: hir::TyKind::Infer, - span: self.lower_span(span), + kind: hir::TyKind::Path(resume_ty), + span: unstable_span, }; // The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`. @@ -602,6 +601,7 @@ impl<'hir> LoweringContext<'_, 'hir> { output, c_variadic: false, implicit_self: hir::ImplicitSelfKind::None, + lifetime_elision_allowed: false, }); // Lower the argument pattern/ident. The ident is used again in the `.await` lowering. @@ -631,35 +631,63 @@ impl<'hir> LoweringContext<'_, 'hir> { // `static |_task_context| -> <ret_ty> { body }`: let generator_kind = { let c = self.arena.alloc(hir::Closure { + def_id: self.local_def_id(closure_node_id), binder: hir::ClosureBinder::Default, capture_clause, bound_generic_params: &[], fn_decl, body, fn_decl_span: self.lower_span(span), + fn_arg_span: None, movability: Some(hir::Movability::Static), }); hir::ExprKind::Closure(c) }; - let generator = hir::Expr { - hir_id: self.lower_node_id(closure_node_id), - kind: generator_kind, - span: self.lower_span(span), - }; - // `future::from_generator`: + let hir_id = self.lower_node_id(closure_node_id); let unstable_span = self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); - let gen_future = self.expr_lang_item_path( - unstable_span, - hir::LangItem::FromGenerator, - AttrVec::new(), - None, - ); - // `future::from_generator(generator)`: - hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator]) + if self.tcx.features().closure_track_caller + && let Some(outer_hir_id) = outer_hir_id + && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id) + && attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)) + { + self.lower_attrs( + hir_id, + &[Attribute { + kind: AttrKind::Normal(ptr::P(NormalAttr { + item: AttrItem { + path: Path::from_ident(Ident::new(sym::track_caller, span)), + args: AttrArgs::Empty, + tokens: None, + }, + tokens: None, + })), + id: self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(), + style: AttrStyle::Outer, + span: unstable_span, + }], + ); + } + + let generator = hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) }; + + // FIXME(swatinem): + // For some reason, the async block needs to flow through *any* + // call (like the identity function), as otherwise type and lifetime + // inference have a hard time figuring things out. + // Without this, we would get: + // E0720 in src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs + // E0700 in src/test/ui/self/self_lifetime-async.rs + + // `future::identity_future`: + let identity_future = + self.expr_lang_item_path(unstable_span, hir::LangItem::IdentityFuture, None); + + // `future::identity_future(generator)`: + hir::ExprKind::Call(self.arena.alloc(identity_future), arena_vec![self; generator]) } /// Desugar `<expr>.await` into: @@ -759,7 +787,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let break_x = self.with_loop_scope(loop_node_id, move |this| { let expr_break = hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr)); - this.arena.alloc(this.expr(gen_future_span, expr_break, AttrVec::new())) + this.arena.alloc(this.expr(gen_future_span, expr_break)) }); self.arm(ready_pat, break_x) }; @@ -792,17 +820,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let yield_expr = self.expr( span, hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }), - AttrVec::new(), ); let yield_expr = self.arena.alloc(yield_expr); if let Some(task_context_hid) = self.task_context { let lhs = self.expr_ident(span, task_context_ident, task_context_hid); - let assign = self.expr( - span, - hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)), - AttrVec::new(), - ); + let assign = + self.expr(span, hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span))); self.stmt_expr(span, assign) } else { // Use of `await` outside of an async context. Return `yield_expr` so that we can @@ -860,6 +884,7 @@ impl<'hir> LoweringContext<'_, 'hir> { decl: &FnDecl, body: &Expr, fn_decl_span: Span, + fn_arg_span: Span, ) -> hir::ExprKind<'hir> { let (binder_clause, generic_params) = self.lower_closure_binder(binder); @@ -880,15 +905,17 @@ impl<'hir> LoweringContext<'_, 'hir> { let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params); // Lower outside new scope to preserve `is_in_loop_condition`. - let fn_decl = self.lower_fn_decl(decl, None, fn_decl_span, FnDeclKind::Closure, None); + let fn_decl = self.lower_fn_decl(decl, closure_id, fn_decl_span, FnDeclKind::Closure, None); let c = self.arena.alloc(hir::Closure { + def_id: self.local_def_id(closure_id), binder: binder_clause, capture_clause, bound_generic_params, fn_decl, body: body_id, fn_decl_span: self.lower_span(fn_decl_span), + fn_arg_span: Some(self.lower_span(fn_arg_span)), movability: generator_option, }); @@ -927,8 +954,8 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> (hir::ClosureBinder, &'c [GenericParam]) { let (binder, params) = match binder { ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]), - &ClosureBinder::For { span, ref generic_params } => { - let span = self.lower_span(span); + ClosureBinder::For { span, generic_params } => { + let span = self.lower_span(*span); (hir::ClosureBinder::For { span }, &**generic_params) } }; @@ -945,6 +972,7 @@ impl<'hir> LoweringContext<'_, 'hir> { decl: &FnDecl, body: &Expr, fn_decl_span: Span, + fn_arg_span: Span, ) -> hir::ExprKind<'hir> { if let &ClosureBinder::For { span, .. } = binder { self.tcx.sess.emit_err(NotSupportedForLifetimeBinderAsyncClosure { span }); @@ -962,19 +990,27 @@ impl<'hir> LoweringContext<'_, 'hir> { } // Transform `async |x: u8| -> X { ... }` into - // `|x: u8| future_from_generator(|| -> X { ... })`. + // `|x: u8| identity_future(|| -> X { ... })`. let body_id = this.lower_fn_body(&outer_decl, |this| { - let async_ret_ty = - if let FnRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None }; + let async_ret_ty = if let FnRetTy::Ty(ty) = &decl.output { + let itctx = ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock); + Some(hir::FnRetTy::Return(this.lower_ty(&ty, &itctx))) + } else { + None + }; + let async_body = this.make_async_expr( capture_clause, + // FIXME(nbdd0121): This should also use a proper HIR id so `#[track_caller]` + // can be applied on async closures as well. + None, inner_closure_id, async_ret_ty, body.span, hir::AsyncGeneratorKind::Closure, |this| this.with_new_scopes(|this| this.lower_expr_mut(body)), ); - this.expr(fn_decl_span, async_body, AttrVec::new()) + this.expr(fn_decl_span, async_body) }); body_id }); @@ -984,15 +1020,17 @@ impl<'hir> LoweringContext<'_, 'hir> { // have to conserve the state of being inside a loop condition for the // closure argument types. let fn_decl = - self.lower_fn_decl(&outer_decl, None, fn_decl_span, FnDeclKind::Closure, None); + self.lower_fn_decl(&outer_decl, closure_id, fn_decl_span, FnDeclKind::Closure, None); let c = self.arena.alloc(hir::Closure { + def_id: self.local_def_id(closure_id), binder: binder_clause, capture_clause, bound_generic_params, fn_decl, body, fn_decl_span: self.lower_span(fn_decl_span), + fn_arg_span: Some(self.lower_span(fn_arg_span)), movability: None, }); hir::ExprKind::Closure(c) @@ -1065,7 +1103,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn extract_tuple_struct_path<'a>( &mut self, expr: &'a Expr, - ) -> Option<(&'a Option<QSelf>, &'a Path)> { + ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> { if let ExprKind::Path(qself, path) = &expr.kind { // Does the path resolve to something disallowed in a tuple struct/variant pattern? if let Some(partial_res) = self.resolver.get_partial_res(expr.id) { @@ -1085,7 +1123,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn extract_unit_struct_path<'a>( &mut self, expr: &'a Expr, - ) -> Option<(&'a Option<QSelf>, &'a Path)> { + ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> { if let ExprKind::Path(qself, path) = &expr.kind { // Does the path resolve to something disallowed in a unit struct/variant pattern? if let Some(partial_res) = self.resolver.get_partial_res(expr.id) { @@ -1232,7 +1270,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let ident = self.expr_ident(lhs.span, ident, binding); let assign = hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span)); - let expr = self.expr(lhs.span, assign, AttrVec::new()); + let expr = self.expr(lhs.span, assign); assignments.push(self.stmt_expr(lhs.span, expr)); pat } @@ -1273,8 +1311,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let e2 = self.lower_expr_mut(e2); let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None); - let fn_expr = - self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new())); + let fn_expr = self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path))); hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2]) } @@ -1446,8 +1483,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `None => break` let none_arm = { - let break_expr = - self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, AttrVec::new())); + let break_expr = self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span)); let pat = self.pat_none(for_span); self.arm(pat, break_expr) }; @@ -1456,7 +1492,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let some_arm = { let some_pat = self.pat_some(pat_span, pat); let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false)); - let body_expr = self.arena.alloc(self.expr_block(body_block, AttrVec::new())); + let body_expr = self.arena.alloc(self.expr_block(body_block)); self.arm(some_pat, body_expr) }; @@ -1519,7 +1555,9 @@ impl<'hir> LoweringContext<'_, 'hir> { // surrounding scope of the `match` since the `match` is not a terminating scope. // // Also, add the attributes to the outer returned expr node. - self.expr_drop_temps_mut(for_span, match_expr, e.attrs.clone()) + let expr = self.expr_drop_temps_mut(for_span, match_expr); + self.lower_attrs(expr.hir_id, &e.attrs); + expr } /// Desugar `ExprKind::Try` from: `<expr>?` into: @@ -1561,28 +1599,21 @@ impl<'hir> LoweringContext<'_, 'hir> { }; // `#[allow(unreachable_code)]` - let attr = { - // `allow(unreachable_code)` - let allow = { - let allow_ident = Ident::new(sym::allow, self.lower_span(span)); - let uc_ident = Ident::new(sym::unreachable_code, self.lower_span(span)); - let uc_nested = attr::mk_nested_word_item(uc_ident); - attr::mk_list_item(allow_ident, vec![uc_nested]) - }; - attr::mk_attr_outer(&self.tcx.sess.parse_sess.attr_id_generator, allow) - }; + let attr = attr::mk_attr_nested_word( + &self.tcx.sess.parse_sess.attr_id_generator, + AttrStyle::Outer, + sym::allow, + sym::unreachable_code, + self.lower_span(span), + ); let attrs: AttrVec = thin_vec![attr]; // `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,` let continue_arm = { let val_ident = Ident::with_dummy_span(sym::val); let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident); - let val_expr = self.arena.alloc(self.expr_ident_with_attrs( - span, - val_ident, - val_pat_nid, - attrs.clone(), - )); + let val_expr = self.expr_ident(span, val_ident, val_pat_nid); + self.lower_attrs(val_expr.hir_id, &attrs); let continue_pat = self.pat_cf_continue(unstable_span, val_pat); self.arm(continue_pat, val_expr) }; @@ -1608,15 +1639,11 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::Destination { label: None, target_id }, Some(from_residual_expr), ), - attrs, )) } else { - self.arena.alloc(self.expr( - try_span, - hir::ExprKind::Ret(Some(from_residual_expr)), - attrs, - )) + self.arena.alloc(self.expr(try_span, hir::ExprKind::Ret(Some(from_residual_expr)))) }; + self.lower_attrs(ret_expr.hir_id, &attrs); let break_pat = self.pat_cf_break(try_span, residual_local); self.arm(break_pat, ret_expr) @@ -1681,18 +1708,16 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, span: Span, expr: &'hir hir::Expr<'hir>, - attrs: AttrVec, ) -> &'hir hir::Expr<'hir> { - self.arena.alloc(self.expr_drop_temps_mut(span, expr, attrs)) + self.arena.alloc(self.expr_drop_temps_mut(span, expr)) } pub(super) fn expr_drop_temps_mut( &mut self, span: Span, expr: &'hir hir::Expr<'hir>, - attrs: AttrVec, ) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::DropTemps(expr), attrs) + self.expr(span, hir::ExprKind::DropTemps(expr)) } fn expr_match( @@ -1702,29 +1727,25 @@ impl<'hir> LoweringContext<'_, 'hir> { arms: &'hir [hir::Arm<'hir>], source: hir::MatchSource, ) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::Match(arg, arms, source), AttrVec::new()) + self.expr(span, hir::ExprKind::Match(arg, arms, source)) } - fn expr_break(&mut self, span: Span, attrs: AttrVec) -> hir::Expr<'hir> { + fn expr_break(&mut self, span: Span) -> hir::Expr<'hir> { let expr_break = hir::ExprKind::Break(self.lower_loop_destination(None), None); - self.expr(span, expr_break, attrs) + self.expr(span, expr_break) } - fn expr_break_alloc(&mut self, span: Span, attrs: AttrVec) -> &'hir hir::Expr<'hir> { - let expr_break = self.expr_break(span, attrs); + fn expr_break_alloc(&mut self, span: Span) -> &'hir hir::Expr<'hir> { + let expr_break = self.expr_break(span); self.arena.alloc(expr_break) } fn expr_mut_addr_of(&mut self, span: Span, e: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> { - self.expr( - span, - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e), - AttrVec::new(), - ) + self.expr(span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e)) } fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> { - self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), AttrVec::new())) + self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]))) } fn expr_call_mut( @@ -1733,7 +1754,7 @@ impl<'hir> LoweringContext<'_, 'hir> { e: &'hir hir::Expr<'hir>, args: &'hir [hir::Expr<'hir>], ) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::Call(e, args), AttrVec::new()) + self.expr(span, hir::ExprKind::Call(e, args)) } fn expr_call( @@ -1752,8 +1773,7 @@ impl<'hir> LoweringContext<'_, 'hir> { args: &'hir [hir::Expr<'hir>], hir_id: Option<hir::HirId>, ) -> hir::Expr<'hir> { - let path = - self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id)); + let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, hir_id)); self.expr_call_mut(span, path, args) } @@ -1771,13 +1791,11 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, span: Span, lang_item: hir::LangItem, - attrs: AttrVec, hir_id: Option<hir::HirId>, ) -> hir::Expr<'hir> { self.expr( span, hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)), - attrs, ) } @@ -1792,19 +1810,9 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn expr_ident_mut( &mut self, - sp: Span, - ident: Ident, - binding: hir::HirId, - ) -> hir::Expr<'hir> { - self.expr_ident_with_attrs(sp, ident, binding, AttrVec::new()) - } - - fn expr_ident_with_attrs( - &mut self, span: Span, ident: Ident, binding: hir::HirId, - attrs: AttrVec, ) -> hir::Expr<'hir> { let hir_id = self.next_id(); let res = Res::Local(binding); @@ -1817,7 +1825,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }), )); - self.expr(span, expr_path, attrs) + self.expr(span, expr_path) } fn expr_unsafe(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> { @@ -1836,32 +1844,21 @@ impl<'hir> LoweringContext<'_, 'hir> { }), None, ), - AttrVec::new(), ) } fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> { let blk = self.block_all(span, &[], None); - let expr = self.expr_block(blk, AttrVec::new()); + let expr = self.expr_block(blk); self.arena.alloc(expr) } - pub(super) fn expr_block( - &mut self, - b: &'hir hir::Block<'hir>, - attrs: AttrVec, - ) -> hir::Expr<'hir> { - self.expr(b.span, hir::ExprKind::Block(b, None), attrs) + pub(super) fn expr_block(&mut self, b: &'hir hir::Block<'hir>) -> hir::Expr<'hir> { + self.expr(b.span, hir::ExprKind::Block(b, None)) } - pub(super) fn expr( - &mut self, - span: Span, - kind: hir::ExprKind<'hir>, - attrs: AttrVec, - ) -> hir::Expr<'hir> { + pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind<'hir>) -> hir::Expr<'hir> { let hir_id = self.next_id(); - self.lower_attrs(hir_id, &attrs); hir::Expr { hir_id, kind, span: self.lower_span(span) } } diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index f1851d7b4..fe0bd4381 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -77,7 +77,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { if hir_id.owner != self.owner { span_bug!( span, - "inconsistent DepNode at `{:?}` for `{:?}`: \ + "inconsistent HirId at `{:?}` for `{:?}`: \ current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})", self.source_map.span_to_diagnostic_string(span), node, @@ -145,7 +145,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_item(&mut self, i: &'hir Item<'hir>) { debug_assert_eq!(i.owner_id, self.owner); self.with_parent(i.hir_id(), |this| { - if let ItemKind::Struct(ref struct_def, _) = i.kind { + if let ItemKind::Struct(struct_def, _) = &i.kind { // If this is a tuple or unit-like struct, register the constructor. if let Some(ctor_hir_id) = struct_def.ctor_hir_id() { this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def)); @@ -303,12 +303,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) { - self.insert(lifetime.span, lifetime.hir_id, Node::Lifetime(lifetime)); + self.insert(lifetime.ident.span, lifetime.hir_id, Node::Lifetime(lifetime)); } fn visit_variant(&mut self, v: &'hir Variant<'hir>) { - self.insert(v.span, v.id, Node::Variant(v)); - self.with_parent(v.id, |this| { + self.insert(v.span, v.hir_id, Node::Variant(v)); + self.with_parent(v.hir_id, |this| { // Register the constructor of this variant. if let Some(ctor_hir_id) = v.data.ctor_hir_id() { this.insert(v.span, ctor_hir_id, Node::Ctor(&v.data)); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 76316a574..d73d6d391 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -6,7 +6,6 @@ use super::{FnDeclKind, LoweringContext, ParamMode}; use rustc_ast::ptr::P; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -20,8 +19,7 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{Span, Symbol}; use rustc_target::spec::abi; use smallvec::{smallvec, SmallVec}; - -use std::iter; +use thin_vec::ThinVec; pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, @@ -67,7 +65,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { // HirId handling. bodies: Vec::new(), attrs: SortedMap::default(), - children: FxHashMap::default(), + children: Vec::default(), current_hir_id_owner: hir::CRATE_OWNER_ID, item_local_id_counter: hir::ItemLocalId::new(0), node_id_to_local_id: Default::default(), @@ -86,7 +84,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { impl_trait_defs: Vec::new(), impl_trait_bounds: Vec::new(), allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()), - allow_gen_future: Some([sym::gen_future][..].into()), + allow_gen_future: Some([sym::gen_future, sym::closure_track_caller][..].into()), allow_into_future: Some([sym::into_future][..].into()), generics_def_id_map: Default::default(), }; @@ -143,7 +141,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { // This is used to track which lifetimes have already been defined, // and which need to be replicated when lowering an async fn. match parent_hir.node().expect_item().kind { - hir::ItemKind::Impl(hir::Impl { ref of_trait, .. }) => { + hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => { lctx.is_in_trait_impl = of_trait.is_some(); } _ => {} @@ -179,37 +177,23 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> { let mut node_ids = smallvec![hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }]; - if let ItemKind::Use(ref use_tree) = &i.kind { - self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids); + if let ItemKind::Use(use_tree) = &i.kind { + self.lower_item_id_use_tree(use_tree, &mut node_ids); } node_ids } - fn lower_item_id_use_tree( - &mut self, - tree: &UseTree, - base_id: NodeId, - vec: &mut SmallVec<[hir::ItemId; 1]>, - ) { - match tree.kind { - UseTreeKind::Nested(ref nested_vec) => { + fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) { + match &tree.kind { + UseTreeKind::Nested(nested_vec) => { for &(ref nested, id) in nested_vec { vec.push(hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(id) }, }); - self.lower_item_id_use_tree(nested, id, vec); - } - } - UseTreeKind::Glob => {} - UseTreeKind::Simple(_, id1, id2) => { - for (_, &id) in - iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2]) - { - vec.push(hir::ItemId { - owner_id: hir::OwnerId { def_id: self.local_def_id(id) }, - }); + self.lower_item_id_use_tree(nested, vec); } } + UseTreeKind::Simple(..) | UseTreeKind::Glob => {} } } @@ -239,26 +223,26 @@ impl<'hir> LoweringContext<'_, 'hir> { vis_span: Span, i: &ItemKind, ) -> hir::ItemKind<'hir> { - match *i { - ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name), - ItemKind::Use(ref use_tree) => { + match i { + ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(*orig_name), + ItemKind::Use(use_tree) => { // Start with an empty prefix. - let prefix = Path { segments: vec![], span: use_tree.span, tokens: None }; + let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None }; self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs) } - ItemKind::Static(ref t, m, ref e) => { + ItemKind::Static(t, m, e) => { let (ty, body_id) = self.lower_const_item(t, span, e.as_deref()); - hir::ItemKind::Static(ty, m, body_id) + hir::ItemKind::Static(ty, *m, body_id) } - ItemKind::Const(_, ref t, ref e) => { + ItemKind::Const(_, t, e) => { let (ty, body_id) = self.lower_const_item(t, span, e.as_deref()); hir::ItemKind::Const(ty, body_id) } ItemKind::Fn(box Fn { - sig: FnSig { ref decl, header, span: fn_sig_span }, - ref generics, - ref body, + sig: FnSig { decl, header, span: fn_sig_span }, + generics, + body, .. }) => { self.with_new_scopes(|this| { @@ -269,43 +253,41 @@ impl<'hir> LoweringContext<'_, 'hir> { // only cares about the input argument patterns in the function // declaration (decl), not the return types. let asyncness = header.asyncness; - let body_id = - this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref()); + let body_id = this.lower_maybe_async_body( + span, + hir_id, + &decl, + asyncness, + body.as_deref(), + ); let mut itctx = ImplTraitContext::Universal; let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| { let ret_id = asyncness.opt_return_id(); - this.lower_fn_decl(&decl, Some(id), fn_sig_span, FnDeclKind::Fn, ret_id) + this.lower_fn_decl(&decl, id, *fn_sig_span, FnDeclKind::Fn, ret_id) }); let sig = hir::FnSig { decl, - header: this.lower_fn_header(header), - span: this.lower_span(fn_sig_span), + header: this.lower_fn_header(*header), + span: this.lower_span(*fn_sig_span), }; hir::ItemKind::Fn(sig, generics, body_id) }) } - ItemKind::Mod(_, ref mod_kind) => match mod_kind { + ItemKind::Mod(_, mod_kind) => match mod_kind { ModKind::Loaded(items, _, spans) => { hir::ItemKind::Mod(self.lower_mod(items, spans)) } ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), }, - ItemKind::ForeignMod(ref fm) => hir::ItemKind::ForeignMod { + ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod { abi: fm.abi.map_or(abi::Abi::FALLBACK, |abi| self.lower_abi(abi)), items: self .arena .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))), }, - ItemKind::GlobalAsm(ref asm) => { - hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)) - } - ItemKind::TyAlias(box TyAlias { - ref generics, - where_clauses, - ty: Some(ref ty), - .. - }) => { + ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)), + ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: Some(ty), .. }) => { // We lower // // type Foo = impl Trait @@ -315,7 +297,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // type Foo = Foo1 // opaque type Foo1: Trait let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, where_clauses, true); + add_ty_alias_where_clause(&mut generics, *where_clauses, true); let (generics, ty) = self.lower_generics( &generics, id, @@ -324,9 +306,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::TyAlias(ty, generics) } - ItemKind::TyAlias(box TyAlias { - ref generics, ref where_clauses, ty: None, .. - }) => { + ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: None, .. }) => { let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, *where_clauses, true); let (generics, ty) = self.lower_generics( @@ -337,7 +317,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::TyAlias(ty, generics) } - ItemKind::Enum(ref enum_definition, ref generics) => { + ItemKind::Enum(enum_definition, generics) => { let (generics, variants) = self.lower_generics( generics, id, @@ -350,7 +330,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::Enum(hir::EnumDef { variants }, generics) } - ItemKind::Struct(ref struct_def, ref generics) => { + ItemKind::Struct(struct_def, generics) => { let (generics, struct_def) = self.lower_generics( generics, id, @@ -359,7 +339,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::Struct(struct_def, generics) } - ItemKind::Union(ref vdata, ref generics) => { + ItemKind::Union(vdata, generics) => { let (generics, vdata) = self.lower_generics( generics, id, @@ -373,10 +353,10 @@ impl<'hir> LoweringContext<'_, 'hir> { polarity, defaultness, constness, - generics: ref ast_generics, - of_trait: ref trait_ref, - self_ty: ref ty, - items: ref impl_items, + generics: ast_generics, + of_trait: trait_ref, + self_ty: ty, + items: impl_items, }) => { // Lower the "impl header" first. This ordering is important // for in-band lifetimes! Consider `'a` here: @@ -414,30 +394,24 @@ impl<'hir> LoweringContext<'_, 'hir> { // `defaultness.has_value()` is never called for an `impl`, always `true` in order // to not cause an assertion failure inside the `lower_defaultness` function. let has_val = true; - let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val); + let (defaultness, defaultness_span) = self.lower_defaultness(*defaultness, has_val); let polarity = match polarity { ImplPolarity::Positive => ImplPolarity::Positive, - ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)), + ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)), }; hir::ItemKind::Impl(self.arena.alloc(hir::Impl { - unsafety: self.lower_unsafety(unsafety), + unsafety: self.lower_unsafety(*unsafety), polarity, defaultness, defaultness_span, - constness: self.lower_constness(constness), + constness: self.lower_constness(*constness), generics, of_trait: trait_ref, self_ty: lowered_ty, items: new_impl_items, })) } - ItemKind::Trait(box Trait { - is_auto, - unsafety, - ref generics, - ref bounds, - ref items, - }) => { + ItemKind::Trait(box Trait { is_auto, unsafety, generics, bounds, items }) => { let (generics, (unsafety, items, bounds)) = self.lower_generics( generics, id, @@ -450,13 +424,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let items = this.arena.alloc_from_iter( items.iter().map(|item| this.lower_trait_item_ref(item)), ); - let unsafety = this.lower_unsafety(unsafety); + let unsafety = this.lower_unsafety(*unsafety); (unsafety, items, bounds) }, ); - hir::ItemKind::Trait(is_auto, unsafety, generics, bounds, items) + hir::ItemKind::Trait(*is_auto, unsafety, generics, bounds, items) } - ItemKind::TraitAlias(ref generics, ref bounds) => { + ItemKind::TraitAlias(generics, bounds) => { let (generics, bounds) = self.lower_generics( generics, id, @@ -470,10 +444,10 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::TraitAlias(generics, bounds) } - ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => { - let body = P(self.lower_mac_args(body)); + ItemKind::MacroDef(MacroDef { body, macro_rules }) => { + let body = P(self.lower_delim_args(body)); let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id)); - hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind) + hir::ItemKind::Macro(ast::MacroDef { body, macro_rules: *macro_rules }, macro_kind) } ItemKind::MacCall(..) => { panic!("`TyMac` should have been expanded by now") @@ -505,7 +479,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect(); match tree.kind { - UseTreeKind::Simple(rename, id1, id2) => { + UseTreeKind::Simple(rename) => { *ident = tree.ident(); // First, apply the prefix to the path. @@ -521,66 +495,16 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - let mut resolutions = self.expect_full_res_from_use(id).fuse(); - // We want to return *something* from this function, so hold onto the first item - // for later. - let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err)); - - // Here, we are looping over namespaces, if they exist for the definition - // being imported. We only handle type and value namespaces because we - // won't be dealing with macros in the rest of the compiler. - // Essentially a single `use` which imports two names is desugared into - // two imports. - for new_node_id in [id1, id2] { - let new_id = self.local_def_id(new_node_id); - let Some(res) = resolutions.next() else { - // Associate an HirId to both ids even if there is no resolution. - let _old = self.children.insert( - new_id, - hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id)), - ); - debug_assert!(_old.is_none()); - continue; - }; - let ident = *ident; - let mut path = path.clone(); - for seg in &mut path.segments { - // Give the cloned segment the same resolution information - // as the old one (this is needed for stability checking). - let new_id = self.next_node_id(); - self.resolver.clone_res(seg.id, new_id); - seg.id = new_id; - } - let span = path.span; - - self.with_hir_id_owner(new_node_id, |this| { - let res = this.lower_res(res); - let path = this.lower_path_extra(res, &path, ParamMode::Explicit); - let kind = hir::ItemKind::Use(path, hir::UseKind::Single); - if let Some(attrs) = attrs { - this.attrs.insert(hir::ItemLocalId::new(0), attrs); - } - - let item = hir::Item { - owner_id: hir::OwnerId { def_id: new_id }, - ident: this.lower_ident(ident), - kind, - vis_span, - span: this.lower_span(span), - }; - hir::OwnerNode::Item(this.arena.alloc(item)) - }); - } - - let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit); + let res = + self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect(); + let path = self.lower_use_path(res, &path, ParamMode::Explicit); hir::ItemKind::Use(path, hir::UseKind::Single) } UseTreeKind::Glob => { - let path = self.lower_path( - id, - &Path { segments, span: path.span, tokens: None }, - ParamMode::Explicit, - ); + let res = self.expect_full_res(id); + let res = smallvec![self.lower_res(res)]; + let path = Path { segments, span: path.span, tokens: None }; + let path = self.lower_use_path(res, &path, ParamMode::Explicit); hir::ItemKind::Use(path, hir::UseKind::Glob) } UseTreeKind::Nested(ref trees) => { @@ -650,9 +574,9 @@ impl<'hir> LoweringContext<'_, 'hir> { }); } - let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err); - let res = self.lower_res(res); - let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit); + let res = + self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect(); + let path = self.lower_use_path(res, &prefix, ParamMode::Explicit); hir::ItemKind::Use(path, hir::UseKind::ListStem) } } @@ -665,8 +589,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let item = hir::ForeignItem { owner_id, ident: self.lower_ident(i.ident), - kind: match i.kind { - ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => { + kind: match &i.kind { + ForeignItemKind::Fn(box Fn { sig, generics, .. }) => { let fdec = &sig.decl; let mut itctx = ImplTraitContext::Universal; let (generics, (fn_dec, fn_args)) = @@ -675,7 +599,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Disallow `impl Trait` in foreign items. this.lower_fn_decl( fdec, - None, + i.id, sig.span, FnDeclKind::ExternFn, None, @@ -686,10 +610,10 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ForeignItemKind::Fn(fn_dec, fn_args, generics) } - ForeignItemKind::Static(ref t, m, _) => { + ForeignItemKind::Static(t, m, _) => { let ty = self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); - hir::ForeignItemKind::Static(ty, m) + hir::ForeignItemKind::Static(ty, *m) } ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type, ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"), @@ -709,11 +633,12 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> { - let id = self.lower_node_id(v.id); - self.lower_attrs(id, &v.attrs); + let hir_id = self.lower_node_id(v.id); + self.lower_attrs(hir_id, &v.attrs); hir::Variant { - id, - data: self.lower_variant_data(id, &v.data), + hir_id, + def_id: self.local_def_id(v.id), + data: self.lower_variant_data(hir_id, &v.data), disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)), ident: self.lower_ident(v.ident), span: self.lower_span(v.span), @@ -725,32 +650,33 @@ impl<'hir> LoweringContext<'_, 'hir> { parent_id: hir::HirId, vdata: &VariantData, ) -> hir::VariantData<'hir> { - match *vdata { - VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct( + match vdata { + VariantData::Struct(fields, recovered) => hir::VariantData::Struct( self.arena .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))), - recovered, + *recovered, ), - VariantData::Tuple(ref fields, id) => { - let ctor_id = self.lower_node_id(id); + VariantData::Tuple(fields, id) => { + let ctor_id = self.lower_node_id(*id); self.alias_attrs(ctor_id, parent_id); hir::VariantData::Tuple( self.arena.alloc_from_iter( fields.iter().enumerate().map(|f| self.lower_field_def(f)), ), ctor_id, + self.local_def_id(*id), ) } VariantData::Unit(id) => { - let ctor_id = self.lower_node_id(id); + let ctor_id = self.lower_node_id(*id); self.alias_attrs(ctor_id, parent_id); - hir::VariantData::Unit(ctor_id) + hir::VariantData::Unit(ctor_id, self.local_def_id(*id)) } } } fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> { - let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind { + let ty = if let TyKind::Path(qself, path) = &f.ty.kind { let t = self.lower_path_ty( &f.ty, qself, @@ -767,6 +693,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::FieldDef { span: self.lower_span(f.span), hir_id, + def_id: self.local_def_id(f.id), ident: match f.ident { Some(ident) => self.lower_ident(ident), // FIXME(jseyfried): positional field hygiene. @@ -779,15 +706,16 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { let hir_id = self.lower_node_id(i.id); + self.lower_attrs(hir_id, &i.attrs); let trait_item_def_id = hir_id.expect_owner(); - let (generics, kind, has_default) = match i.kind { - AssocItemKind::Const(_, ref ty, ref default) => { + let (generics, kind, has_default) = match &i.kind { + AssocItemKind::Const(_, ty, default) => { let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some()) } - AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => { + AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => { let asyncness = sig.header.asyncness; let names = self.lower_fn_params_to_names(&sig.decl); let (generics, sig) = self.lower_method_sig( @@ -799,10 +727,10 @@ impl<'hir> LoweringContext<'_, 'hir> { ); (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false) } - AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => { + AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), .. }) => { let asyncness = sig.header.asyncness; let body_id = - self.lower_maybe_async_body(i.span, &sig.decl, asyncness, Some(&body)); + self.lower_maybe_async_body(i.span, hir_id, &sig.decl, asyncness, Some(&body)); let (generics, sig) = self.lower_method_sig( generics, sig, @@ -812,15 +740,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ); (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true) } - AssocItemKind::Type(box TyAlias { - ref generics, - where_clauses, - ref bounds, - ref ty, - .. - }) => { + AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => { let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, where_clauses, false); + add_ty_alias_where_clause(&mut generics, *where_clauses, false); let (generics, kind) = self.lower_generics( &generics, i.id, @@ -843,7 +765,6 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"), }; - self.lower_attrs(hir_id, &i.attrs); let item = hir::TraitItem { owner_id: trait_item_def_id, ident: self.lower_ident(i.ident), @@ -875,13 +796,15 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Construct `ExprKind::Err` for the given `span`. pub(crate) fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::Err, AttrVec::new()) + self.expr(span, hir::ExprKind::Err) } fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { // Since `default impl` is not yet implemented, this is always true in impls. let has_value = true; let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); + let hir_id = self.lower_node_id(i.id); + self.lower_attrs(hir_id, &i.attrs); let (generics, kind) = match &i.kind { AssocItemKind::Const(_, ty, expr) => { @@ -894,8 +817,13 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => { self.current_item = Some(i.span); let asyncness = sig.header.asyncness; - let body_id = - self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref()); + let body_id = self.lower_maybe_async_body( + i.span, + hir_id, + &sig.decl, + asyncness, + body.as_deref(), + ); let (generics, sig) = self.lower_method_sig( generics, sig, @@ -928,8 +856,6 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"), }; - let hir_id = self.lower_node_id(i.id); - self.lower_attrs(hir_id, &i.attrs); let item = hir::ImplItem { owner_id: hir_id.expect_owner(), ident: self.lower_ident(i.ident), @@ -1062,6 +988,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_maybe_async_body( &mut self, span: Span, + fn_id: hir::HirId, decl: &FnDecl, asyncness: Async, body: Option<&Block>, @@ -1212,6 +1139,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let async_expr = this.make_async_expr( CaptureBy::Value, + Some(fn_id), closure_id, None, body.span, @@ -1223,11 +1151,8 @@ impl<'hir> LoweringContext<'_, 'hir> { // Transform into `drop-temps { <user-body> }`, an expression: let desugared_span = this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None); - let user_body = this.expr_drop_temps( - desugared_span, - this.arena.alloc(user_body), - AttrVec::new(), - ); + let user_body = + this.expr_drop_temps(desugared_span, this.arena.alloc(user_body)); // As noted above, create the final block like // @@ -1244,14 +1169,11 @@ impl<'hir> LoweringContext<'_, 'hir> { Some(user_body), ); - this.expr_block(body, AttrVec::new()) + this.expr_block(body) }, ); - ( - this.arena.alloc_from_iter(parameters), - this.expr(body.span, async_expr, AttrVec::new()), - ) + (this.arena.alloc_from_iter(parameters), this.expr(body.span, async_expr)) }) } @@ -1266,7 +1188,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let header = self.lower_fn_header(sig.header); let mut itctx = ImplTraitContext::Universal; let (generics, decl) = self.lower_generics(generics, id, &mut itctx, |this| { - this.lower_fn_decl(&sig.decl, Some(id), sig.span, kind, is_async) + this.lower_fn_decl(&sig.decl, id, sig.span, kind, is_async) }); (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) }) } @@ -1352,7 +1274,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and // where clauses for `?Sized`. for pred in &generics.where_clause.predicates { - let WherePredicate::BoundPredicate(ref bound_pred) = *pred else { + let WherePredicate::BoundPredicate(bound_pred) = pred else { continue; }; let compute_is_param = || { @@ -1498,10 +1420,9 @@ impl<'hir> LoweringContext<'_, 'hir> { })) } GenericParamKind::Lifetime => { - let ident_span = self.lower_span(ident.span); let ident = self.lower_ident(ident); let lt_id = self.next_node_id(); - let lifetime = self.new_named_lifetime(id, lt_id, ident_span, ident); + let lifetime = self.new_named_lifetime(id, lt_id, ident); Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { lifetime, span, @@ -1513,11 +1434,11 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> { - match *pred { + match pred { WherePredicate::BoundPredicate(WhereBoundPredicate { - ref bound_generic_params, - ref bounded_ty, - ref bounds, + bound_generic_params, + bounded_ty, + bounds, span, }) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { hir_id: self.next_id(), @@ -1530,29 +1451,27 @@ impl<'hir> LoweringContext<'_, 'hir> { &ImplTraitContext::Disallowed(ImplTraitPosition::Bound), ) })), - span: self.lower_span(span), + span: self.lower_span(*span), origin: PredicateOrigin::WhereClause, }), - WherePredicate::RegionPredicate(WhereRegionPredicate { - ref lifetime, - ref bounds, - span, - }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { - span: self.lower_span(span), - lifetime: self.lower_lifetime(lifetime), - bounds: self.lower_param_bounds( - bounds, - &ImplTraitContext::Disallowed(ImplTraitPosition::Bound), - ), - in_where_clause: true, - }), - WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span }) => { + WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span }) => { + hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { + span: self.lower_span(*span), + lifetime: self.lower_lifetime(lifetime), + bounds: self.lower_param_bounds( + bounds, + &ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + ), + in_where_clause: true, + }) + } + WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => { hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { lhs_ty: self .lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), rhs_ty: self .lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), - span: self.lower_span(span), + span: self.lower_span(*span), }) } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ff29d15f1..4fa18907f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -34,7 +34,6 @@ #![feature(let_chains)] #![feature(never_type)] #![recursion_limit = "256"] -#![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] @@ -61,8 +60,8 @@ use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::definitions::DefPathData; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; use rustc_index::vec::{Idx, IndexVec}; +use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; -use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DesugaringKind; @@ -107,7 +106,7 @@ struct LoweringContext<'a, 'hir> { /// Attributes inside the owner being lowered. attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>, /// Collect items that were created by lowering the current owner. - children: FxHashMap<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>, + children: Vec<(LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>)>, generator_kind: Option<hir::GeneratorKind>, @@ -260,6 +259,8 @@ enum ImplTraitContext { }, /// Impl trait in type aliases. TypeAliasesOpaqueTy, + /// `impl Trait` is unstably accepted in this position. + FeatureGated(ImplTraitPosition, Symbol), /// `impl Trait` is not accepted in this position. Disallowed(ImplTraitPosition), } @@ -328,7 +329,14 @@ enum FnDeclKind { } impl FnDeclKind { - fn impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool { + fn param_impl_trait_allowed(&self) -> bool { + match self { + FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true, + _ => false, + } + } + + fn return_impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool { match self { FnDeclKind::Fn | FnDeclKind::Inherent => true, FnDeclKind::Impl if tcx.features().return_position_impl_trait_in_trait => true, @@ -481,6 +489,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { parent: LocalDefId, node_id: ast::NodeId, data: DefPathData, + span: Span, ) -> LocalDefId { debug_assert_ne!(node_id, ast::DUMMY_NODE_ID); assert!( @@ -491,7 +500,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.tcx.hir().def_key(self.local_def_id(node_id)), ); - let def_id = self.tcx.create_def(parent, data); + let def_id = self.tcx.at(span).create_def(parent, data).def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); self.resolver.node_id_to_def_id.insert(node_id, def_id); @@ -611,8 +620,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.impl_trait_defs = current_impl_trait_defs; self.impl_trait_bounds = current_impl_trait_bounds; - let _old = self.children.insert(def_id, hir::MaybeOwner::Owner(info)); - debug_assert!(_old.is_none()) + debug_assert!(self.children.iter().find(|(id, _)| id == &def_id).is_none()); + self.children.push((def_id, hir::MaybeOwner::Owner(info))); } /// Installs the remapping `remap` in scope while `f` is being executed. @@ -719,8 +728,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { assert_ne!(local_id, hir::ItemLocalId::new(0)); if let Some(def_id) = self.opt_local_def_id(ast_node_id) { - // Do not override a `MaybeOwner::Owner` that may already here. - self.children.entry(def_id).or_insert(hir::MaybeOwner::NonOwner(hir_id)); + self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); self.local_id_to_def_id.insert(local_id, def_id); } @@ -818,6 +826,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.current_hir_id_owner.def_id, param, DefPathData::LifetimeNs(kw::UnderscoreLifetime), + ident.span, ); debug!(?_def_id); @@ -830,8 +839,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ), }; let hir_id = self.lower_node_id(node_id); + let def_id = self.local_def_id(node_id); Some(hir::GenericParam { hir_id, + def_id, name, span: self.lower_span(ident.span), pure_wrt_drop: false, @@ -911,7 +922,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr { item: AttrItem { path: normal.item.path.clone(), - args: self.lower_mac_args(&normal.item.args), + args: self.lower_attr_args(&normal.item.args), tokens: None, }, tokens: None, @@ -931,51 +942,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_mac_args(&self, args: &MacArgs) -> MacArgs { - match *args { - MacArgs::Empty => MacArgs::Empty, - MacArgs::Delimited(dspan, delim, ref tokens) => { - // This is either a non-key-value attribute, or a `macro_rules!` body. - // We either not have any nonterminals present (in the case of an attribute), - // or have tokens available for all nonterminals in the case of a nested - // `macro_rules`: e.g: - // - // ```rust - // macro_rules! outer { - // ($e:expr) => { - // macro_rules! inner { - // () => { $e } - // } - // } - // } - // ``` - // - // In both cases, we don't want to synthesize any tokens - MacArgs::Delimited(dspan, delim, tokens.flattened()) - } + fn lower_attr_args(&self, args: &AttrArgs) -> AttrArgs { + match args { + AttrArgs::Empty => AttrArgs::Empty, + AttrArgs::Delimited(args) => AttrArgs::Delimited(self.lower_delim_args(args)), // This is an inert key-value attribute - it will never be visible to macros // after it gets lowered to HIR. Therefore, we can extract literals to handle // nonterminals in `#[doc]` (e.g. `#[doc = $e]`). - MacArgs::Eq(eq_span, MacArgsEq::Ast(ref expr)) => { + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { // In valid code the value always ends up as a single literal. Otherwise, a dummy // literal suffices because the error is handled elsewhere. - let lit = if let ExprKind::Lit(lit) = &expr.kind { - lit.clone() + let lit = if let ExprKind::Lit(token_lit) = expr.kind + && let Ok(lit) = MetaItemLit::from_token_lit(token_lit, expr.span) + { + lit } else { - Lit { + MetaItemLit { token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None), kind: LitKind::Err, span: DUMMY_SP, } }; - MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) + AttrArgs::Eq(*eq_span, AttrArgsEq::Hir(lit)) } - MacArgs::Eq(_, MacArgsEq::Hir(ref lit)) => { + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when lowering mac args eq: {:?}", lit) } } } + fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs { + DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() } + } + /// Given an associated type constraint like one of these: /// /// ```ignore (illustrative) @@ -994,12 +993,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::TypeBinding<'hir> { debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx); // lower generic arguments of identifier in constraint - let gen_args = if let Some(ref gen_args) = constraint.gen_args { + let gen_args = if let Some(gen_args) = &constraint.gen_args { let gen_args_ctor = match gen_args { - GenericArgs::AngleBracketed(ref data) => { + GenericArgs::AngleBracketed(data) => { self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0 } - GenericArgs::Parenthesized(ref data) => { + GenericArgs::Parenthesized(data) => { self.emit_bad_parenthesized_trait_in_assoc_ty(data); let aba = self.ast_arena.aba.alloc(data.as_angle_bracketed_args()); self.lower_angle_bracketed_parameter_data(aba, ParamMode::Explicit, itctx).0 @@ -1011,15 +1010,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; let itctx_tait = &ImplTraitContext::TypeAliasesOpaqueTy; - let kind = match constraint.kind { - AssocConstraintKind::Equality { ref term } => { + let kind = match &constraint.kind { + AssocConstraintKind::Equality { term } => { let term = match term { - Term::Ty(ref ty) => self.lower_ty(ty, itctx).into(), - Term::Const(ref c) => self.lower_anon_const(c).into(), + Term::Ty(ty) => self.lower_ty(ty, itctx).into(), + Term::Const(c) => self.lower_anon_const(c).into(), }; hir::TypeBindingKind::Equality { term } } - AssocConstraintKind::Bound { ref bounds } => { + AssocConstraintKind::Bound { bounds } => { // Piggy-back on the `impl Trait` context to figure out the correct behavior. let (desugar_to_impl_trait, itctx) = match itctx { // We are in the return position: @@ -1129,7 +1128,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { match arg { ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)), ast::GenericArg::Type(ty) => { - match ty.kind { + match &ty.kind { TyKind::Infer if self.tcx.features().generic_arg_infer => { return GenericArg::Infer(hir::InferArg { hir_id: self.lower_node_id(ty.id), @@ -1140,7 +1139,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // parsing. We try to resolve that ambiguity by attempting resolution in both the // type and value namespaces. If we resolved the path in the value namespace, we // transform it into a generic const argument. - TyKind::Path(ref qself, ref path) => { + TyKind::Path(qself, path) => { if let Some(res) = self .resolver .get_partial_res(ty.id) @@ -1156,15 +1155,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let parent_def_id = self.current_hir_id_owner; let node_id = self.next_node_id(); + let span = self.lower_span(ty.span); // Add a definition for the in-band const def. - self.create_def( + let def_id = self.create_def( parent_def_id.def_id, node_id, DefPathData::AnonConst, + span, ); - let span = self.lower_span(ty.span); let path_expr = Expr { id: ty.id, kind: ExprKind::Path(qself.clone(), path.clone()), @@ -1174,6 +1174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; let ct = self.with_new_scopes(|this| hir::AnonConst { + def_id, hir_id: this.lower_node_id(node_id), body: this.lower_const_body(path_expr.span, Some(&path_expr)), }); @@ -1200,7 +1201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_path_ty( &mut self, t: &Ty, - qself: &Option<QSelf>, + qself: &Option<ptr::P<QSelf>>, path: &Path, param_mode: ParamMode, itctx: &ImplTraitContext, @@ -1246,12 +1247,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'hir> { - let kind = match t.kind { + let kind = match &t.kind { TyKind::Infer => hir::TyKind::Infer, TyKind::Err => hir::TyKind::Err, - TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), - TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), - TyKind::Rptr(ref region, ref mt) => { + TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), + TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), + TyKind::Rptr(region, mt) => { let region = region.unwrap_or_else(|| { let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) = self.resolver.get_lifetime_res(t.id) @@ -1261,30 +1262,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { self.next_node_id() }; - let span = self.tcx.sess.source_map().start_point(t.span); + let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi(); Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id } }); let lifetime = self.lower_lifetime(®ion); hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx)) } - TyKind::BareFn(ref f) => { + TyKind::BareFn(f) => { let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params); hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy { generic_params, unsafety: self.lower_unsafety(f.unsafety), abi: self.lower_extern(f.ext), - decl: self.lower_fn_decl(&f.decl, None, t.span, FnDeclKind::Pointer, None), + decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None), param_names: self.lower_fn_params_to_names(&f.decl), })) } TyKind::Never => hir::TyKind::Never, - TyKind::Tup(ref tys) => hir::TyKind::Tup( + TyKind::Tup(tys) => hir::TyKind::Tup( self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))), ), - TyKind::Paren(ref ty) => { + TyKind::Paren(ty) => { return self.lower_ty_direct(ty, itctx); } - TyKind::Path(ref qself, ref path) => { + TyKind::Path(qself, path) => { return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx); } TyKind::ImplicitSelf => { @@ -1304,48 +1305,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }), )) } - TyKind::Array(ref ty, ref length) => { + TyKind::Array(ty, length) => { hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length)) } - TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)), - TyKind::TraitObject(ref bounds, kind) => { + TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)), + TyKind::TraitObject(bounds, kind) => { let mut lifetime_bound = None; let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| { let bounds = - this.arena.alloc_from_iter(bounds.iter().filter_map( - |bound| match *bound { - GenericBound::Trait( - ref ty, - TraitBoundModifier::None | TraitBoundModifier::MaybeConst, - ) => Some(this.lower_poly_trait_ref(ty, itctx)), - // `~const ?Bound` will cause an error during AST validation - // anyways, so treat it like `?Bound` as compilation proceeds. - GenericBound::Trait( - _, - TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe, - ) => None, - GenericBound::Outlives(ref lifetime) => { - if lifetime_bound.is_none() { - lifetime_bound = Some(this.lower_lifetime(lifetime)); - } - None + this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound { + GenericBound::Trait( + ty, + TraitBoundModifier::None | TraitBoundModifier::MaybeConst, + ) => Some(this.lower_poly_trait_ref(ty, itctx)), + // `~const ?Bound` will cause an error during AST validation + // anyways, so treat it like `?Bound` as compilation proceeds. + GenericBound::Trait( + _, + TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe, + ) => None, + GenericBound::Outlives(lifetime) => { + if lifetime_bound.is_none() { + lifetime_bound = Some(this.lower_lifetime(lifetime)); } - }, - )); + None + } + })); let lifetime_bound = lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span)); (bounds, lifetime_bound) }); - hir::TyKind::TraitObject(bounds, lifetime_bound, kind) + hir::TyKind::TraitObject(bounds, lifetime_bound, *kind) } - TyKind::ImplTrait(def_node_id, ref bounds) => { + TyKind::ImplTrait(def_node_id, bounds) => { let span = t.span; match itctx { ImplTraitContext::ReturnPositionOpaqueTy { origin, in_trait } => self .lower_opaque_impl_trait( span, *origin, - def_node_id, + *def_node_id, bounds, *in_trait, itctx, @@ -1353,38 +1352,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait( span, hir::OpaqueTyOrigin::TyAlias, - def_node_id, + *def_node_id, bounds, false, itctx, ), ImplTraitContext::Universal => { + let span = t.span; self.create_def( self.current_hir_id_owner.def_id, - def_node_id, + *def_node_id, DefPathData::ImplTrait, + span, ); - let span = t.span; let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span); let (param, bounds, path) = - self.lower_generic_and_bounds(def_node_id, span, ident, bounds); + self.lower_generic_and_bounds(*def_node_id, span, ident, bounds); self.impl_trait_defs.push(param); if let Some(bounds) = bounds { self.impl_trait_bounds.push(bounds); } path } - ImplTraitContext::Disallowed( - position @ (ImplTraitPosition::TraitReturn | ImplTraitPosition::ImplReturn), - ) => { + ImplTraitContext::FeatureGated(position, feature) => { self.tcx .sess .create_feature_err( MisplacedImplTrait { span: t.span, - position: DiagnosticArgFromDisplay(&position), + position: DiagnosticArgFromDisplay(position), }, - sym::return_position_impl_trait_in_trait, + *feature, ) .emit(); hir::TyKind::Err @@ -1392,7 +1390,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::Disallowed(position) => { self.tcx.sess.emit_err(MisplacedImplTrait { span: t.span, - position: DiagnosticArgFromDisplay(&position), + position: DiagnosticArgFromDisplay(position), }); hir::TyKind::Err } @@ -1457,17 +1455,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); - let opaque_ty_def_id = match origin { - hir::OpaqueTyOrigin::TyAlias => self.create_def( - self.current_hir_id_owner.def_id, - opaque_ty_node_id, - DefPathData::ImplTrait, - ), - hir::OpaqueTyOrigin::FnReturn(fn_def_id) => { - self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait) - } - hir::OpaqueTyOrigin::AsyncFn(..) => bug!("unreachable"), - }; + let opaque_ty_def_id = self.create_def( + self.current_hir_id_owner.def_id, + opaque_ty_node_id, + DefPathData::ImplTrait, + opaque_ty_span, + ); debug!(?opaque_ty_def_id); // Contains the new lifetime definitions created for the TAIT (if any). @@ -1521,6 +1514,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::GenericParam { hir_id, + def_id: lctx.local_def_id(new_node_id), name, span: lifetime.ident.span, pure_wrt_drop: false, @@ -1559,15 +1553,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let lifetimes = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| { let id = self.next_node_id(); - let span = lifetime.ident.span; - - let ident = if lifetime.ident.name == kw::UnderscoreLifetime { - Ident::with_dummy_span(kw::UnderscoreLifetime) - } else { - lifetime.ident - }; - - let l = self.new_named_lifetime(lifetime.id, id, span, ident); + let l = self.new_named_lifetime(lifetime.id, id, lifetime.ident); hir::GenericArg::Lifetime(l) })); debug!(?lifetimes); @@ -1627,6 +1613,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { parent_def_id, node_id, DefPathData::LifetimeNs(lifetime.ident.name), + lifetime.ident.span, ); remapping.insert(old_def_id, new_def_id); @@ -1643,6 +1630,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { parent_def_id, node_id, DefPathData::LifetimeNs(kw::UnderscoreLifetime), + lifetime.ident.span, ); remapping.insert(old_def_id, new_def_id); @@ -1692,7 +1680,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_fn_decl( &mut self, decl: &FnDecl, - fn_node_id: Option<NodeId>, + fn_node_id: NodeId, fn_span: Span, kind: FnDeclKind, make_ret_async: Option<(NodeId, Span)>, @@ -1707,23 +1695,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { inputs = &inputs[..inputs.len() - 1]; } let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| { - if fn_node_id.is_some() { - self.lower_ty_direct(¶m.ty, &ImplTraitContext::Universal) + let itctx = if kind.param_impl_trait_allowed() { + ImplTraitContext::Universal } else { - self.lower_ty_direct( - ¶m.ty, - &ImplTraitContext::Disallowed(match kind { - FnDeclKind::Fn | FnDeclKind::Inherent => { - unreachable!("fn should allow in-band lifetimes") - } - FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam, - FnDeclKind::Closure => ImplTraitPosition::ClosureParam, - FnDeclKind::Pointer => ImplTraitPosition::PointerParam, - FnDeclKind::Trait => ImplTraitPosition::TraitParam, - FnDeclKind::Impl => ImplTraitPosition::ImplParam, - }), - ) - } + ImplTraitContext::Disallowed(match kind { + FnDeclKind::Fn | FnDeclKind::Inherent => { + unreachable!("fn should allow APIT") + } + FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam, + FnDeclKind::Closure => ImplTraitPosition::ClosureParam, + FnDeclKind::Pointer => ImplTraitPosition::PointerParam, + FnDeclKind::Trait => ImplTraitPosition::TraitParam, + FnDeclKind::Impl => ImplTraitPosition::ImplParam, + }) + }; + self.lower_ty_direct(¶m.ty, &itctx) })); let output = if let Some((ret_id, span)) = make_ret_async { @@ -1746,22 +1732,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_async_fn_ret_ty( &decl.output, - fn_node_id.expect("`make_ret_async` but no `fn_def_id`"), + fn_node_id, ret_id, matches!(kind, FnDeclKind::Trait), ) } else { - match decl.output { - FnRetTy::Ty(ref ty) => { - let mut context = match fn_node_id { - Some(fn_node_id) if kind.impl_trait_allowed(self.tcx) => { - let fn_def_id = self.local_def_id(fn_node_id); - ImplTraitContext::ReturnPositionOpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), - in_trait: matches!(kind, FnDeclKind::Trait), - } + match &decl.output { + FnRetTy::Ty(ty) => { + let context = if kind.return_impl_trait_allowed(self.tcx) { + let fn_def_id = self.local_def_id(fn_node_id); + ImplTraitContext::ReturnPositionOpaqueTy { + origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), + in_trait: matches!(kind, FnDeclKind::Trait), } - _ => ImplTraitContext::Disallowed(match kind { + } else { + let position = match kind { FnDeclKind::Fn | FnDeclKind::Inherent => { unreachable!("fn should allow in-band lifetimes") } @@ -1770,11 +1755,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { FnDeclKind::Pointer => ImplTraitPosition::PointerReturn, FnDeclKind::Trait => ImplTraitPosition::TraitReturn, FnDeclKind::Impl => ImplTraitPosition::ImplReturn, - }), + }; + match kind { + FnDeclKind::Trait | FnDeclKind::Impl => ImplTraitContext::FeatureGated( + position, + sym::return_position_impl_trait_in_trait, + ), + _ => ImplTraitContext::Disallowed(position), + } }; - hir::FnRetTy::Return(self.lower_ty(ty, &mut context)) + hir::FnRetTy::Return(self.lower_ty(ty, &context)) } - FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(span)), + FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)), } }; @@ -1782,26 +1774,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { inputs, output, c_variadic, + lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id), implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| { let is_mutable_pat = matches!( arg.pat.kind, PatKind::Ident(hir::BindingAnnotation(_, Mutability::Mut), ..) ); - match arg.ty.kind { + match &arg.ty.kind { TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut, TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm, // Given we are only considering `ImplicitSelf` types, we needn't consider // the case where we have a mutable pattern to a reference as that would // no longer be an `ImplicitSelf`. - TyKind::Rptr(_, ref mt) - if mt.ty.kind.is_implicit_self() && mt.mutbl == ast::Mutability::Mut => - { - hir::ImplicitSelfKind::MutRef - } - TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() => { - hir::ImplicitSelfKind::ImmRef - } + TyKind::Rptr(_, mt) if mt.ty.kind.is_implicit_self() => match mt.mutbl { + hir::Mutability::Not => hir::ImplicitSelfKind::ImmRef, + hir::Mutability::Mut => hir::ImplicitSelfKind::MutRef, + }, _ => hir::ImplicitSelfKind::None, } }), @@ -1828,9 +1817,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None); - let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id); let fn_def_id = self.local_def_id(fn_node_id); + let opaque_ty_def_id = + self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait, opaque_ty_span); + // When we create the opaque type for this async fn, it is going to have // to capture all the lifetimes involved in the signature (including in the // return type). This is done by introducing lifetime parameters for: @@ -1889,6 +1880,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { opaque_ty_def_id, inner_node_id, DefPathData::LifetimeNs(ident.name), + ident.span, ); new_remapping.insert(outer_def_id, inner_def_id); @@ -1953,7 +1945,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { output, span, if in_trait && !this.tcx.features().return_position_impl_trait_in_trait { - ImplTraitContext::Disallowed(ImplTraitPosition::TraitReturn) + ImplTraitContext::FeatureGated( + ImplTraitPosition::TraitReturn, + sym::return_position_impl_trait_in_trait, + ) } else { ImplTraitContext::ReturnPositionOpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), @@ -1978,6 +1973,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::GenericParam { hir_id, + def_id: this.local_def_id(new_node_id), name, span: lifetime.ident.span, pure_wrt_drop: false, @@ -2024,18 +2020,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let generic_args = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map( |(_, lifetime, res)| { let id = self.next_node_id(); - let span = lifetime.ident.span; - - let ident = if lifetime.ident.name == kw::UnderscoreLifetime { - Ident::with_dummy_span(kw::UnderscoreLifetime) - } else { - lifetime.ident - }; - let res = res.unwrap_or( self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error), ); - hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, span, ident, res)) + hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, lifetime.ident, res)) }, )); @@ -2105,43 +2093,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime { - let span = self.lower_span(l.ident.span); let ident = self.lower_ident(l.ident); - self.new_named_lifetime(l.id, l.id, span, ident) + self.new_named_lifetime(l.id, l.id, ident) } #[instrument(level = "debug", skip(self))] fn new_named_lifetime_with_res( &mut self, id: NodeId, - span: Span, ident: Ident, res: LifetimeRes, ) -> &'hir hir::Lifetime { - let name = match res { + let res = match res { LifetimeRes::Param { param, .. } => { - let p_name = ParamName::Plain(ident); let param = self.get_remapped_def_id(param); - - hir::LifetimeName::Param(param, p_name) + hir::LifetimeName::Param(param) } LifetimeRes::Fresh { param, .. } => { - debug_assert_eq!(ident.name, kw::UnderscoreLifetime); let param = self.local_def_id(param); - - hir::LifetimeName::Param(param, ParamName::Fresh) + hir::LifetimeName::Param(param) } LifetimeRes::Infer => hir::LifetimeName::Infer, LifetimeRes::Static => hir::LifetimeName::Static, LifetimeRes::Error => hir::LifetimeName::Error, - res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span), + res => panic!( + "Unexpected lifetime resolution {:?} for {:?} at {:?}", + res, ident, ident.span + ), }; - debug!(?name); + debug!(?res); self.arena.alloc(hir::Lifetime { hir_id: self.lower_node_id(id), - span: self.lower_span(span), - name, + ident: self.lower_ident(ident), + res, }) } @@ -2150,11 +2135,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, id: NodeId, new_id: NodeId, - span: Span, ident: Ident, ) -> &'hir hir::Lifetime { let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error); - self.new_named_lifetime_with_res(new_id, span, ident, res) + self.new_named_lifetime_with_res(new_id, ident, res) } fn lower_generic_params_mut<'s>( @@ -2176,6 +2160,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_attrs(hir_id, ¶m.attrs); hir::GenericParam { hir_id, + def_id: self.local_def_id(param.id), name, span: self.lower_span(param.span()), pure_wrt_drop: self.tcx.sess.contains_name(¶m.attrs, sym::may_dangle), @@ -2188,7 +2173,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, param: &GenericParam, ) -> (hir::ParamName, hir::GenericParamKind<'hir>) { - match param.kind { + match ¶m.kind { GenericParamKind::Lifetime => { // AST resolution emitted an error on those parameters, so we lower them using // `ParamName::Error`. @@ -2204,7 +2189,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (param_name, kind) } - GenericParamKind::Type { ref default, .. } => { + GenericParamKind::Type { default, .. } => { let kind = hir::GenericParamKind::Type { default: default.as_ref().map(|x| { self.lower_ty(x, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)) @@ -2214,7 +2199,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(self.lower_ident(param.ident)), kind) } - GenericParamKind::Const { ref ty, kw_span: _, ref default } => { + GenericParamKind::Const { ty, kw_span: _, default } => { let ty = self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); let default = default.as_ref().map(|def| self.lower_anon_const(def)); ( @@ -2280,6 +2265,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Set the name to `impl Bound1 + Bound2`. let param = hir::GenericParam { hir_id: self.lower_node_id(node_id), + def_id, name: ParamName::Plain(self.lower_ident(ident)), pure_wrt_drop: false, span: self.lower_span(span), @@ -2315,7 +2301,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// has no attributes and is not targeted by a `break`. fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> { let block = self.lower_block(b, false); - self.expr_block(block, AttrVec::new()) + self.expr_block(block) } fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen { @@ -2340,6 +2326,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst { self.with_new_scopes(|this| hir::AnonConst { + def_id: this.local_def_id(c.id), hir_id: this.lower_node_id(c.id), body: this.lower_const_body(c.value.span, Some(&c.value)), }) @@ -2563,8 +2550,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime { let r = hir::Lifetime { hir_id: self.next_id(), - span: self.lower_span(span), - name: hir::LifetimeName::ImplicitObjectLifetimeDefault, + ident: Ident::new(kw::Empty, self.lower_span(span)), + res: hir::LifetimeName::ImplicitObjectLifetimeDefault, }; debug!("elided_dyn_bound: r={:?}", r); self.arena.alloc(r) diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 1af1633b5..16b012630 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -22,16 +22,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ensure_sufficient_stack(|| { // loop here to avoid recursion let node = loop { - match pattern.kind { + match &pattern.kind { PatKind::Wild => break hir::PatKind::Wild, - PatKind::Ident(binding_mode, ident, ref sub) => { - let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s)); - break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub); + PatKind::Ident(binding_mode, ident, sub) => { + let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(s)); + break self.lower_pat_ident(pattern, *binding_mode, *ident, lower_sub); } - PatKind::Lit(ref e) => { + PatKind::Lit(e) => { break hir::PatKind::Lit(self.lower_expr_within_pat(e, false)); } - PatKind::TupleStruct(ref qself, ref path, ref pats) => { + PatKind::TupleStruct(qself, path, pats) => { let qpath = self.lower_qpath( pattern.id, qself, @@ -42,12 +42,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct"); break hir::PatKind::TupleStruct(qpath, pats, ddpos); } - PatKind::Or(ref pats) => { + PatKind::Or(pats) => { break hir::PatKind::Or( self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat_mut(x))), ); } - PatKind::Path(ref qself, ref path) => { + PatKind::Path(qself, path) => { let qpath = self.lower_qpath( pattern.id, qself, @@ -57,7 +57,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); break hir::PatKind::Path(qpath); } - PatKind::Struct(ref qself, ref path, ref fields, etc) => { + PatKind::Struct(qself, path, fields, etc) => { let qpath = self.lower_qpath( pattern.id, qself, @@ -78,32 +78,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: self.lower_span(f.span), } })); - break hir::PatKind::Struct(qpath, fs, etc); + break hir::PatKind::Struct(qpath, fs, *etc); } - PatKind::Tuple(ref pats) => { + PatKind::Tuple(pats) => { let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple"); break hir::PatKind::Tuple(pats, ddpos); } - PatKind::Box(ref inner) => { + PatKind::Box(inner) => { break hir::PatKind::Box(self.lower_pat(inner)); } - PatKind::Ref(ref inner, mutbl) => { - break hir::PatKind::Ref(self.lower_pat(inner), mutbl); + PatKind::Ref(inner, mutbl) => { + break hir::PatKind::Ref(self.lower_pat(inner), *mutbl); } - PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => { + PatKind::Range(e1, e2, Spanned { node: end, .. }) => { break hir::PatKind::Range( e1.as_deref().map(|e| self.lower_expr_within_pat(e, true)), e2.as_deref().map(|e| self.lower_expr_within_pat(e, true)), self.lower_range_end(end, e2.is_some()), ); } - PatKind::Slice(ref pats) => break self.lower_pat_slice(pats), + PatKind::Slice(pats) => break self.lower_pat_slice(pats), PatKind::Rest => { // If we reach here the `..` pattern is not semantically allowed. break self.ban_illegal_rest_pat(pattern.span); } // return inner to be processed in next loop - PatKind::Paren(ref inner) => pattern = inner, + PatKind::Paren(inner) => pattern = inner, PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span), } }; @@ -126,7 +126,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Note that unlike for slice patterns, // where `xs @ ..` is a legal sub-slice pattern, // it is not a legal sub-tuple pattern. - match pat.kind { + match &pat.kind { // Found a sub-tuple rest pattern PatKind::Rest => { rest = Some((idx, pat.span)); @@ -134,12 +134,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } // Found a sub-tuple pattern `$binding_mode $ident @ ..`. // This is not allowed as a sub-tuple pattern - PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => { + PatKind::Ident(_, ident, Some(sub)) if sub.is_rest() => { let sp = pat.span; self.tcx.sess.emit_err(SubTupleBinding { span: sp, ident_name: ident.name, - ident, + ident: *ident, ctx, }); } @@ -176,7 +176,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let mut prev_rest_span = None; // Lowers `$bm $ident @ ..` to `$bm $ident @ _`. - let lower_rest_sub = |this: &mut Self, pat, ann, ident, sub| { + let lower_rest_sub = |this: &mut Self, pat, &ann, &ident, sub| { let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub)); let node = this.lower_pat_ident(pat, ann, ident, lower_sub); this.pat_with_node_id_of(pat, node) @@ -185,7 +185,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let mut iter = pats.iter(); // Lower all the patterns until the first occurrence of a sub-slice pattern. for pat in iter.by_ref() { - match pat.kind { + match &pat.kind { // Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here. PatKind::Rest => { prev_rest_span = Some(pat.span); @@ -194,7 +194,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } // Found a sub-slice pattern `$binding_mode $ident @ ..`. // Record, lower it to `$binding_mode $ident @ _`, and stop here. - PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => { + PatKind::Ident(ann, ident, Some(sub)) if sub.is_rest() => { prev_rest_span = Some(sub.span); slice = Some(self.arena.alloc(lower_rest_sub(self, pat, ann, ident, sub))); break; @@ -207,9 +207,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Lower all the patterns after the first sub-slice pattern. for pat in iter { // There was a previous subslice pattern; make sure we don't allow more. - let rest_span = match pat.kind { + let rest_span = match &pat.kind { PatKind::Rest => Some(pat.span), - PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => { + PatKind::Ident(ann, ident, Some(sub)) if sub.is_rest() => { // #69103: Lower into `binding @ _` as above to avoid ICEs. after.push(lower_rest_sub(self, pat, ann, ident, sub)); Some(sub.span) @@ -322,10 +322,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // m!(S); // ``` fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> { - match expr.kind { - ExprKind::Lit(..) | ExprKind::ConstBlock(..) | ExprKind::Err => {} + match &expr.kind { + ExprKind::Lit(..) + | ExprKind::ConstBlock(..) + | ExprKind::IncludedBytes(..) + | ExprKind::Err => {} ExprKind::Path(..) if allow_paths => {} - ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} + ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} _ => { self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span }); return self.arena.alloc(self.expr_err(expr.span)); diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 888776ccc..592fc5aa6 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -9,17 +9,17 @@ use rustc_ast::{self as ast, *}; use rustc_hir as hir; use rustc_hir::def::{DefKind, PartialRes, Res}; use rustc_hir::GenericArg; -use rustc_span::symbol::{kw, Ident}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span, DUMMY_SP}; -use smallvec::smallvec; +use smallvec::{smallvec, SmallVec}; impl<'a, 'hir> LoweringContext<'a, 'hir> { #[instrument(level = "trace", skip(self))] pub(crate) fn lower_qpath( &mut self, id: NodeId, - qself: &Option<QSelf>, + qself: &Option<ptr::P<QSelf>>, p: &Path, param_mode: ParamMode, itctx: &ImplTraitContext, @@ -144,13 +144,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); } - pub(crate) fn lower_path_extra( + pub(crate) fn lower_use_path( &mut self, - res: Res, + res: SmallVec<[Res; 3]>, p: &Path, param_mode: ParamMode, - ) -> &'hir hir::Path<'hir> { - self.arena.alloc(hir::Path { + ) -> &'hir hir::UsePath<'hir> { + self.arena.alloc(hir::UsePath { res, segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| { self.lower_path_segment( @@ -165,17 +165,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) } - pub(crate) fn lower_path( - &mut self, - id: NodeId, - p: &Path, - param_mode: ParamMode, - ) -> &'hir hir::Path<'hir> { - let res = self.expect_full_res(id); - let res = self.lower_res(res); - self.lower_path_extra(res, p, param_mode) - } - pub(crate) fn lower_path_segment( &mut self, path_span: Span, @@ -185,13 +174,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { itctx: &ImplTraitContext, ) -> hir::PathSegment<'hir> { debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,); - let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args { - match **generic_args { - GenericArgs::AngleBracketed(ref data) => { + let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() { + match generic_args { + GenericArgs::AngleBracketed(data) => { self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) } - GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { - ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), + GenericArgs::Parenthesized(data) => match parenthesized_generic_args { + ParenthesizedGenericArgs::Ok => { + self.lower_parenthesized_parameter_data(data, itctx) + } ParenthesizedGenericArgs::Err => { // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>` let sub = if !data.inputs.is_empty() { @@ -307,7 +298,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let id = NodeId::from_u32(i); let l = self.lower_lifetime(&Lifetime { id, - ident: Ident::new(kw::UnderscoreLifetime, elided_lifetime_span), + ident: Ident::new(kw::Empty, elided_lifetime_span), }); GenericArg::Lifetime(l) }), @@ -344,6 +335,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_parenthesized_parameter_data( &mut self, data: &ParenthesizedArgs, + itctx: &ImplTraitContext, ) -> (GenericArgsCtor<'hir>, bool) { // Switch to `PassThrough` mode for anonymous lifetimes; this // means that we permit things like `&Ref<T>`, where `Ref` has @@ -355,6 +347,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_ty_direct(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam)) })); let output_ty = match output { + // Only allow `impl Trait` in return position. i.e.: + // ```rust + // fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug + // // disallowed --^^^^^^^^^^ allowed --^^^^^^^^^^ + // ``` + FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. }) => { + if self.tcx.features().impl_trait_in_fn_trait_return { + self.lower_ty(&ty, itctx) + } else { + self.lower_ty( + &ty, + &ImplTraitContext::FeatureGated( + ImplTraitPosition::FnTraitReturn, + sym::impl_trait_in_fn_trait_return, + ), + ) + } + } FnRetTy::Ty(ty) => { self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)) } |