Auto merge of #104776 - Dylan-DPC:rollup-rf4c2u0, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #104269 (Fix hang in where-clause suggestion with `predicate_can_apply`) - #104286 (copy doc output files by format) - #104509 (Use obligation ctxt instead of dyn TraitEngine) - #104721 (Remove more `ref` patterns from the compiler) - #104744 (rustdoc: give struct fields CSS `display: block`) - #104751 (Fix an ICE parsing a malformed attribute.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d121aa3b55
38 changed files with 516 additions and 433 deletions
|
@ -52,19 +52,15 @@ fn test_arena_alloc_nested() {
|
|||
|
||||
impl<'a> Wrap<'a> {
|
||||
fn alloc_inner<F: Fn() -> Inner>(&self, f: F) -> &Inner {
|
||||
let r: &EI<'_> = self.0.alloc(EI::I(f()));
|
||||
if let &EI::I(ref i) = r {
|
||||
i
|
||||
} else {
|
||||
panic!("mismatch");
|
||||
match self.0.alloc(EI::I(f())) {
|
||||
EI::I(i) => i,
|
||||
_ => panic!("mismatch"),
|
||||
}
|
||||
}
|
||||
fn alloc_outer<F: Fn() -> Outer<'a>>(&self, f: F) -> &Outer<'_> {
|
||||
let r: &EI<'_> = self.0.alloc(EI::O(f()));
|
||||
if let &EI::O(ref o) = r {
|
||||
o
|
||||
} else {
|
||||
panic!("mismatch");
|
||||
match self.0.alloc(EI::O(f())) {
|
||||
EI::O(o) => o,
|
||||
_ => panic!("mismatch"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -618,9 +618,12 @@ impl MetaItemKind {
|
|||
}) => MetaItemKind::list_from_tokens(tokens.clone()),
|
||||
AttrArgs::Delimited(..) => None,
|
||||
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind {
|
||||
ast::ExprKind::Lit(token_lit) => Some(MetaItemKind::NameValue(
|
||||
Lit::from_token_lit(token_lit, expr.span).expect("token_lit in from_attr_args"),
|
||||
)),
|
||||
ast::ExprKind::Lit(token_lit) => {
|
||||
// Turn failures to `None`, we'll get parse errors elsewhere.
|
||||
Lit::from_token_lit(token_lit, expr.span)
|
||||
.ok()
|
||||
.map(|lit| MetaItemKind::NameValue(lit))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())),
|
||||
|
|
|
@ -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)
|
||||
|
@ -347,7 +345,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!();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -31,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));
|
||||
|
@ -61,7 +61,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
hir::ExprKind::Call(f, self.lower_exprs(args))
|
||||
}
|
||||
}
|
||||
ExprKind::MethodCall(box 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,
|
||||
|
@ -72,92 +72,88 @@ 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(token_lit) => {
|
||||
let lit_kind = match LitKind::from_token_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);
|
||||
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::IncludedBytes(ref bytes) => hir::ExprKind::Lit(respan(
|
||||
ExprKind::IncludedBytes(bytes) => hir::ExprKind::Lit(respan(
|
||||
self.lower_span(e.span),
|
||||
LitKind::ByteStr(bytes.clone()),
|
||||
)),
|
||||
ExprKind::Cast(ref expr, ref ty) => {
|
||||
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) => 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,
|
||||
)
|
||||
}),
|
||||
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,
|
||||
*closure_node_id,
|
||||
None,
|
||||
block.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
|
||||
|
@ -173,65 +169,63 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
self.lower_expr_await(dot_await_span, expr)
|
||||
}
|
||||
ExprKind::Closure(box Closure {
|
||||
ref binder,
|
||||
binder,
|
||||
capture_clause,
|
||||
asyncness,
|
||||
movability,
|
||||
ref fn_decl,
|
||||
ref body,
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span,
|
||||
}) => {
|
||||
if let Async::Yes { closure_id, .. } = asyncness {
|
||||
self.lower_expr_async_closure(
|
||||
binder,
|
||||
capture_clause,
|
||||
*capture_clause,
|
||||
e.id,
|
||||
closure_id,
|
||||
*closure_id,
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span,
|
||||
*fn_decl_span,
|
||||
)
|
||||
} else {
|
||||
self.lower_expr_closure(
|
||||
binder,
|
||||
capture_clause,
|
||||
*capture_clause,
|
||||
e.id,
|
||||
movability,
|
||||
*movability,
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span,
|
||||
*fn_decl_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,
|
||||
|
@ -241,22 +235,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) => {
|
||||
|
@ -278,10 +272,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) {
|
||||
|
@ -306,8 +300,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),
|
||||
};
|
||||
|
@ -358,7 +352,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!();
|
||||
};
|
||||
|
||||
|
@ -552,10 +546,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
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),
|
||||
|
@ -961,8 +955,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)
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -142,7 +142,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();
|
||||
}
|
||||
_ => {}
|
||||
|
@ -178,7 +178,7 @@ 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 {
|
||||
if let ItemKind::Use(use_tree) = &i.kind {
|
||||
self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids);
|
||||
}
|
||||
node_ids
|
||||
|
@ -190,8 +190,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
base_id: NodeId,
|
||||
vec: &mut SmallVec<[hir::ItemId; 1]>,
|
||||
) {
|
||||
match tree.kind {
|
||||
UseTreeKind::Nested(ref nested_vec) => {
|
||||
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) },
|
||||
|
@ -201,8 +201,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
UseTreeKind::Glob => {}
|
||||
UseTreeKind::Simple(_, id1, id2) => {
|
||||
for (_, &id) in
|
||||
iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[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) },
|
||||
|
@ -238,26 +238,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: 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| {
|
||||
|
@ -274,37 +274,30 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
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, Some(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
|
||||
|
@ -314,7 +307,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,
|
||||
|
@ -323,9 +316,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(
|
||||
|
@ -336,7 +327,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,
|
||||
|
@ -349,7 +340,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,
|
||||
|
@ -358,7 +349,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,
|
||||
|
@ -372,10 +363,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:
|
||||
|
@ -413,30 +404,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,
|
||||
|
@ -449,13 +434,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,
|
||||
|
@ -469,10 +454,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
);
|
||||
hir::ItemKind::TraitAlias(generics, bounds)
|
||||
}
|
||||
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
|
||||
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")
|
||||
|
@ -664,8 +649,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)) =
|
||||
|
@ -685,10 +670,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"),
|
||||
|
@ -725,33 +710,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),
|
||||
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, self.local_def_id(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,
|
||||
|
@ -783,13 +768,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let hir_id = self.lower_node_id(i.id);
|
||||
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(
|
||||
|
@ -801,7 +786,7 @@ 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));
|
||||
|
@ -814,15 +799,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,
|
||||
|
@ -1354,7 +1333,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 = || {
|
||||
|
@ -1515,11 +1494,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(),
|
||||
|
@ -1532,29 +1511,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),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -932,13 +932,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
|
||||
fn lower_attr_args(&self, args: &AttrArgs) -> AttrArgs {
|
||||
match *args {
|
||||
match args {
|
||||
AttrArgs::Empty => AttrArgs::Empty,
|
||||
AttrArgs::Delimited(ref args) => AttrArgs::Delimited(self.lower_delim_args(args)),
|
||||
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]`).
|
||||
AttrArgs::Eq(eq_span, AttrArgsEq::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(token_lit) = expr.kind {
|
||||
|
@ -957,9 +957,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
span: DUMMY_SP,
|
||||
}
|
||||
};
|
||||
AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit))
|
||||
AttrArgs::Eq(*eq_span, AttrArgsEq::Hir(lit))
|
||||
}
|
||||
AttrArgs::Eq(_, AttrArgsEq::Hir(ref lit)) => {
|
||||
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||
unreachable!("in literal form when lowering mac args eq: {:?}", lit)
|
||||
}
|
||||
}
|
||||
|
@ -987,12 +987,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
|
||||
|
@ -1004,15 +1004,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:
|
||||
|
@ -1122,7 +1122,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),
|
||||
|
@ -1133,7 +1133,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)
|
||||
|
@ -1240,12 +1240,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,7 +1261,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
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,
|
||||
|
@ -1272,13 +1272,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}))
|
||||
}
|
||||
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 => {
|
||||
|
@ -1298,48 +1298,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,
|
||||
|
@ -1347,7 +1345,7 @@ 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,
|
||||
|
@ -1355,13 +1353,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
ImplTraitContext::Universal => {
|
||||
self.create_def(
|
||||
self.current_hir_id_owner.def_id,
|
||||
def_node_id,
|
||||
*def_node_id,
|
||||
DefPathData::ImplTrait,
|
||||
);
|
||||
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);
|
||||
|
@ -1740,8 +1738,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
matches!(kind, FnDeclKind::Trait),
|
||||
)
|
||||
} else {
|
||||
match decl.output {
|
||||
FnRetTy::Ty(ref ty) => {
|
||||
match &decl.output {
|
||||
FnRetTy::Ty(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);
|
||||
|
@ -1763,7 +1761,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
};
|
||||
hir::FnRetTy::Return(self.lower_ty(ty, &mut context))
|
||||
}
|
||||
FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
|
||||
FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1777,18 +1775,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
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)
|
||||
TyKind::Rptr(_, 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() => {
|
||||
TyKind::Rptr(_, mt) if mt.ty.kind.is_implicit_self() => {
|
||||
hir::ImplicitSelfKind::ImmRef
|
||||
}
|
||||
_ => hir::ImplicitSelfKind::None,
|
||||
|
@ -2181,7 +2179,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`.
|
||||
|
@ -2197,7 +2195,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))
|
||||
|
@ -2207,7 +2205,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));
|
||||
(
|
||||
|
|
|
@ -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,13 +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 {
|
||||
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));
|
||||
|
|
|
@ -185,12 +185,12 @@ 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 {
|
||||
GenericArgs::Parenthesized(data) => match parenthesized_generic_args {
|
||||
ParenthesizedGenericArgs::Ok => {
|
||||
self.lower_parenthesized_parameter_data(data, itctx)
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ use rustc_hir::Expr;
|
|||
use rustc_hir_analysis::astconv::AstConv;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::{Coercion, InferOk, InferResult};
|
||||
use rustc_infer::traits::{Obligation, TraitEngine, TraitEngineExt};
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::adjustment::{
|
||||
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
|
||||
|
@ -62,8 +62,7 @@ use rustc_span::{self, BytePos, DesugaringKind, Span};
|
|||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::TraitEngineExt as _;
|
||||
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, ObligationCtxt};
|
||||
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::ops::Deref;
|
||||
|
@ -1055,9 +1054,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let Ok(ok) = coerce.coerce(source, target) else {
|
||||
return false;
|
||||
};
|
||||
let mut fcx = <dyn TraitEngine<'tcx>>::new_in_snapshot(self.tcx);
|
||||
fcx.register_predicate_obligations(self, ok.obligations);
|
||||
fcx.select_where_possible(&self).is_empty()
|
||||
let ocx = ObligationCtxt::new_in_snapshot(self);
|
||||
ocx.register_obligations(ok.obligations);
|
||||
ocx.select_where_possible().is_empty()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -245,9 +245,9 @@ impl<'a> Parser<'a> {
|
|||
/// PATH `=` UNSUFFIXED_LIT
|
||||
/// The delimiters or `=` are still put into the resulting token stream.
|
||||
pub fn parse_attr_item(&mut self, capture_tokens: bool) -> PResult<'a, ast::AttrItem> {
|
||||
let item = match self.token.kind {
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
Nonterminal::NtMeta(ref item) => Some(item.clone().into_inner()),
|
||||
let item = match &self.token.kind {
|
||||
token::Interpolated(nt) => match &**nt {
|
||||
Nonterminal::NtMeta(item) => Some(item.clone().into_inner()),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
|
@ -364,9 +364,9 @@ impl<'a> Parser<'a> {
|
|||
/// meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
|
||||
/// ```
|
||||
pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> {
|
||||
let nt_meta = match self.token.kind {
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
token::NtMeta(ref e) => Some(e.clone()),
|
||||
let nt_meta = match &self.token.kind {
|
||||
token::Interpolated(nt) => match &**nt {
|
||||
token::NtMeta(e) => Some(e.clone()),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
|
|
|
@ -973,7 +973,7 @@ impl<'a> Parser<'a> {
|
|||
inner_op: &Expr,
|
||||
outer_op: &Spanned<AssocOp>,
|
||||
) -> bool /* advanced the cursor */ {
|
||||
if let ExprKind::Binary(op, ref l1, ref r1) = inner_op.kind {
|
||||
if let ExprKind::Binary(op, l1, r1) = &inner_op.kind {
|
||||
if let ExprKind::Field(_, ident) = l1.kind
|
||||
&& ident.as_str().parse::<i32>().is_err()
|
||||
&& !matches!(r1.kind, ExprKind::Lit(_))
|
||||
|
@ -1079,8 +1079,8 @@ impl<'a> Parser<'a> {
|
|||
|
||||
let mk_err_expr = |this: &Self, span| Ok(Some(this.mk_expr(span, ExprKind::Err)));
|
||||
|
||||
match inner_op.kind {
|
||||
ExprKind::Binary(op, ref l1, ref r1) if op.node.is_comparison() => {
|
||||
match &inner_op.kind {
|
||||
ExprKind::Binary(op, l1, r1) if op.node.is_comparison() => {
|
||||
let mut err = ComparisonOperatorsCannotBeChained {
|
||||
span: vec![op.span, self.prev_token.span],
|
||||
suggest_turbofish: None,
|
||||
|
@ -1237,8 +1237,8 @@ impl<'a> Parser<'a> {
|
|||
let bounds = self.parse_generic_bounds(None)?;
|
||||
let sum_span = ty.span.to(self.prev_token.span);
|
||||
|
||||
let sub = match ty.kind {
|
||||
TyKind::Rptr(ref lifetime, ref mut_ty) => {
|
||||
let sub = match &ty.kind {
|
||||
TyKind::Rptr(lifetime, mut_ty) => {
|
||||
let sum_with_parens = pprust::to_string(|s| {
|
||||
s.s.word("&");
|
||||
s.print_opt_lifetime(lifetime);
|
||||
|
|
|
@ -414,7 +414,7 @@ impl<'a> Parser<'a> {
|
|||
self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
|
||||
false
|
||||
}
|
||||
(true, Some(ref op)) if !op.can_continue_expr_unambiguously() => false,
|
||||
(true, Some(op)) if !op.can_continue_expr_unambiguously() => false,
|
||||
(true, Some(_)) => {
|
||||
self.error_found_expr_would_be_stmt(lhs);
|
||||
true
|
||||
|
@ -1728,7 +1728,7 @@ impl<'a> Parser<'a> {
|
|||
|| !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
|
||||
{
|
||||
let expr = self.parse_expr_opt()?;
|
||||
if let Some(ref expr) = expr {
|
||||
if let Some(expr) = &expr {
|
||||
if label.is_some()
|
||||
&& matches!(
|
||||
expr.kind,
|
||||
|
@ -2590,8 +2590,8 @@ impl<'a> Parser<'a> {
|
|||
// Used to check the `let_chains` and `if_let_guard` features mostly by scanning
|
||||
// `&&` tokens.
|
||||
fn check_let_expr(expr: &Expr) -> (bool, bool) {
|
||||
match expr.kind {
|
||||
ExprKind::Binary(BinOp { node: BinOpKind::And, .. }, ref lhs, ref rhs) => {
|
||||
match &expr.kind {
|
||||
ExprKind::Binary(BinOp { node: BinOpKind::And, .. }, lhs, rhs) => {
|
||||
let lhs_rslt = check_let_expr(lhs);
|
||||
let rhs_rslt = check_let_expr(rhs);
|
||||
(lhs_rslt.0 || rhs_rslt.0, false)
|
||||
|
|
|
@ -1255,8 +1255,8 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
match impl_info.1 {
|
||||
ItemKind::Impl(box Impl { of_trait: Some(ref trai), ref mut constness, .. }) => {
|
||||
match &mut impl_info.1 {
|
||||
ItemKind::Impl(box Impl { of_trait: Some(trai), constness, .. }) => {
|
||||
*constness = Const::Yes(const_span);
|
||||
|
||||
let before_trait = trai.path.span.shrink_to_lo();
|
||||
|
@ -2585,8 +2585,8 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
fn is_named_param(&self) -> bool {
|
||||
let offset = match self.token.kind {
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
let offset = match &self.token.kind {
|
||||
token::Interpolated(nt) => match **nt {
|
||||
token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
|
||||
_ => 0,
|
||||
},
|
||||
|
|
|
@ -384,8 +384,8 @@ enum TokenType {
|
|||
|
||||
impl TokenType {
|
||||
fn to_string(&self) -> String {
|
||||
match *self {
|
||||
TokenType::Token(ref t) => format!("`{}`", pprust::token_kind_to_string(t)),
|
||||
match self {
|
||||
TokenType::Token(t) => format!("`{}`", pprust::token_kind_to_string(t)),
|
||||
TokenType::Keyword(kw) => format!("`{}`", kw),
|
||||
TokenType::Operator => "an operator".to_string(),
|
||||
TokenType::Lifetime => "lifetime".to_string(),
|
||||
|
@ -738,8 +738,8 @@ impl<'a> Parser<'a> {
|
|||
|
||||
fn check_inline_const(&self, dist: usize) -> bool {
|
||||
self.is_keyword_ahead(dist, &[kw::Const])
|
||||
&& self.look_ahead(dist + 1, |t| match t.kind {
|
||||
token::Interpolated(ref nt) => matches!(**nt, token::NtBlock(..)),
|
||||
&& self.look_ahead(dist + 1, |t| match &t.kind {
|
||||
token::Interpolated(nt) => matches!(**nt, token::NtBlock(..)),
|
||||
token::OpenDelim(Delimiter::Brace) => true,
|
||||
_ => false,
|
||||
})
|
||||
|
@ -860,7 +860,7 @@ impl<'a> Parser<'a> {
|
|||
if let token::CloseDelim(..) | token::Eof = self.token.kind {
|
||||
break;
|
||||
}
|
||||
if let Some(ref t) = sep.sep {
|
||||
if let Some(t) = &sep.sep {
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
|
@ -895,7 +895,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
_ => {
|
||||
// Attempt to keep parsing if it was a similar separator.
|
||||
if let Some(ref tokens) = t.similar_tokens() {
|
||||
if let Some(tokens) = t.similar_tokens() {
|
||||
if tokens.contains(&self.token.kind) && !unclosed_delims {
|
||||
self.bump();
|
||||
}
|
||||
|
|
|
@ -42,9 +42,9 @@ impl<'a> Parser<'a> {
|
|||
token::Comma | token::Ident(..) | token::Interpolated(..) => true,
|
||||
_ => token.can_begin_type(),
|
||||
},
|
||||
NonterminalKind::Block => match token.kind {
|
||||
NonterminalKind::Block => match &token.kind {
|
||||
token::OpenDelim(Delimiter::Brace) => true,
|
||||
token::Interpolated(ref nt) => !matches!(
|
||||
token::Interpolated(nt) => !matches!(
|
||||
**nt,
|
||||
token::NtItem(_)
|
||||
| token::NtPat(_)
|
||||
|
@ -56,16 +56,16 @@ impl<'a> Parser<'a> {
|
|||
),
|
||||
_ => false,
|
||||
},
|
||||
NonterminalKind::Path | NonterminalKind::Meta => match token.kind {
|
||||
NonterminalKind::Path | NonterminalKind::Meta => match &token.kind {
|
||||
token::ModSep | token::Ident(..) => true,
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
token::Interpolated(nt) => match **nt {
|
||||
token::NtPath(_) | token::NtMeta(_) => true,
|
||||
_ => may_be_ident(&nt),
|
||||
},
|
||||
_ => false,
|
||||
},
|
||||
NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr { .. } => {
|
||||
match token.kind {
|
||||
match &token.kind {
|
||||
token::Ident(..) | // box, ref, mut, and other identifiers (can stricten)
|
||||
token::OpenDelim(Delimiter::Parenthesis) | // tuple pattern
|
||||
token::OpenDelim(Delimiter::Bracket) | // slice pattern
|
||||
|
@ -80,13 +80,13 @@ impl<'a> Parser<'a> {
|
|||
token::BinOp(token::Shl) => true, // path (double UFCS)
|
||||
// leading vert `|` or-pattern
|
||||
token::BinOp(token::Or) => matches!(kind, NonterminalKind::PatWithOr {..}),
|
||||
token::Interpolated(ref nt) => may_be_ident(nt),
|
||||
token::Interpolated(nt) => may_be_ident(nt),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
NonterminalKind::Lifetime => match token.kind {
|
||||
NonterminalKind::Lifetime => match &token.kind {
|
||||
token::Lifetime(_) => true,
|
||||
token::Interpolated(ref nt) => {
|
||||
token::Interpolated(nt) => {
|
||||
matches!(**nt, token::NtLifetime(_))
|
||||
}
|
||||
_ => false,
|
||||
|
|
|
@ -485,7 +485,7 @@ impl<'a> Parser<'a> {
|
|||
let mut rhs = self.parse_pat_no_top_alt(None)?;
|
||||
let sp = lhs.span.to(rhs.span);
|
||||
|
||||
if let PatKind::Ident(_, _, ref mut sub @ None) = rhs.kind {
|
||||
if let PatKind::Ident(_, _, sub @ None) = &mut rhs.kind {
|
||||
// The user inverted the order, so help them fix that.
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
// FIXME(bindings_after_at): Remove this code when stabilizing the feature.
|
||||
|
@ -595,7 +595,7 @@ impl<'a> Parser<'a> {
|
|||
self.recover_additional_muts();
|
||||
|
||||
// Make sure we don't allow e.g. `let mut $p;` where `$p:pat`.
|
||||
if let token::Interpolated(ref nt) = self.token.kind {
|
||||
if let token::Interpolated(nt) = &self.token.kind {
|
||||
if let token::NtPat(_) = **nt {
|
||||
self.expected_ident_found().emit();
|
||||
}
|
||||
|
@ -796,7 +796,7 @@ impl<'a> Parser<'a> {
|
|||
/// expression syntax `...expr` for splatting in expressions.
|
||||
fn parse_pat_range_to(&mut self, mut re: Spanned<RangeEnd>) -> PResult<'a, PatKind> {
|
||||
let end = self.parse_pat_range_end()?;
|
||||
if let RangeEnd::Included(ref mut syn @ RangeSyntax::DotDotDot) = &mut re.node {
|
||||
if let RangeEnd::Included(syn @ RangeSyntax::DotDotDot) = &mut re.node {
|
||||
*syn = RangeSyntax::DotDotEq;
|
||||
self.struct_span_err(re.span, "range-to patterns with `...` are not allowed")
|
||||
.span_suggestion_short(
|
||||
|
|
|
@ -563,9 +563,9 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
|
||||
let mut eat_semi = true;
|
||||
match stmt.kind {
|
||||
match &mut stmt.kind {
|
||||
// Expression without semicolon.
|
||||
StmtKind::Expr(ref mut expr)
|
||||
StmtKind::Expr(expr)
|
||||
if self.token != token::Eof && classify::expr_requires_semi_to_be_stmt(expr) => {
|
||||
// Just check for errors and recover; do not eat semicolon yet.
|
||||
// `expect_one_of` returns PResult<'a, bool /* recovered */>
|
||||
|
@ -611,7 +611,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
StmtKind::Expr(_) | StmtKind::MacCall(_) => {}
|
||||
StmtKind::Local(ref mut local) if let Err(e) = self.expect_semi() => {
|
||||
StmtKind::Local(local) if let Err(e) = self.expect_semi() => {
|
||||
// We might be at the `,` in `let x = foo<bar, baz>;`. Try to recover.
|
||||
match &mut local.kind {
|
||||
LocalKind::Init(expr) | LocalKind::InitElse(expr, _) => {
|
||||
|
|
|
@ -4,13 +4,12 @@ pub mod suggestions;
|
|||
|
||||
use super::{
|
||||
FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause,
|
||||
ObligationCauseCode, OutputTypeParameterMismatch, Overflow, PredicateObligation,
|
||||
SelectionContext, SelectionError, TraitNotObjectSafe,
|
||||
ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow,
|
||||
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
|
||||
};
|
||||
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
|
||||
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use crate::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||
use crate::traits::engine::TraitEngineExt as _;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use crate::traits::query::normalize::AtExt as _;
|
||||
use crate::traits::specialize::to_pretty_impl_header;
|
||||
|
@ -30,7 +29,6 @@ use rustc_hir::Item;
|
|||
use rustc_hir::Node;
|
||||
use rustc_infer::infer::error_reporting::TypeErrCtxt;
|
||||
use rustc_infer::infer::TypeTrace;
|
||||
use rustc_infer::traits::TraitEngine;
|
||||
use rustc_middle::traits::select::OverflowError;
|
||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||
use rustc_middle::ty::error::ExpectedFound;
|
||||
|
@ -354,9 +352,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
param_env,
|
||||
ty.rebind(ty::TraitPredicate { trait_ref, constness, polarity }),
|
||||
);
|
||||
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new_in_snapshot(self.tcx);
|
||||
fulfill_cx.register_predicate_obligation(self, obligation);
|
||||
if fulfill_cx.select_all_or_error(self).is_empty() {
|
||||
let ocx = ObligationCtxt::new_in_snapshot(self);
|
||||
ocx.register_obligation(obligation);
|
||||
if ocx.select_all_or_error().is_empty() {
|
||||
return Ok((
|
||||
ty::ClosureKind::from_def_id(self.tcx, trait_def_id)
|
||||
.expect("expected to map DefId to ClosureKind"),
|
||||
|
@ -2546,7 +2544,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
let obligation =
|
||||
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred);
|
||||
|
||||
self.predicate_may_hold(&obligation)
|
||||
// We don't use `InferCtxt::predicate_may_hold` because that
|
||||
// will re-run predicates that overflow locally, which ends up
|
||||
// taking a really long time to compute.
|
||||
self.evaluate_obligation(&obligation).map_or(false, |eval| eval.may_apply())
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1340,9 +1340,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
obligation.param_env,
|
||||
trait_pred_and_suggested_ty,
|
||||
);
|
||||
let suggested_ty_would_satisfy_obligation = self
|
||||
.evaluate_obligation_no_overflow(&new_obligation)
|
||||
.must_apply_modulo_regions();
|
||||
let suggested_ty_would_satisfy_obligation =
|
||||
self.predicate_must_hold_modulo_regions(&new_obligation);
|
||||
if suggested_ty_would_satisfy_obligation {
|
||||
let sp = self
|
||||
.tcx
|
||||
|
|
|
@ -31,7 +31,6 @@ use rustc_errors::ErrorGuaranteed;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_infer::traits::TraitEngineExt as _;
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{
|
||||
|
@ -403,9 +402,7 @@ pub fn fully_solve_obligation<'tcx>(
|
|||
infcx: &InferCtxt<'tcx>,
|
||||
obligation: PredicateObligation<'tcx>,
|
||||
) -> Vec<FulfillmentError<'tcx>> {
|
||||
let mut engine = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
|
||||
engine.register_predicate_obligation(infcx, obligation);
|
||||
engine.select_all_or_error(infcx)
|
||||
fully_solve_obligations(infcx, [obligation])
|
||||
}
|
||||
|
||||
/// Process a set of obligations (and any nested obligations that come from them)
|
||||
|
@ -414,9 +411,9 @@ pub fn fully_solve_obligations<'tcx>(
|
|||
infcx: &InferCtxt<'tcx>,
|
||||
obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
|
||||
) -> Vec<FulfillmentError<'tcx>> {
|
||||
let mut engine = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
|
||||
engine.register_predicate_obligations(infcx, obligations);
|
||||
engine.select_all_or_error(infcx)
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
ocx.register_obligations(obligations);
|
||||
ocx.select_all_or_error()
|
||||
}
|
||||
|
||||
/// Process a bound (and any nested obligations that come from it) to completion.
|
||||
|
@ -429,9 +426,16 @@ pub fn fully_solve_bound<'tcx>(
|
|||
ty: Ty<'tcx>,
|
||||
bound: DefId,
|
||||
) -> Vec<FulfillmentError<'tcx>> {
|
||||
let mut engine = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
|
||||
engine.register_bound(infcx, param_env, ty, bound, cause);
|
||||
engine.select_all_or_error(infcx)
|
||||
let tcx = infcx.tcx;
|
||||
let trait_ref = ty::TraitRef { def_id: bound, substs: tcx.mk_substs_trait(ty, []) };
|
||||
let obligation = Obligation {
|
||||
cause,
|
||||
recursion_depth: 0,
|
||||
param_env,
|
||||
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
|
||||
};
|
||||
|
||||
fully_solve_obligation(infcx, obligation)
|
||||
}
|
||||
|
||||
/// Normalizes the predicates and checks whether they hold in an empty environment. If this
|
||||
|
|
|
@ -10,14 +10,14 @@
|
|||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html
|
||||
|
||||
pub mod specialization_graph;
|
||||
use rustc_infer::traits::{TraitEngine, TraitEngineExt as _};
|
||||
use specialization_graph::GraphExt;
|
||||
|
||||
use crate::errors::NegativePositiveConflict;
|
||||
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
||||
use crate::traits::engine::TraitEngineExt as _;
|
||||
use crate::traits::select::IntercrateAmbiguityCause;
|
||||
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
|
||||
use crate::traits::{
|
||||
self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt,
|
||||
};
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_errors::{error_code, DelayDm, Diagnostic};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
|
@ -204,12 +204,12 @@ fn fulfill_implication<'tcx>(
|
|||
|
||||
// Needs to be `in_snapshot` because this function is used to rebase
|
||||
// substitutions, which may happen inside of a select within a probe.
|
||||
let mut engine = <dyn TraitEngine<'tcx>>::new_in_snapshot(infcx.tcx);
|
||||
let ocx = ObligationCtxt::new_in_snapshot(infcx);
|
||||
// attempt to prove all of the predicates for impl2 given those for impl1
|
||||
// (which are packed up in penv)
|
||||
engine.register_predicate_obligations(infcx, obligations.chain(more_obligations));
|
||||
ocx.register_obligations(obligations.chain(more_obligations));
|
||||
|
||||
let errors = engine.select_all_or_error(infcx);
|
||||
let errors = ocx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
// no dice!
|
||||
debug!(
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use crate::traits::ObligationCause;
|
||||
use crate::traits::{TraitEngine, TraitEngineExt};
|
||||
use crate::traits::{ObligationCause, ObligationCtxt};
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir as hir;
|
||||
|
@ -72,28 +71,16 @@ fn type_marked_structural<'tcx>(
|
|||
adt_ty: Ty<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
) -> bool {
|
||||
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
// require `#[derive(PartialEq)]`
|
||||
let structural_peq_def_id =
|
||||
infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span));
|
||||
fulfillment_cx.register_bound(
|
||||
infcx,
|
||||
ty::ParamEnv::empty(),
|
||||
adt_ty,
|
||||
structural_peq_def_id,
|
||||
cause.clone(),
|
||||
);
|
||||
ocx.register_bound(cause.clone(), ty::ParamEnv::empty(), adt_ty, structural_peq_def_id);
|
||||
// for now, require `#[derive(Eq)]`. (Doing so is a hack to work around
|
||||
// the type `for<'a> fn(&'a ())` failing to implement `Eq` itself.)
|
||||
let structural_teq_def_id =
|
||||
infcx.tcx.require_lang_item(LangItem::StructuralTeq, Some(cause.span));
|
||||
fulfillment_cx.register_bound(
|
||||
infcx,
|
||||
ty::ParamEnv::empty(),
|
||||
adt_ty,
|
||||
structural_teq_def_id,
|
||||
cause,
|
||||
);
|
||||
ocx.register_bound(cause, ty::ParamEnv::empty(), adt_ty, structural_teq_def_id);
|
||||
|
||||
// We deliberately skip *reporting* fulfillment errors (via
|
||||
// `report_fulfillment_errors`), for two reasons:
|
||||
|
@ -104,7 +91,7 @@ fn type_marked_structural<'tcx>(
|
|||
//
|
||||
// 2. We are sometimes doing future-incompatibility lints for
|
||||
// now, so we do not want unconditional errors here.
|
||||
fulfillment_cx.select_all_or_error(infcx).is_empty()
|
||||
ocx.select_all_or_error().is_empty()
|
||||
}
|
||||
|
||||
/// This implements the traversal over the structure of a given type to try to
|
||||
|
|
|
@ -5,16 +5,15 @@
|
|||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::canonical::{self, Canonical};
|
||||
use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::query::OutlivesBound;
|
||||
use rustc_infer::traits::TraitEngineExt as _;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_span::source_map::DUMMY_SP;
|
||||
use rustc_trait_selection::infer::InferCtxtBuilderExt;
|
||||
use rustc_trait_selection::traits::query::{CanonicalTyGoal, Fallible, NoSolution};
|
||||
use rustc_trait_selection::traits::wf;
|
||||
use rustc_trait_selection::traits::{TraitEngine, TraitEngineExt};
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
pub(crate) fn provide(p: &mut Providers) {
|
||||
|
@ -30,16 +29,16 @@ fn implied_outlives_bounds<'tcx>(
|
|||
> {
|
||||
tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| {
|
||||
let (param_env, ty) = key.into_parts();
|
||||
compute_implied_outlives_bounds(&ocx.infcx, param_env, ty)
|
||||
compute_implied_outlives_bounds(ocx, param_env, ty)
|
||||
})
|
||||
}
|
||||
|
||||
fn compute_implied_outlives_bounds<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
ocx: &ObligationCtxt<'_, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Fallible<Vec<OutlivesBound<'tcx>>> {
|
||||
let tcx = infcx.tcx;
|
||||
let tcx = ocx.infcx.tcx;
|
||||
|
||||
// Sometimes when we ask what it takes for T: WF, we get back that
|
||||
// U: WF is required; in that case, we push U onto this stack and
|
||||
|
@ -52,8 +51,6 @@ fn compute_implied_outlives_bounds<'tcx>(
|
|||
let mut outlives_bounds: Vec<ty::OutlivesPredicate<ty::GenericArg<'tcx>, ty::Region<'tcx>>> =
|
||||
vec![];
|
||||
|
||||
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(tcx);
|
||||
|
||||
while let Some(arg) = wf_args.pop() {
|
||||
if !checked_wf_args.insert(arg) {
|
||||
continue;
|
||||
|
@ -70,15 +67,15 @@ fn compute_implied_outlives_bounds<'tcx>(
|
|||
// FIXME(@lcnr): It's not really "always fine", having fewer implied
|
||||
// bounds can be backward incompatible, e.g. #101951 was caused by
|
||||
// us not dealing with inference vars in `TypeOutlives` predicates.
|
||||
let obligations = wf::obligations(infcx, param_env, hir::CRATE_HIR_ID, 0, arg, DUMMY_SP)
|
||||
.unwrap_or_default();
|
||||
let obligations =
|
||||
wf::obligations(ocx.infcx, param_env, hir::CRATE_HIR_ID, 0, arg, DUMMY_SP)
|
||||
.unwrap_or_default();
|
||||
|
||||
// While these predicates should all be implied by other parts of
|
||||
// the program, they are still relevant as they may constrain
|
||||
// inference variables, which is necessary to add the correct
|
||||
// implied bounds in some cases, mostly when dealing with projections.
|
||||
fulfill_cx.register_predicate_obligations(
|
||||
infcx,
|
||||
ocx.register_obligations(
|
||||
obligations.iter().filter(|o| o.predicate.has_non_region_infer()).cloned(),
|
||||
);
|
||||
|
||||
|
@ -116,9 +113,9 @@ fn compute_implied_outlives_bounds<'tcx>(
|
|||
}));
|
||||
}
|
||||
|
||||
// Ensure that those obligations that we had to solve
|
||||
// get solved *here*.
|
||||
match fulfill_cx.select_all_or_error(infcx).as_slice() {
|
||||
// This call to `select_all_or_error` is necessary to constrain inference variables, which we
|
||||
// use further down when computing the implied bounds.
|
||||
match ocx.select_all_or_error().as_slice() {
|
||||
[] => (),
|
||||
_ => return Err(NoSolution),
|
||||
}
|
||||
|
@ -130,7 +127,7 @@ fn compute_implied_outlives_bounds<'tcx>(
|
|||
.flat_map(|ty::OutlivesPredicate(a, r_b)| match a.unpack() {
|
||||
ty::GenericArgKind::Lifetime(r_a) => vec![OutlivesBound::RegionSubRegion(r_b, r_a)],
|
||||
ty::GenericArgKind::Type(ty_a) => {
|
||||
let ty_a = infcx.resolve_vars_if_possible(ty_a);
|
||||
let ty_a = ocx.infcx.resolve_vars_if_possible(ty_a);
|
||||
let mut components = smallvec![];
|
||||
push_outlives_components(tcx, ty_a, &mut components);
|
||||
implied_bounds_from_components(r_b, components)
|
||||
|
|
|
@ -1094,7 +1094,13 @@ impl<'a> Builder<'a> {
|
|||
let my_out = match mode {
|
||||
// This is the intended out directory for compiler documentation.
|
||||
Mode::Rustc | Mode::ToolRustc => self.compiler_doc_out(target),
|
||||
Mode::Std => out_dir.join(target.triple).join("doc"),
|
||||
Mode::Std => {
|
||||
if self.config.cmd.json() {
|
||||
out_dir.join(target.triple).join("json-doc")
|
||||
} else {
|
||||
out_dir.join(target.triple).join("doc")
|
||||
}
|
||||
}
|
||||
_ => panic!("doc mode {:?} not expected", mode),
|
||||
};
|
||||
let rustdoc = self.rustdoc(compiler);
|
||||
|
|
|
@ -564,27 +564,22 @@ fn doc_std(
|
|||
);
|
||||
}
|
||||
let compiler = builder.compiler(stage, builder.config.build);
|
||||
|
||||
let target_doc_dir_name = if format == DocumentationFormat::JSON { "json-doc" } else { "doc" };
|
||||
let target_dir =
|
||||
builder.stage_out(compiler, Mode::Std).join(target.triple).join(target_doc_dir_name);
|
||||
|
||||
// This is directory where the compiler will place the output of the command.
|
||||
// We will then copy the files from this directory into the final `out` directory, the specified
|
||||
// as a function parameter.
|
||||
let out_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join("doc");
|
||||
// `cargo` uses the same directory for both JSON docs and HTML docs.
|
||||
// This could lead to cross-contamination when copying files into the specified `out` directory.
|
||||
// For example:
|
||||
// ```bash
|
||||
// x doc std
|
||||
// x doc std --json
|
||||
// ```
|
||||
// could lead to HTML docs being copied into the JSON docs output directory.
|
||||
// To avoid this issue, we clean the doc folder before invoking `cargo`.
|
||||
if out_dir.exists() {
|
||||
builder.remove_dir(&out_dir);
|
||||
}
|
||||
let out_dir = target_dir.join(target.triple).join("doc");
|
||||
|
||||
let run_cargo_rustdoc_for = |package: &str| {
|
||||
let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustdoc");
|
||||
compile::std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
cargo
|
||||
.arg("--target-dir")
|
||||
.arg(&*target_dir.to_string_lossy())
|
||||
.arg("-p")
|
||||
.arg(package)
|
||||
.arg("-Zskip-rustdoc-fingerprint")
|
||||
|
|
|
@ -701,6 +701,8 @@ a {
|
|||
}
|
||||
|
||||
.small-section-header {
|
||||
/* fields use <span> tags, but should get their own lines */
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
|
36
src/test/run-make/rustdoc-verify-output-files/Makefile
Normal file
36
src/test/run-make/rustdoc-verify-output-files/Makefile
Normal file
|
@ -0,0 +1,36 @@
|
|||
include ../../run-make-fulldeps/tools.mk
|
||||
|
||||
OUTPUT_DIR := "$(TMPDIR)/rustdoc"
|
||||
TMP_OUTPUT_DIR := "$(TMPDIR)/tmp-rustdoc"
|
||||
|
||||
all:
|
||||
# Generate html docs
|
||||
$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR)
|
||||
|
||||
# Copy first output for to check if it's exactly same after second compilation
|
||||
cp -R $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)
|
||||
|
||||
# Generate html docs once again on same output
|
||||
$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR)
|
||||
|
||||
# Check if everything exactly same
|
||||
$(DIFF) -r -q $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)
|
||||
|
||||
# Generate json doc on the same output
|
||||
$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) -Z unstable-options --output-format json
|
||||
|
||||
# Check if expected json file is generated
|
||||
[ -e $(OUTPUT_DIR)/foobar.json ]
|
||||
|
||||
# TODO
|
||||
# We should re-generate json doc once again and compare the diff with previously
|
||||
# generated one. Because layout of json docs changes in each compilation, we can't
|
||||
# do that currently.
|
||||
#
|
||||
# See https://github.com/rust-lang/rust/issues/103785#issuecomment-1307425590 for details.
|
||||
|
||||
# remove generated json doc
|
||||
rm $(OUTPUT_DIR)/foobar.json
|
||||
|
||||
# Check if json doc compilation broke any of the html files generated previously
|
||||
$(DIFF) -r -q $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)
|
1
src/test/run-make/rustdoc-verify-output-files/src/lib.rs
Normal file
1
src/test/run-make/rustdoc-verify-output-files/src/lib.rs
Normal file
|
@ -0,0 +1 @@
|
|||
// nothing to see here
|
|
@ -408,6 +408,11 @@ pub struct WithGenerics<T: TraitWithNoDocblocks, S = String, E = WhoLetTheDogOut
|
|||
p: P,
|
||||
}
|
||||
|
||||
pub struct StructWithPublicUndocumentedFields {
|
||||
pub first: u32,
|
||||
pub second: u32,
|
||||
}
|
||||
|
||||
pub const CONST: u8 = 0;
|
||||
|
||||
pub trait TraitWithoutGenerics {
|
||||
|
|
5
src/test/rustdoc-gui/struct-fields.goml
Normal file
5
src/test/rustdoc-gui/struct-fields.goml
Normal file
|
@ -0,0 +1,5 @@
|
|||
goto: "file://" + |DOC_PATH| + "/test_docs/struct.StructWithPublicUndocumentedFields.html"
|
||||
|
||||
// Both fields must be on their own line. In other words, they have display: block.
|
||||
store-property: (first_top, "//*[@id='structfield.first']", "offsetTop")
|
||||
assert-property-false: ("//*[@id='structfield.second']", { "offsetTop": |first_top| })
|
4
src/test/ui/parser/issue-104620.rs
Normal file
4
src/test/ui/parser/issue-104620.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
#![feature(rustc_attrs)]
|
||||
|
||||
#![rustc_dummy=5z] //~ ERROR unexpected expression: `5z`
|
||||
fn main() {}
|
8
src/test/ui/parser/issue-104620.stderr
Normal file
8
src/test/ui/parser/issue-104620.stderr
Normal file
|
@ -0,0 +1,8 @@
|
|||
error: unexpected expression: `5z`
|
||||
--> $DIR/issue-104620.rs:3:16
|
||||
|
|
||||
LL | #![rustc_dummy=5z]
|
||||
| ^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
6
src/test/ui/traits/predicate_can_apply-hang.rs
Normal file
6
src/test/ui/traits/predicate_can_apply-hang.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
fn f<B>(x: Vec<[[[B; 1]; 1]; 1]>) -> impl PartialEq<B> {
|
||||
//~^ ERROR can't compare `Vec<[[[B; 1]; 1]; 1]>` with `B`
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {}
|
21
src/test/ui/traits/predicate_can_apply-hang.stderr
Normal file
21
src/test/ui/traits/predicate_can_apply-hang.stderr
Normal file
|
@ -0,0 +1,21 @@
|
|||
error[E0277]: can't compare `Vec<[[[B; 1]; 1]; 1]>` with `B`
|
||||
--> $DIR/predicate_can_apply-hang.rs:1:38
|
||||
|
|
||||
LL | fn f<B>(x: Vec<[[[B; 1]; 1]; 1]>) -> impl PartialEq<B> {
|
||||
| ^^^^^^^^^^^^^^^^^ no implementation for `Vec<[[[B; 1]; 1]; 1]> == B`
|
||||
LL |
|
||||
LL | x
|
||||
| - return type was inferred to be `Vec<[[[B; 1]; 1]; 1]>` here
|
||||
|
|
||||
= help: the trait `PartialEq<B>` is not implemented for `Vec<[[[B; 1]; 1]; 1]>`
|
||||
= help: the following other types implement trait `PartialEq<Rhs>`:
|
||||
<Vec<T, A1> as PartialEq<Vec<U, A2>>>
|
||||
<Vec<T, A> as PartialEq<&[U; N]>>
|
||||
<Vec<T, A> as PartialEq<&[U]>>
|
||||
<Vec<T, A> as PartialEq<&mut [U]>>
|
||||
<Vec<T, A> as PartialEq<[U; N]>>
|
||||
<Vec<T, A> as PartialEq<[U]>>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
19
src/test/ui/typeck/hang-in-overflow.rs
Normal file
19
src/test/ui/typeck/hang-in-overflow.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// normalize-stderr-test "the requirement `.*`" -> "the requirement `...`"
|
||||
// normalize-stderr-test "required for `.*` to implement `.*`" -> "required for `...` to implement `...`"
|
||||
// normalize-stderr-test: ".*the full type name has been written to.*\n" -> ""
|
||||
|
||||
// Currently this fatally aborts instead of hanging.
|
||||
// Make sure at least that this doesn't turn into a hang.
|
||||
|
||||
fn f() {
|
||||
foo::<_>();
|
||||
//~^ ERROR overflow evaluating the requirement
|
||||
}
|
||||
|
||||
fn foo<B>()
|
||||
where
|
||||
Vec<[[[B; 1]; 1]; 1]>: PartialEq<B>,
|
||||
{
|
||||
}
|
||||
|
||||
fn main() {}
|
22
src/test/ui/typeck/hang-in-overflow.stderr
Normal file
22
src/test/ui/typeck/hang-in-overflow.stderr
Normal file
|
@ -0,0 +1,22 @@
|
|||
error[E0275]: overflow evaluating the requirement `...`
|
||||
--> $DIR/hang-in-overflow.rs:9:5
|
||||
|
|
||||
LL | foo::<_>();
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`hang_in_overflow`)
|
||||
= note: required for `...` to implement `...`
|
||||
= note: 127 redundant requirements hidden
|
||||
= note: required for `...` to implement `...`
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/hang-in-overflow.rs:15:28
|
||||
|
|
||||
LL | fn foo<B>()
|
||||
| --- required by a bound in this
|
||||
LL | where
|
||||
LL | Vec<[[[B; 1]; 1]; 1]>: PartialEq<B>,
|
||||
| ^^^^^^^^^^^^ required by this bound in `foo`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
Loading…
Add table
Reference in a new issue