Auto merge of #105425 - matthiaskrgr:rollup-3ngvxmt, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #105267 (Don't ICE in ExprUseVisitor on FRU for non-existent struct) - #105343 (Simplify attribute handling in rustc_ast_lowering) - #105368 (Remove more `ref` patterns from the compiler) - #105400 (normalize before handling simple checks for evaluatability of `ty::Const`) - #105403 (rustdoc: simplify CSS selectors for item table `.stab`) - #105418 (fix: remove hack from link.rs) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f5418b09e8
50 changed files with 536 additions and 561 deletions
|
@ -436,18 +436,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let lhs = self.lower_cond(lhs);
|
let lhs = self.lower_cond(lhs);
|
||||||
let rhs = self.lower_cond(rhs);
|
let rhs = self.lower_cond(rhs);
|
||||||
|
|
||||||
self.arena.alloc(self.expr(
|
self.arena.alloc(self.expr(cond.span, hir::ExprKind::Binary(op, lhs, rhs)))
|
||||||
cond.span,
|
|
||||||
hir::ExprKind::Binary(op, lhs, rhs),
|
|
||||||
AttrVec::new(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
ExprKind::Let(..) => self.lower_expr(cond),
|
ExprKind::Let(..) => self.lower_expr(cond),
|
||||||
_ => {
|
_ => {
|
||||||
let cond = self.lower_expr(cond);
|
let cond = self.lower_expr(cond);
|
||||||
let reason = DesugaringKind::CondTemporary;
|
let reason = DesugaringKind::CondTemporary;
|
||||||
let span_block = self.mark_span_with_reason(reason, cond.span, None);
|
let span_block = self.mark_span_with_reason(reason, cond.span, None);
|
||||||
self.expr_drop_temps(span_block, cond, AttrVec::new())
|
self.expr_drop_temps(span_block, cond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,12 +473,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
) -> hir::ExprKind<'hir> {
|
) -> hir::ExprKind<'hir> {
|
||||||
let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond));
|
let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond));
|
||||||
let then = self.lower_block_expr(body);
|
let then = self.lower_block_expr(body);
|
||||||
let expr_break = self.expr_break(span, AttrVec::new());
|
let expr_break = self.expr_break(span);
|
||||||
let stmt_break = self.stmt_expr(span, expr_break);
|
let stmt_break = self.stmt_expr(span, expr_break);
|
||||||
let else_blk = self.block_all(span, arena_vec![self; stmt_break], None);
|
let else_blk = self.block_all(span, arena_vec![self; stmt_break], None);
|
||||||
let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new()));
|
let else_expr = self.arena.alloc(self.expr_block(else_blk));
|
||||||
let if_kind = hir::ExprKind::If(lowered_cond, self.arena.alloc(then), Some(else_expr));
|
let if_kind = hir::ExprKind::If(lowered_cond, self.arena.alloc(then), Some(else_expr));
|
||||||
let if_expr = self.expr(span, if_kind, AttrVec::new());
|
let if_expr = self.expr(span, if_kind);
|
||||||
let block = self.block_expr(self.arena.alloc(if_expr));
|
let block = self.block_expr(self.arena.alloc(if_expr));
|
||||||
let span = self.lower_span(span.with_hi(cond.span.hi()));
|
let span = self.lower_span(span.with_hi(cond.span.hi()));
|
||||||
let opt_label = self.lower_label(opt_label);
|
let opt_label = self.lower_label(opt_label);
|
||||||
|
@ -538,12 +534,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
expr: &'hir hir::Expr<'hir>,
|
expr: &'hir hir::Expr<'hir>,
|
||||||
overall_span: Span,
|
overall_span: Span,
|
||||||
) -> &'hir hir::Expr<'hir> {
|
) -> &'hir hir::Expr<'hir> {
|
||||||
let constructor = self.arena.alloc(self.expr_lang_item_path(
|
let constructor = self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, None));
|
||||||
method_span,
|
|
||||||
lang_item,
|
|
||||||
AttrVec::new(),
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
|
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,12 +706,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
// E0700 in src/test/ui/self/self_lifetime-async.rs
|
// E0700 in src/test/ui/self/self_lifetime-async.rs
|
||||||
|
|
||||||
// `future::identity_future`:
|
// `future::identity_future`:
|
||||||
let identity_future = self.expr_lang_item_path(
|
let identity_future =
|
||||||
unstable_span,
|
self.expr_lang_item_path(unstable_span, hir::LangItem::IdentityFuture, None);
|
||||||
hir::LangItem::IdentityFuture,
|
|
||||||
AttrVec::new(),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
// `future::identity_future(generator)`:
|
// `future::identity_future(generator)`:
|
||||||
hir::ExprKind::Call(self.arena.alloc(identity_future), arena_vec![self; generator])
|
hir::ExprKind::Call(self.arena.alloc(identity_future), arena_vec![self; generator])
|
||||||
|
@ -817,7 +804,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let break_x = self.with_loop_scope(loop_node_id, move |this| {
|
let break_x = self.with_loop_scope(loop_node_id, move |this| {
|
||||||
let expr_break =
|
let expr_break =
|
||||||
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
|
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
|
||||||
this.arena.alloc(this.expr(gen_future_span, expr_break, AttrVec::new()))
|
this.arena.alloc(this.expr(gen_future_span, expr_break))
|
||||||
});
|
});
|
||||||
self.arm(ready_pat, break_x)
|
self.arm(ready_pat, break_x)
|
||||||
};
|
};
|
||||||
|
@ -850,17 +837,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let yield_expr = self.expr(
|
let yield_expr = self.expr(
|
||||||
span,
|
span,
|
||||||
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
|
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
|
||||||
AttrVec::new(),
|
|
||||||
);
|
);
|
||||||
let yield_expr = self.arena.alloc(yield_expr);
|
let yield_expr = self.arena.alloc(yield_expr);
|
||||||
|
|
||||||
if let Some(task_context_hid) = self.task_context {
|
if let Some(task_context_hid) = self.task_context {
|
||||||
let lhs = self.expr_ident(span, task_context_ident, task_context_hid);
|
let lhs = self.expr_ident(span, task_context_ident, task_context_hid);
|
||||||
let assign = self.expr(
|
let assign =
|
||||||
span,
|
self.expr(span, hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)));
|
||||||
hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)),
|
|
||||||
AttrVec::new(),
|
|
||||||
);
|
|
||||||
self.stmt_expr(span, assign)
|
self.stmt_expr(span, assign)
|
||||||
} else {
|
} else {
|
||||||
// Use of `await` outside of an async context. Return `yield_expr` so that we can
|
// Use of `await` outside of an async context. Return `yield_expr` so that we can
|
||||||
|
@ -1044,7 +1027,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::AsyncGeneratorKind::Closure,
|
hir::AsyncGeneratorKind::Closure,
|
||||||
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
|
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
|
||||||
);
|
);
|
||||||
this.expr(fn_decl_span, async_body, AttrVec::new())
|
this.expr(fn_decl_span, async_body)
|
||||||
});
|
});
|
||||||
body_id
|
body_id
|
||||||
});
|
});
|
||||||
|
@ -1304,7 +1287,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let ident = self.expr_ident(lhs.span, ident, binding);
|
let ident = self.expr_ident(lhs.span, ident, binding);
|
||||||
let assign =
|
let assign =
|
||||||
hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span));
|
hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span));
|
||||||
let expr = self.expr(lhs.span, assign, AttrVec::new());
|
let expr = self.expr(lhs.span, assign);
|
||||||
assignments.push(self.stmt_expr(lhs.span, expr));
|
assignments.push(self.stmt_expr(lhs.span, expr));
|
||||||
pat
|
pat
|
||||||
}
|
}
|
||||||
|
@ -1345,8 +1328,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let e2 = self.lower_expr_mut(e2);
|
let e2 = self.lower_expr_mut(e2);
|
||||||
let fn_path =
|
let fn_path =
|
||||||
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
|
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
|
||||||
let fn_expr =
|
let fn_expr = self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path)));
|
||||||
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new()));
|
|
||||||
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
|
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1518,8 +1500,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|
|
||||||
// `None => break`
|
// `None => break`
|
||||||
let none_arm = {
|
let none_arm = {
|
||||||
let break_expr =
|
let break_expr = self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span));
|
||||||
self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, AttrVec::new()));
|
|
||||||
let pat = self.pat_none(for_span);
|
let pat = self.pat_none(for_span);
|
||||||
self.arm(pat, break_expr)
|
self.arm(pat, break_expr)
|
||||||
};
|
};
|
||||||
|
@ -1528,7 +1509,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let some_arm = {
|
let some_arm = {
|
||||||
let some_pat = self.pat_some(pat_span, pat);
|
let some_pat = self.pat_some(pat_span, pat);
|
||||||
let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
|
let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
|
||||||
let body_expr = self.arena.alloc(self.expr_block(body_block, AttrVec::new()));
|
let body_expr = self.arena.alloc(self.expr_block(body_block));
|
||||||
self.arm(some_pat, body_expr)
|
self.arm(some_pat, body_expr)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1591,7 +1572,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
// surrounding scope of the `match` since the `match` is not a terminating scope.
|
// surrounding scope of the `match` since the `match` is not a terminating scope.
|
||||||
//
|
//
|
||||||
// Also, add the attributes to the outer returned expr node.
|
// Also, add the attributes to the outer returned expr node.
|
||||||
self.expr_drop_temps_mut(for_span, match_expr, e.attrs.clone())
|
let expr = self.expr_drop_temps_mut(for_span, match_expr);
|
||||||
|
self.lower_attrs(expr.hir_id, &e.attrs);
|
||||||
|
expr
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Desugar `ExprKind::Try` from: `<expr>?` into:
|
/// Desugar `ExprKind::Try` from: `<expr>?` into:
|
||||||
|
@ -1646,12 +1629,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let continue_arm = {
|
let continue_arm = {
|
||||||
let val_ident = Ident::with_dummy_span(sym::val);
|
let val_ident = Ident::with_dummy_span(sym::val);
|
||||||
let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
|
let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
|
||||||
let val_expr = self.arena.alloc(self.expr_ident_with_attrs(
|
let val_expr = self.expr_ident(span, val_ident, val_pat_nid);
|
||||||
span,
|
self.lower_attrs(val_expr.hir_id, &attrs);
|
||||||
val_ident,
|
|
||||||
val_pat_nid,
|
|
||||||
attrs.clone(),
|
|
||||||
));
|
|
||||||
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
|
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
|
||||||
self.arm(continue_pat, val_expr)
|
self.arm(continue_pat, val_expr)
|
||||||
};
|
};
|
||||||
|
@ -1677,15 +1656,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::Destination { label: None, target_id },
|
hir::Destination { label: None, target_id },
|
||||||
Some(from_residual_expr),
|
Some(from_residual_expr),
|
||||||
),
|
),
|
||||||
attrs,
|
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
self.arena.alloc(self.expr(
|
self.arena.alloc(self.expr(try_span, hir::ExprKind::Ret(Some(from_residual_expr))))
|
||||||
try_span,
|
|
||||||
hir::ExprKind::Ret(Some(from_residual_expr)),
|
|
||||||
attrs,
|
|
||||||
))
|
|
||||||
};
|
};
|
||||||
|
self.lower_attrs(ret_expr.hir_id, &attrs);
|
||||||
|
|
||||||
let break_pat = self.pat_cf_break(try_span, residual_local);
|
let break_pat = self.pat_cf_break(try_span, residual_local);
|
||||||
self.arm(break_pat, ret_expr)
|
self.arm(break_pat, ret_expr)
|
||||||
|
@ -1750,18 +1725,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
expr: &'hir hir::Expr<'hir>,
|
expr: &'hir hir::Expr<'hir>,
|
||||||
attrs: AttrVec,
|
|
||||||
) -> &'hir hir::Expr<'hir> {
|
) -> &'hir hir::Expr<'hir> {
|
||||||
self.arena.alloc(self.expr_drop_temps_mut(span, expr, attrs))
|
self.arena.alloc(self.expr_drop_temps_mut(span, expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn expr_drop_temps_mut(
|
pub(super) fn expr_drop_temps_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
expr: &'hir hir::Expr<'hir>,
|
expr: &'hir hir::Expr<'hir>,
|
||||||
attrs: AttrVec,
|
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
self.expr(span, hir::ExprKind::DropTemps(expr), attrs)
|
self.expr(span, hir::ExprKind::DropTemps(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_match(
|
fn expr_match(
|
||||||
|
@ -1771,29 +1744,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
arms: &'hir [hir::Arm<'hir>],
|
arms: &'hir [hir::Arm<'hir>],
|
||||||
source: hir::MatchSource,
|
source: hir::MatchSource,
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
self.expr(span, hir::ExprKind::Match(arg, arms, source), AttrVec::new())
|
self.expr(span, hir::ExprKind::Match(arg, arms, source))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_break(&mut self, span: Span, attrs: AttrVec) -> hir::Expr<'hir> {
|
fn expr_break(&mut self, span: Span) -> hir::Expr<'hir> {
|
||||||
let expr_break = hir::ExprKind::Break(self.lower_loop_destination(None), None);
|
let expr_break = hir::ExprKind::Break(self.lower_loop_destination(None), None);
|
||||||
self.expr(span, expr_break, attrs)
|
self.expr(span, expr_break)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_break_alloc(&mut self, span: Span, attrs: AttrVec) -> &'hir hir::Expr<'hir> {
|
fn expr_break_alloc(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
|
||||||
let expr_break = self.expr_break(span, attrs);
|
let expr_break = self.expr_break(span);
|
||||||
self.arena.alloc(expr_break)
|
self.arena.alloc(expr_break)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_mut_addr_of(&mut self, span: Span, e: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
|
fn expr_mut_addr_of(&mut self, span: Span, e: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
|
||||||
self.expr(
|
self.expr(span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e))
|
||||||
span,
|
|
||||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e),
|
|
||||||
AttrVec::new(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> {
|
fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> {
|
||||||
self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), AttrVec::new()))
|
self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[])))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_call_mut(
|
fn expr_call_mut(
|
||||||
|
@ -1802,7 +1771,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
e: &'hir hir::Expr<'hir>,
|
e: &'hir hir::Expr<'hir>,
|
||||||
args: &'hir [hir::Expr<'hir>],
|
args: &'hir [hir::Expr<'hir>],
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
self.expr(span, hir::ExprKind::Call(e, args), AttrVec::new())
|
self.expr(span, hir::ExprKind::Call(e, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_call(
|
fn expr_call(
|
||||||
|
@ -1821,8 +1790,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
args: &'hir [hir::Expr<'hir>],
|
args: &'hir [hir::Expr<'hir>],
|
||||||
hir_id: Option<hir::HirId>,
|
hir_id: Option<hir::HirId>,
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
let path =
|
let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, hir_id));
|
||||||
self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id));
|
|
||||||
self.expr_call_mut(span, path, args)
|
self.expr_call_mut(span, path, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1840,13 +1808,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
attrs: AttrVec,
|
|
||||||
hir_id: Option<hir::HirId>,
|
hir_id: Option<hir::HirId>,
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
self.expr(
|
self.expr(
|
||||||
span,
|
span,
|
||||||
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)),
|
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)),
|
||||||
attrs,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1860,20 +1826,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn expr_ident_mut(
|
pub(super) fn expr_ident_mut(
|
||||||
&mut self,
|
|
||||||
sp: Span,
|
|
||||||
ident: Ident,
|
|
||||||
binding: hir::HirId,
|
|
||||||
) -> hir::Expr<'hir> {
|
|
||||||
self.expr_ident_with_attrs(sp, ident, binding, AttrVec::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expr_ident_with_attrs(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
binding: hir::HirId,
|
binding: hir::HirId,
|
||||||
attrs: AttrVec,
|
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
let hir_id = self.next_id();
|
let hir_id = self.next_id();
|
||||||
let res = Res::Local(binding);
|
let res = Res::Local(binding);
|
||||||
|
@ -1886,7 +1842,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
|
||||||
self.expr(span, expr_path, attrs)
|
self.expr(span, expr_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_unsafe(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
|
fn expr_unsafe(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
|
||||||
|
@ -1905,32 +1861,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}),
|
}),
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
AttrVec::new(),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
|
fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
|
||||||
let blk = self.block_all(span, &[], None);
|
let blk = self.block_all(span, &[], None);
|
||||||
let expr = self.expr_block(blk, AttrVec::new());
|
let expr = self.expr_block(blk);
|
||||||
self.arena.alloc(expr)
|
self.arena.alloc(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn expr_block(
|
pub(super) fn expr_block(&mut self, b: &'hir hir::Block<'hir>) -> hir::Expr<'hir> {
|
||||||
&mut self,
|
self.expr(b.span, hir::ExprKind::Block(b, None))
|
||||||
b: &'hir hir::Block<'hir>,
|
|
||||||
attrs: AttrVec,
|
|
||||||
) -> hir::Expr<'hir> {
|
|
||||||
self.expr(b.span, hir::ExprKind::Block(b, None), attrs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn expr(
|
pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind<'hir>) -> hir::Expr<'hir> {
|
||||||
&mut self,
|
|
||||||
span: Span,
|
|
||||||
kind: hir::ExprKind<'hir>,
|
|
||||||
attrs: AttrVec,
|
|
||||||
) -> hir::Expr<'hir> {
|
|
||||||
let hir_id = self.next_id();
|
let hir_id = self.next_id();
|
||||||
self.lower_attrs(hir_id, &attrs);
|
|
||||||
hir::Expr { hir_id, kind, span: self.lower_span(span) }
|
hir::Expr { hir_id, kind, span: self.lower_span(span) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -796,7 +796,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|
|
||||||
/// Construct `ExprKind::Err` for the given `span`.
|
/// Construct `ExprKind::Err` for the given `span`.
|
||||||
pub(crate) fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
|
pub(crate) fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
|
||||||
self.expr(span, hir::ExprKind::Err, AttrVec::new())
|
self.expr(span, hir::ExprKind::Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
|
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
|
||||||
|
@ -1151,11 +1151,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
// Transform into `drop-temps { <user-body> }`, an expression:
|
// Transform into `drop-temps { <user-body> }`, an expression:
|
||||||
let desugared_span =
|
let desugared_span =
|
||||||
this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
|
this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
|
||||||
let user_body = this.expr_drop_temps(
|
let user_body =
|
||||||
desugared_span,
|
this.expr_drop_temps(desugared_span, this.arena.alloc(user_body));
|
||||||
this.arena.alloc(user_body),
|
|
||||||
AttrVec::new(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// As noted above, create the final block like
|
// As noted above, create the final block like
|
||||||
//
|
//
|
||||||
|
@ -1172,14 +1169,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
Some(user_body),
|
Some(user_body),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.expr_block(body, AttrVec::new())
|
this.expr_block(body)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(this.arena.alloc_from_iter(parameters), this.expr(body.span, async_expr))
|
||||||
this.arena.alloc_from_iter(parameters),
|
|
||||||
this.expr(body.span, async_expr, AttrVec::new()),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2291,7 +2291,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
/// has no attributes and is not targeted by a `break`.
|
/// has no attributes and is not targeted by a `break`.
|
||||||
fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
|
fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
|
||||||
let block = self.lower_block(b, false);
|
let block = self.lower_block(b, false);
|
||||||
self.expr_block(block, AttrVec::new())
|
self.expr_block(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
|
fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
|
||||||
|
|
|
@ -277,8 +277,7 @@ where
|
||||||
allowed_through_unstable_modules = true;
|
allowed_through_unstable_modules = true;
|
||||||
}
|
}
|
||||||
// attributes with data
|
// attributes with data
|
||||||
else if let Some(MetaItem { kind: MetaItemKind::List(ref metas), .. }) = meta {
|
else if let Some(meta @ MetaItem { kind: MetaItemKind::List(metas), .. }) = &meta {
|
||||||
let meta = meta.as_ref().unwrap();
|
|
||||||
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
|
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
|
||||||
if item.is_some() {
|
if item.is_some() {
|
||||||
handle_errors(
|
handle_errors(
|
||||||
|
@ -533,27 +532,26 @@ where
|
||||||
|
|
||||||
// Merge the const-unstable info into the stability info
|
// Merge the const-unstable info into the stability info
|
||||||
if promotable {
|
if promotable {
|
||||||
if let Some((ref mut stab, _)) = const_stab {
|
match &mut const_stab {
|
||||||
stab.promotable = promotable;
|
Some((stab, _)) => stab.promotable = promotable,
|
||||||
} else {
|
_ => _ = sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }),
|
||||||
sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if allowed_through_unstable_modules {
|
if allowed_through_unstable_modules {
|
||||||
if let Some((
|
match &mut stab {
|
||||||
|
Some((
|
||||||
Stability {
|
Stability {
|
||||||
level: StabilityLevel::Stable { ref mut allowed_through_unstable_modules, .. },
|
level: StabilityLevel::Stable { allowed_through_unstable_modules, .. },
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
_,
|
_,
|
||||||
)) = stab
|
)) => *allowed_through_unstable_modules = true,
|
||||||
{
|
_ => {
|
||||||
*allowed_through_unstable_modules = true;
|
|
||||||
} else {
|
|
||||||
sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp });
|
sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(stab, const_stab, body_stab)
|
(stab, const_stab, body_stab)
|
||||||
}
|
}
|
||||||
|
@ -654,8 +652,8 @@ pub fn eval_condition(
|
||||||
features: Option<&Features>,
|
features: Option<&Features>,
|
||||||
eval: &mut impl FnMut(Condition) -> bool,
|
eval: &mut impl FnMut(Condition) -> bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match cfg.kind {
|
match &cfg.kind {
|
||||||
ast::MetaItemKind::List(ref mis) if cfg.name_or_empty() == sym::version => {
|
ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => {
|
||||||
try_gate_cfg(sym::version, cfg.span, sess, features);
|
try_gate_cfg(sym::version, cfg.span, sess, features);
|
||||||
let (min_version, span) = match &mis[..] {
|
let (min_version, span) = match &mis[..] {
|
||||||
[NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
[NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
||||||
|
@ -688,7 +686,7 @@ pub fn eval_condition(
|
||||||
rustc_version >= min_version
|
rustc_version >= min_version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::MetaItemKind::List(ref mis) => {
|
ast::MetaItemKind::List(mis) => {
|
||||||
for mi in mis.iter() {
|
for mi in mis.iter() {
|
||||||
if !mi.is_meta_item() {
|
if !mi.is_meta_item() {
|
||||||
handle_errors(
|
handle_errors(
|
||||||
|
@ -759,7 +757,7 @@ pub fn eval_condition(
|
||||||
sess.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span });
|
sess.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span });
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => {
|
MetaItemKind::NameValue(lit) if !lit.kind.is_str() => {
|
||||||
handle_errors(
|
handle_errors(
|
||||||
sess,
|
sess,
|
||||||
lit.span,
|
lit.span,
|
||||||
|
@ -1036,7 +1034,8 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if let Some(meta_item) = item.meta_item() {
|
} else if let Some(meta_item) = item.meta_item() {
|
||||||
if let MetaItemKind::NameValue(ref value) = meta_item.kind {
|
match &meta_item.kind {
|
||||||
|
MetaItemKind::NameValue(value) => {
|
||||||
if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) {
|
if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) {
|
||||||
let name = meta_item.name_or_empty().to_ident_string();
|
let name = meta_item.name_or_empty().to_ident_string();
|
||||||
recognised = true;
|
recognised = true;
|
||||||
|
@ -1060,7 +1059,8 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
||||||
name: meta_item.name_or_empty().to_ident_string(),
|
name: meta_item.name_or_empty().to_ident_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if let MetaItemKind::List(_) = meta_item.kind {
|
}
|
||||||
|
MetaItemKind::List(_) => {
|
||||||
if meta_item.has_name(sym::align) {
|
if meta_item.has_name(sym::align) {
|
||||||
recognised = true;
|
recognised = true;
|
||||||
sess.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
|
sess.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
|
||||||
|
@ -1068,9 +1068,11 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
||||||
});
|
});
|
||||||
} else if meta_item.has_name(sym::packed) {
|
} else if meta_item.has_name(sym::packed) {
|
||||||
recognised = true;
|
recognised = true;
|
||||||
sess.emit_err(session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
|
sess.emit_err(
|
||||||
|
session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
|
||||||
span: meta_item.span,
|
span: meta_item.span,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
} else if matches!(
|
} else if matches!(
|
||||||
meta_item.name_or_empty(),
|
meta_item.name_or_empty(),
|
||||||
sym::C | sym::simd | sym::transparent
|
sym::C | sym::simd | sym::transparent
|
||||||
|
@ -1083,6 +1085,8 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !recognised {
|
if !recognised {
|
||||||
// Not a word we recognize. This will be caught and reported by
|
// Not a word we recognize. This will be caught and reported by
|
||||||
|
|
|
@ -198,7 +198,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
|
||||||
rvalue: &mir::Rvalue<'tcx>,
|
rvalue: &mir::Rvalue<'tcx>,
|
||||||
location: mir::Location,
|
location: mir::Location,
|
||||||
) {
|
) {
|
||||||
if let mir::Rvalue::Ref(region, kind, ref borrowed_place) = *rvalue {
|
if let &mir::Rvalue::Ref(region, kind, borrowed_place) = rvalue {
|
||||||
if borrowed_place.ignore_borrow(self.tcx, self.body, &self.locals_state_at_exit) {
|
if borrowed_place.ignore_borrow(self.tcx, self.body, &self.locals_state_at_exit) {
|
||||||
debug!("ignoring_borrow of {:?}", borrowed_place);
|
debug!("ignoring_borrow of {:?}", borrowed_place);
|
||||||
return;
|
return;
|
||||||
|
@ -211,7 +211,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
|
||||||
region,
|
region,
|
||||||
reserve_location: location,
|
reserve_location: location,
|
||||||
activation_location: TwoPhaseActivation::NotTwoPhase,
|
activation_location: TwoPhaseActivation::NotTwoPhase,
|
||||||
borrowed_place: *borrowed_place,
|
borrowed_place,
|
||||||
assigned_place: *assigned_place,
|
assigned_place: *assigned_place,
|
||||||
};
|
};
|
||||||
let (idx, _) = self.location_map.insert_full(location, borrow);
|
let (idx, _) = self.location_map.insert_full(location, borrow);
|
||||||
|
@ -273,14 +273,14 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: mir::Location) {
|
fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: mir::Location) {
|
||||||
if let mir::Rvalue::Ref(region, kind, ref place) = *rvalue {
|
if let &mir::Rvalue::Ref(region, kind, place) = rvalue {
|
||||||
// double-check that we already registered a BorrowData for this
|
// double-check that we already registered a BorrowData for this
|
||||||
|
|
||||||
let borrow_data = &self.location_map[&location];
|
let borrow_data = &self.location_map[&location];
|
||||||
assert_eq!(borrow_data.reserve_location, location);
|
assert_eq!(borrow_data.reserve_location, location);
|
||||||
assert_eq!(borrow_data.kind, kind);
|
assert_eq!(borrow_data.kind, kind);
|
||||||
assert_eq!(borrow_data.region, region.to_region_vid());
|
assert_eq!(borrow_data.region, region.to_region_vid());
|
||||||
assert_eq!(borrow_data.borrowed_place, *place);
|
assert_eq!(borrow_data.borrowed_place, place);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.super_rvalue(rvalue, location)
|
self.super_rvalue(rvalue, location)
|
||||||
|
|
|
@ -358,9 +358,9 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
|
||||||
stmt: &mir::Statement<'tcx>,
|
stmt: &mir::Statement<'tcx>,
|
||||||
location: Location,
|
location: Location,
|
||||||
) {
|
) {
|
||||||
match stmt.kind {
|
match &stmt.kind {
|
||||||
mir::StatementKind::Assign(box (lhs, ref rhs)) => {
|
mir::StatementKind::Assign(box (lhs, rhs)) => {
|
||||||
if let mir::Rvalue::Ref(_, _, place) = *rhs {
|
if let mir::Rvalue::Ref(_, _, place) = rhs {
|
||||||
if place.ignore_borrow(
|
if place.ignore_borrow(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
self.body,
|
self.body,
|
||||||
|
@ -377,13 +377,13 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
|
||||||
|
|
||||||
// Make sure there are no remaining borrows for variables
|
// Make sure there are no remaining borrows for variables
|
||||||
// that are assigned over.
|
// that are assigned over.
|
||||||
self.kill_borrows_on_place(trans, lhs);
|
self.kill_borrows_on_place(trans, *lhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
mir::StatementKind::StorageDead(local) => {
|
mir::StatementKind::StorageDead(local) => {
|
||||||
// Make sure there are no remaining borrows for locals that
|
// Make sure there are no remaining borrows for locals that
|
||||||
// are gone out of scope.
|
// are gone out of scope.
|
||||||
self.kill_borrows_on_place(trans, Place::from(local));
|
self.kill_borrows_on_place(trans, Place::from(*local));
|
||||||
}
|
}
|
||||||
|
|
||||||
mir::StatementKind::FakeRead(..)
|
mir::StatementKind::FakeRead(..)
|
||||||
|
|
|
@ -243,9 +243,9 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
|
||||||
placeholder_region: ty::Region<'tcx>,
|
placeholder_region: ty::Region<'tcx>,
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
error_region: Option<ty::Region<'tcx>>,
|
||||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||||
let (ref infcx, key, _) =
|
let (infcx, key, _) =
|
||||||
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
||||||
let ocx = ObligationCtxt::new(infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
type_op_prove_predicate_with_cause(&ocx, key, cause);
|
type_op_prove_predicate_with_cause(&ocx, key, cause);
|
||||||
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
|
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
|
||||||
}
|
}
|
||||||
|
@ -284,9 +284,9 @@ where
|
||||||
placeholder_region: ty::Region<'tcx>,
|
placeholder_region: ty::Region<'tcx>,
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
error_region: Option<ty::Region<'tcx>>,
|
||||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||||
let (ref infcx, key, _) =
|
let (infcx, key, _) =
|
||||||
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
||||||
let ocx = ObligationCtxt::new(infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
|
|
||||||
// FIXME(lqd): Unify and de-duplicate the following with the actual
|
// FIXME(lqd): Unify and de-duplicate the following with the actual
|
||||||
// `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the
|
// `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the
|
||||||
|
@ -328,9 +328,9 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
|
||||||
placeholder_region: ty::Region<'tcx>,
|
placeholder_region: ty::Region<'tcx>,
|
||||||
error_region: Option<ty::Region<'tcx>>,
|
error_region: Option<ty::Region<'tcx>>,
|
||||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||||
let (ref infcx, key, _) =
|
let (infcx, key, _) =
|
||||||
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
||||||
let ocx = ObligationCtxt::new(infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
|
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
|
||||||
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
|
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,7 +265,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
|
DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
|
||||||
);
|
);
|
||||||
let note_msg = match opt_name {
|
let note_msg = match opt_name {
|
||||||
Some(ref name) => format!("`{}`", name),
|
Some(name) => format!("`{}`", name),
|
||||||
None => "value".to_owned(),
|
None => "value".to_owned(),
|
||||||
};
|
};
|
||||||
if self.suggest_borrow_fn_like(&mut err, ty, &move_site_vec, ¬e_msg) {
|
if self.suggest_borrow_fn_like(&mut err, ty, &move_site_vec, ¬e_msg) {
|
||||||
|
@ -1417,7 +1417,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// then just use the normal error. The closure isn't escaping
|
// then just use the normal error. The closure isn't escaping
|
||||||
// and `move` will not help here.
|
// and `move` will not help here.
|
||||||
(
|
(
|
||||||
Some(ref name),
|
Some(name),
|
||||||
BorrowExplanation::MustBeValidFor {
|
BorrowExplanation::MustBeValidFor {
|
||||||
category:
|
category:
|
||||||
category @ (ConstraintCategory::Return(_)
|
category @ (ConstraintCategory::Return(_)
|
||||||
|
@ -1438,7 +1438,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
&format!("`{}`", name),
|
&format!("`{}`", name),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
ref name,
|
name,
|
||||||
BorrowExplanation::MustBeValidFor {
|
BorrowExplanation::MustBeValidFor {
|
||||||
category: ConstraintCategory::Assignment,
|
category: ConstraintCategory::Assignment,
|
||||||
from_closure: false,
|
from_closure: false,
|
||||||
|
@ -1450,7 +1450,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
span,
|
span,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
) => self.report_escaping_data(borrow_span, name, upvar_span, upvar_name, span),
|
) => self.report_escaping_data(borrow_span, &name, upvar_span, upvar_name, span),
|
||||||
(Some(name), explanation) => self.report_local_value_does_not_live_long_enough(
|
(Some(name), explanation) => self.report_local_value_does_not_live_long_enough(
|
||||||
location,
|
location,
|
||||||
&name,
|
&name,
|
||||||
|
@ -2452,7 +2452,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// and it'll make sense.
|
// and it'll make sense.
|
||||||
let location = borrow.reserve_location;
|
let location = borrow.reserve_location;
|
||||||
debug!("annotate_argument_and_return_for_borrow: location={:?}", location);
|
debug!("annotate_argument_and_return_for_borrow: location={:?}", location);
|
||||||
if let Some(&Statement { kind: StatementKind::Assign(box (ref reservation, _)), .. }) =
|
if let Some(Statement { kind: StatementKind::Assign(box (reservation, _)), .. }) =
|
||||||
&self.body[location.block].statements.get(location.statement_index)
|
&self.body[location.block].statements.get(location.statement_index)
|
||||||
{
|
{
|
||||||
debug!("annotate_argument_and_return_for_borrow: reservation={:?}", reservation);
|
debug!("annotate_argument_and_return_for_borrow: reservation={:?}", reservation);
|
||||||
|
@ -2480,8 +2480,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// Check if our `target` was captured by a closure.
|
// Check if our `target` was captured by a closure.
|
||||||
if let Rvalue::Aggregate(
|
if let Rvalue::Aggregate(
|
||||||
box AggregateKind::Closure(def_id, substs),
|
box AggregateKind::Closure(def_id, substs),
|
||||||
ref operands,
|
operands,
|
||||||
) = *rvalue
|
) = rvalue
|
||||||
{
|
{
|
||||||
for operand in operands {
|
for operand in operands {
|
||||||
let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) = operand else {
|
let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) = operand else {
|
||||||
|
@ -2505,7 +2505,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// into a place then we should annotate the closure in
|
// into a place then we should annotate the closure in
|
||||||
// case it ends up being assigned into the return place.
|
// case it ends up being assigned into the return place.
|
||||||
annotated_closure =
|
annotated_closure =
|
||||||
self.annotate_fn_sig(def_id, substs.as_closure().sig());
|
self.annotate_fn_sig(*def_id, substs.as_closure().sig());
|
||||||
debug!(
|
debug!(
|
||||||
"annotate_argument_and_return_for_borrow: \
|
"annotate_argument_and_return_for_borrow: \
|
||||||
annotated_closure={:?} assigned_from_local={:?} \
|
annotated_closure={:?} assigned_from_local={:?} \
|
||||||
|
|
|
@ -469,8 +469,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
} else if self.was_captured_by_trait_object(borrow) {
|
} else if self.was_captured_by_trait_object(borrow) {
|
||||||
LaterUseKind::TraitCapture
|
LaterUseKind::TraitCapture
|
||||||
} else if location.statement_index == block.statements.len() {
|
} else if location.statement_index == block.statements.len() {
|
||||||
if let TerminatorKind::Call { ref func, from_hir_call: true, .. } =
|
if let TerminatorKind::Call { func, from_hir_call: true, .. } =
|
||||||
block.terminator().kind
|
&block.terminator().kind
|
||||||
{
|
{
|
||||||
// Just point to the function, to reduce the chance of overlapping spans.
|
// Just point to the function, to reduce the chance of overlapping spans.
|
||||||
let function_span = match func {
|
let function_span = match func {
|
||||||
|
@ -515,11 +515,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// will only ever have one item at any given time, but by using a vector, we can pop from
|
// will only ever have one item at any given time, but by using a vector, we can pop from
|
||||||
// it which simplifies the termination logic.
|
// it which simplifies the termination logic.
|
||||||
let mut queue = vec![location];
|
let mut queue = vec![location];
|
||||||
let mut target = if let Some(&Statement {
|
let mut target =
|
||||||
kind: StatementKind::Assign(box (ref place, _)),
|
if let Some(Statement { kind: StatementKind::Assign(box (place, _)), .. }) = stmt {
|
||||||
..
|
|
||||||
}) = stmt
|
|
||||||
{
|
|
||||||
if let Some(local) = place.as_local() {
|
if let Some(local) = place.as_local() {
|
||||||
local
|
local
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -78,7 +78,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
if let StatementKind::Assign(box (into, Rvalue::Use(from))) = &stmt.kind {
|
if let StatementKind::Assign(box (into, Rvalue::Use(from))) = &stmt.kind {
|
||||||
debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from);
|
debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from);
|
||||||
match from {
|
match from {
|
||||||
Operand::Copy(ref place) | Operand::Move(ref place)
|
Operand::Copy(place) | Operand::Move(place)
|
||||||
if target == place.local_or_deref_local() =>
|
if target == place.local_or_deref_local() =>
|
||||||
{
|
{
|
||||||
target = into.local_or_deref_local()
|
target = into.local_or_deref_local()
|
||||||
|
@ -101,7 +101,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
debug!("add_moved_or_invoked_closure_note: id={:?}", id);
|
debug!("add_moved_or_invoked_closure_note: id={:?}", id);
|
||||||
if Some(self.infcx.tcx.parent(id)) == self.infcx.tcx.lang_items().fn_once_trait() {
|
if Some(self.infcx.tcx.parent(id)) == self.infcx.tcx.lang_items().fn_once_trait() {
|
||||||
let closure = match args.first() {
|
let closure = match args.first() {
|
||||||
Some(Operand::Copy(ref place)) | Some(Operand::Move(ref place))
|
Some(Operand::Copy(place) | Operand::Move(place))
|
||||||
if target == place.local_or_deref_local() =>
|
if target == place.local_or_deref_local() =>
|
||||||
{
|
{
|
||||||
place.local_or_deref_local().unwrap()
|
place.local_or_deref_local().unwrap()
|
||||||
|
@ -439,9 +439,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
if !is_terminator {
|
if !is_terminator {
|
||||||
continue;
|
continue;
|
||||||
} else if let Some(Terminator {
|
} else if let Some(Terminator {
|
||||||
kind: TerminatorKind::Call { ref func, from_hir_call: false, .. },
|
kind: TerminatorKind::Call { func, from_hir_call: false, .. },
|
||||||
..
|
..
|
||||||
}) = bbd.terminator
|
}) = &bbd.terminator
|
||||||
{
|
{
|
||||||
if let Some(source) =
|
if let Some(source) =
|
||||||
BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx)
|
BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx)
|
||||||
|
@ -811,9 +811,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
|
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
|
||||||
if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) = stmt.kind {
|
if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind
|
||||||
match **kind {
|
&& let AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) = **kind
|
||||||
AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) => {
|
{
|
||||||
debug!("move_spans: def_id={:?} places={:?}", def_id, places);
|
debug!("move_spans: def_id={:?} places={:?}", def_id, places);
|
||||||
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
||||||
self.closure_span(def_id, moved_place, places)
|
self.closure_span(def_id, moved_place, places)
|
||||||
|
@ -826,18 +826,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatementKind::FakeRead only contains a def_id if they are introduced as a result
|
// StatementKind::FakeRead only contains a def_id if they are introduced as a result
|
||||||
// of pattern matching within a closure.
|
// of pattern matching within a closure.
|
||||||
if let StatementKind::FakeRead(box (cause, ref place)) = stmt.kind {
|
if let StatementKind::FakeRead(box (cause, place)) = stmt.kind {
|
||||||
match cause {
|
match cause {
|
||||||
FakeReadCause::ForMatchedPlace(Some(closure_def_id))
|
FakeReadCause::ForMatchedPlace(Some(closure_def_id))
|
||||||
| FakeReadCause::ForLet(Some(closure_def_id)) => {
|
| FakeReadCause::ForLet(Some(closure_def_id)) => {
|
||||||
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place);
|
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place);
|
||||||
let places = &[Operand::Move(*place)];
|
let places = &[Operand::Move(place)];
|
||||||
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
||||||
self.closure_span(closure_def_id, moved_place, places)
|
self.closure_span(closure_def_id, moved_place, places)
|
||||||
{
|
{
|
||||||
|
@ -924,7 +921,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
debug!("borrow_spans: use_span={:?} location={:?}", use_span, location);
|
debug!("borrow_spans: use_span={:?} location={:?}", use_span, location);
|
||||||
|
|
||||||
let target = match self.body[location.block].statements.get(location.statement_index) {
|
let target = match self.body[location.block].statements.get(location.statement_index) {
|
||||||
Some(&Statement { kind: StatementKind::Assign(box (ref place, _)), .. }) => {
|
Some(Statement { kind: StatementKind::Assign(box (place, _)), .. }) => {
|
||||||
if let Some(local) = place.as_local() {
|
if let Some(local) = place.as_local() {
|
||||||
local
|
local
|
||||||
} else {
|
} else {
|
||||||
|
@ -940,9 +937,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
|
for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
|
||||||
if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) =
|
if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind {
|
||||||
stmt.kind
|
|
||||||
{
|
|
||||||
let (&def_id, is_generator) = match kind {
|
let (&def_id, is_generator) = match kind {
|
||||||
box AggregateKind::Closure(def_id, _) => (def_id, false),
|
box AggregateKind::Closure(def_id, _) => (def_id, false),
|
||||||
box AggregateKind::Generator(def_id, _, _) => (def_id, true),
|
box AggregateKind::Generator(def_id, _, _) => (def_id, true),
|
||||||
|
|
|
@ -219,8 +219,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
PlaceRef {
|
PlaceRef {
|
||||||
local,
|
local,
|
||||||
projection:
|
projection:
|
||||||
&[
|
[
|
||||||
ref proj_base @ ..,
|
proj_base @ ..,
|
||||||
ProjectionElem::Deref,
|
ProjectionElem::Deref,
|
||||||
ProjectionElem::Field(field, _),
|
ProjectionElem::Field(field, _),
|
||||||
ProjectionElem::Deref,
|
ProjectionElem::Deref,
|
||||||
|
@ -231,7 +231,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
if let Some(span) = get_mut_span_in_struct_field(
|
if let Some(span) = get_mut_span_in_struct_field(
|
||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty,
|
Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty,
|
||||||
field,
|
*field,
|
||||||
) {
|
) {
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -921,7 +921,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ExprKind::Block(blk, _) => {
|
hir::ExprKind::Block(blk, _) => {
|
||||||
if let Some(ref expr) = blk.expr {
|
if let Some(expr) = blk.expr {
|
||||||
// only when the block is a closure
|
// only when the block is a closure
|
||||||
if let hir::ExprKind::Closure(hir::Closure {
|
if let hir::ExprKind::Closure(hir::Closure {
|
||||||
capture_clause: hir::CaptureBy::Ref,
|
capture_clause: hir::CaptureBy::Ref,
|
||||||
|
|
|
@ -254,7 +254,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
.or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr))
|
.or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr))
|
||||||
.or_else(|| self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(fr));
|
.or_else(|| self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(fr));
|
||||||
|
|
||||||
if let Some(ref value) = value {
|
if let Some(value) = &value {
|
||||||
self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
|
self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,9 +69,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||||
self.consume_operand(location, op);
|
self.consume_operand(location, op);
|
||||||
}
|
}
|
||||||
StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
|
StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
|
||||||
ref src,
|
src,
|
||||||
ref dst,
|
dst,
|
||||||
ref count,
|
count,
|
||||||
})) => {
|
})) => {
|
||||||
self.consume_operand(location, src);
|
self.consume_operand(location, src);
|
||||||
self.consume_operand(location, dst);
|
self.consume_operand(location, dst);
|
||||||
|
@ -106,7 +106,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||||
self.check_activations(location);
|
self.check_activations(location);
|
||||||
|
|
||||||
match &terminator.kind {
|
match &terminator.kind {
|
||||||
TerminatorKind::SwitchInt { ref discr, switch_ty: _, targets: _ } => {
|
TerminatorKind::SwitchInt { discr, switch_ty: _, targets: _ } => {
|
||||||
self.consume_operand(location, discr);
|
self.consume_operand(location, discr);
|
||||||
}
|
}
|
||||||
TerminatorKind::Drop { place: drop_place, target: _, unwind: _ } => {
|
TerminatorKind::Drop { place: drop_place, target: _, unwind: _ } => {
|
||||||
|
@ -119,7 +119,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
TerminatorKind::DropAndReplace {
|
TerminatorKind::DropAndReplace {
|
||||||
place: drop_place,
|
place: drop_place,
|
||||||
value: ref new_value,
|
value: new_value,
|
||||||
target: _,
|
target: _,
|
||||||
unwind: _,
|
unwind: _,
|
||||||
} => {
|
} => {
|
||||||
|
@ -127,8 +127,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||||
self.consume_operand(location, new_value);
|
self.consume_operand(location, new_value);
|
||||||
}
|
}
|
||||||
TerminatorKind::Call {
|
TerminatorKind::Call {
|
||||||
ref func,
|
func,
|
||||||
ref args,
|
args,
|
||||||
destination,
|
destination,
|
||||||
target: _,
|
target: _,
|
||||||
cleanup: _,
|
cleanup: _,
|
||||||
|
@ -141,15 +141,15 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
self.mutate_place(location, *destination, Deep);
|
self.mutate_place(location, *destination, Deep);
|
||||||
}
|
}
|
||||||
TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
|
TerminatorKind::Assert { cond, expected: _, msg, target: _, cleanup: _ } => {
|
||||||
self.consume_operand(location, cond);
|
self.consume_operand(location, cond);
|
||||||
use rustc_middle::mir::AssertKind;
|
use rustc_middle::mir::AssertKind;
|
||||||
if let AssertKind::BoundsCheck { ref len, ref index } = *msg {
|
if let AssertKind::BoundsCheck { len, index } = msg {
|
||||||
self.consume_operand(location, len);
|
self.consume_operand(location, len);
|
||||||
self.consume_operand(location, index);
|
self.consume_operand(location, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TerminatorKind::Yield { ref value, resume, resume_arg, drop: _ } => {
|
TerminatorKind::Yield { value, resume, resume_arg, drop: _ } => {
|
||||||
self.consume_operand(location, value);
|
self.consume_operand(location, value);
|
||||||
|
|
||||||
// Invalidate all borrows of local places
|
// Invalidate all borrows of local places
|
||||||
|
@ -175,25 +175,25 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
TerminatorKind::InlineAsm {
|
TerminatorKind::InlineAsm {
|
||||||
template: _,
|
template: _,
|
||||||
ref operands,
|
operands,
|
||||||
options: _,
|
options: _,
|
||||||
line_spans: _,
|
line_spans: _,
|
||||||
destination: _,
|
destination: _,
|
||||||
cleanup: _,
|
cleanup: _,
|
||||||
} => {
|
} => {
|
||||||
for op in operands {
|
for op in operands {
|
||||||
match *op {
|
match op {
|
||||||
InlineAsmOperand::In { reg: _, ref value } => {
|
InlineAsmOperand::In { reg: _, value } => {
|
||||||
self.consume_operand(location, value);
|
self.consume_operand(location, value);
|
||||||
}
|
}
|
||||||
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
|
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
|
||||||
if let Some(place) = place {
|
if let &Some(place) = place {
|
||||||
self.mutate_place(location, place, Shallow(None));
|
self.mutate_place(location, place, Shallow(None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InlineAsmOperand::InOut { reg: _, late: _, ref in_value, out_place } => {
|
InlineAsmOperand::InOut { reg: _, late: _, in_value, out_place } => {
|
||||||
self.consume_operand(location, in_value);
|
self.consume_operand(location, in_value);
|
||||||
if let Some(out_place) = out_place {
|
if let &Some(out_place) = out_place {
|
||||||
self.mutate_place(location, out_place, Shallow(None));
|
self.mutate_place(location, out_place, Shallow(None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,8 +252,8 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||||
|
|
||||||
// Simulates consumption of an rvalue
|
// Simulates consumption of an rvalue
|
||||||
fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) {
|
fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) {
|
||||||
match *rvalue {
|
match rvalue {
|
||||||
Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||||
let access_kind = match bk {
|
let access_kind = match bk {
|
||||||
BorrowKind::Shallow => {
|
BorrowKind::Shallow => {
|
||||||
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
|
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
|
||||||
|
@ -272,7 +272,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||||
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
|
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::AddressOf(mutability, place) => {
|
&Rvalue::AddressOf(mutability, place) => {
|
||||||
let access_kind = match mutability {
|
let access_kind = match mutability {
|
||||||
Mutability::Mut => (
|
Mutability::Mut => (
|
||||||
Deep,
|
Deep,
|
||||||
|
@ -288,20 +288,19 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||||
|
|
||||||
Rvalue::ThreadLocalRef(_) => {}
|
Rvalue::ThreadLocalRef(_) => {}
|
||||||
|
|
||||||
Rvalue::Use(ref operand)
|
Rvalue::Use(operand)
|
||||||
| Rvalue::Repeat(ref operand, _)
|
| Rvalue::Repeat(operand, _)
|
||||||
| Rvalue::UnaryOp(_ /*un_op*/, ref operand)
|
| Rvalue::UnaryOp(_ /*un_op*/, operand)
|
||||||
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
|
| Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
|
||||||
| Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
|
| Rvalue::ShallowInitBox(operand, _ /*ty*/) => self.consume_operand(location, operand),
|
||||||
self.consume_operand(location, operand)
|
|
||||||
}
|
&Rvalue::CopyForDeref(place) => {
|
||||||
Rvalue::CopyForDeref(ref place) => {
|
let op = &Operand::Copy(place);
|
||||||
let op = &Operand::Copy(*place);
|
|
||||||
self.consume_operand(location, op);
|
self.consume_operand(location, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::Len(place) | Rvalue::Discriminant(place) => {
|
&(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
|
||||||
let af = match *rvalue {
|
let af = match rvalue {
|
||||||
Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
|
Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
|
||||||
Rvalue::Discriminant(..) => None,
|
Rvalue::Discriminant(..) => None,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -314,15 +313,15 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::BinaryOp(_bin_op, box (ref operand1, ref operand2))
|
Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
|
||||||
| Rvalue::CheckedBinaryOp(_bin_op, box (ref operand1, ref operand2)) => {
|
| Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
|
||||||
self.consume_operand(location, operand1);
|
self.consume_operand(location, operand1);
|
||||||
self.consume_operand(location, operand2);
|
self.consume_operand(location, operand2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::NullaryOp(_op, _ty) => {}
|
Rvalue::NullaryOp(_op, _ty) => {}
|
||||||
|
|
||||||
Rvalue::Aggregate(_, ref operands) => {
|
Rvalue::Aggregate(_, operands) => {
|
||||||
for operand in operands {
|
for operand in operands {
|
||||||
self.consume_operand(location, operand);
|
self.consume_operand(location, operand);
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,12 +578,12 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||||
self.check_activations(location, span, flow_state);
|
self.check_activations(location, span, flow_state);
|
||||||
|
|
||||||
match &stmt.kind {
|
match &stmt.kind {
|
||||||
StatementKind::Assign(box (lhs, ref rhs)) => {
|
StatementKind::Assign(box (lhs, rhs)) => {
|
||||||
self.consume_rvalue(location, (rhs, span), flow_state);
|
self.consume_rvalue(location, (rhs, span), flow_state);
|
||||||
|
|
||||||
self.mutate_place(location, (*lhs, span), Shallow(None), flow_state);
|
self.mutate_place(location, (*lhs, span), Shallow(None), flow_state);
|
||||||
}
|
}
|
||||||
StatementKind::FakeRead(box (_, ref place)) => {
|
StatementKind::FakeRead(box (_, place)) => {
|
||||||
// Read for match doesn't access any memory and is used to
|
// Read for match doesn't access any memory and is used to
|
||||||
// assert that a place is safe and live. So we don't have to
|
// assert that a place is safe and live. So we don't have to
|
||||||
// do any checks here.
|
// do any checks here.
|
||||||
|
@ -601,7 +601,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
StatementKind::Intrinsic(box ref kind) => match kind {
|
StatementKind::Intrinsic(box kind) => match kind {
|
||||||
NonDivergingIntrinsic::Assume(op) => self.consume_operand(location, (op, span), flow_state),
|
NonDivergingIntrinsic::Assume(op) => self.consume_operand(location, (op, span), flow_state),
|
||||||
NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
|
NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
|
||||||
span,
|
span,
|
||||||
|
@ -643,8 +643,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||||
|
|
||||||
self.check_activations(loc, span, flow_state);
|
self.check_activations(loc, span, flow_state);
|
||||||
|
|
||||||
match term.kind {
|
match &term.kind {
|
||||||
TerminatorKind::SwitchInt { ref discr, switch_ty: _, targets: _ } => {
|
TerminatorKind::SwitchInt { discr, switch_ty: _, targets: _ } => {
|
||||||
self.consume_operand(loc, (discr, span), flow_state);
|
self.consume_operand(loc, (discr, span), flow_state);
|
||||||
}
|
}
|
||||||
TerminatorKind::Drop { place, target: _, unwind: _ } => {
|
TerminatorKind::Drop { place, target: _, unwind: _ } => {
|
||||||
|
@ -656,7 +656,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||||
|
|
||||||
self.access_place(
|
self.access_place(
|
||||||
loc,
|
loc,
|
||||||
(place, span),
|
(*place, span),
|
||||||
(AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
|
(AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
|
||||||
LocalMutationIsAllowed::Yes,
|
LocalMutationIsAllowed::Yes,
|
||||||
flow_state,
|
flow_state,
|
||||||
|
@ -664,16 +664,16 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||||
}
|
}
|
||||||
TerminatorKind::DropAndReplace {
|
TerminatorKind::DropAndReplace {
|
||||||
place: drop_place,
|
place: drop_place,
|
||||||
value: ref new_value,
|
value: new_value,
|
||||||
target: _,
|
target: _,
|
||||||
unwind: _,
|
unwind: _,
|
||||||
} => {
|
} => {
|
||||||
self.mutate_place(loc, (drop_place, span), Deep, flow_state);
|
self.mutate_place(loc, (*drop_place, span), Deep, flow_state);
|
||||||
self.consume_operand(loc, (new_value, span), flow_state);
|
self.consume_operand(loc, (new_value, span), flow_state);
|
||||||
}
|
}
|
||||||
TerminatorKind::Call {
|
TerminatorKind::Call {
|
||||||
ref func,
|
func,
|
||||||
ref args,
|
args,
|
||||||
destination,
|
destination,
|
||||||
target: _,
|
target: _,
|
||||||
cleanup: _,
|
cleanup: _,
|
||||||
|
@ -684,43 +684,43 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||||
for arg in args {
|
for arg in args {
|
||||||
self.consume_operand(loc, (arg, span), flow_state);
|
self.consume_operand(loc, (arg, span), flow_state);
|
||||||
}
|
}
|
||||||
self.mutate_place(loc, (destination, span), Deep, flow_state);
|
self.mutate_place(loc, (*destination, span), Deep, flow_state);
|
||||||
}
|
}
|
||||||
TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
|
TerminatorKind::Assert { cond, expected: _, msg, target: _, cleanup: _ } => {
|
||||||
self.consume_operand(loc, (cond, span), flow_state);
|
self.consume_operand(loc, (cond, span), flow_state);
|
||||||
use rustc_middle::mir::AssertKind;
|
use rustc_middle::mir::AssertKind;
|
||||||
if let AssertKind::BoundsCheck { ref len, ref index } = *msg {
|
if let AssertKind::BoundsCheck { len, index } = msg {
|
||||||
self.consume_operand(loc, (len, span), flow_state);
|
self.consume_operand(loc, (len, span), flow_state);
|
||||||
self.consume_operand(loc, (index, span), flow_state);
|
self.consume_operand(loc, (index, span), flow_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminatorKind::Yield { ref value, resume: _, resume_arg, drop: _ } => {
|
TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
|
||||||
self.consume_operand(loc, (value, span), flow_state);
|
self.consume_operand(loc, (value, span), flow_state);
|
||||||
self.mutate_place(loc, (resume_arg, span), Deep, flow_state);
|
self.mutate_place(loc, (*resume_arg, span), Deep, flow_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminatorKind::InlineAsm {
|
TerminatorKind::InlineAsm {
|
||||||
template: _,
|
template: _,
|
||||||
ref operands,
|
operands,
|
||||||
options: _,
|
options: _,
|
||||||
line_spans: _,
|
line_spans: _,
|
||||||
destination: _,
|
destination: _,
|
||||||
cleanup: _,
|
cleanup: _,
|
||||||
} => {
|
} => {
|
||||||
for op in operands {
|
for op in operands {
|
||||||
match *op {
|
match op {
|
||||||
InlineAsmOperand::In { reg: _, ref value } => {
|
InlineAsmOperand::In { reg: _, value } => {
|
||||||
self.consume_operand(loc, (value, span), flow_state);
|
self.consume_operand(loc, (value, span), flow_state);
|
||||||
}
|
}
|
||||||
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
|
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
|
||||||
if let Some(place) = place {
|
if let Some(place) = place {
|
||||||
self.mutate_place(loc, (place, span), Shallow(None), flow_state);
|
self.mutate_place(loc, (*place, span), Shallow(None), flow_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InlineAsmOperand::InOut { reg: _, late: _, ref in_value, out_place } => {
|
InlineAsmOperand::InOut { reg: _, late: _, in_value, out_place } => {
|
||||||
self.consume_operand(loc, (in_value, span), flow_state);
|
self.consume_operand(loc, (in_value, span), flow_state);
|
||||||
if let Some(out_place) = out_place {
|
if let &Some(out_place) = out_place {
|
||||||
self.mutate_place(
|
self.mutate_place(
|
||||||
loc,
|
loc,
|
||||||
(out_place, span),
|
(out_place, span),
|
||||||
|
@ -1164,8 +1164,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
(rvalue, span): (&'cx Rvalue<'tcx>, Span),
|
(rvalue, span): (&'cx Rvalue<'tcx>, Span),
|
||||||
flow_state: &Flows<'cx, 'tcx>,
|
flow_state: &Flows<'cx, 'tcx>,
|
||||||
) {
|
) {
|
||||||
match *rvalue {
|
match rvalue {
|
||||||
Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||||
let access_kind = match bk {
|
let access_kind = match bk {
|
||||||
BorrowKind::Shallow => {
|
BorrowKind::Shallow => {
|
||||||
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
|
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
|
||||||
|
@ -1203,7 +1203,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::AddressOf(mutability, place) => {
|
&Rvalue::AddressOf(mutability, place) => {
|
||||||
let access_kind = match mutability {
|
let access_kind = match mutability {
|
||||||
Mutability::Mut => (
|
Mutability::Mut => (
|
||||||
Deep,
|
Deep,
|
||||||
|
@ -1232,14 +1232,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
|
|
||||||
Rvalue::ThreadLocalRef(_) => {}
|
Rvalue::ThreadLocalRef(_) => {}
|
||||||
|
|
||||||
Rvalue::Use(ref operand)
|
Rvalue::Use(operand)
|
||||||
| Rvalue::Repeat(ref operand, _)
|
| Rvalue::Repeat(operand, _)
|
||||||
| Rvalue::UnaryOp(_ /*un_op*/, ref operand)
|
| Rvalue::UnaryOp(_ /*un_op*/, operand)
|
||||||
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
|
| Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
|
||||||
| Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
|
| Rvalue::ShallowInitBox(operand, _ /*ty*/) => {
|
||||||
self.consume_operand(location, (operand, span), flow_state)
|
self.consume_operand(location, (operand, span), flow_state)
|
||||||
}
|
}
|
||||||
Rvalue::CopyForDeref(place) => {
|
|
||||||
|
&Rvalue::CopyForDeref(place) => {
|
||||||
self.access_place(
|
self.access_place(
|
||||||
location,
|
location,
|
||||||
(place, span),
|
(place, span),
|
||||||
|
@ -1257,7 +1258,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::Len(place) | Rvalue::Discriminant(place) => {
|
&(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
|
||||||
let af = match *rvalue {
|
let af = match *rvalue {
|
||||||
Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
|
Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
|
||||||
Rvalue::Discriminant(..) => None,
|
Rvalue::Discriminant(..) => None,
|
||||||
|
@ -1278,8 +1279,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::BinaryOp(_bin_op, box (ref operand1, ref operand2))
|
Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
|
||||||
| Rvalue::CheckedBinaryOp(_bin_op, box (ref operand1, ref operand2)) => {
|
| Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
|
||||||
self.consume_operand(location, (operand1, span), flow_state);
|
self.consume_operand(location, (operand1, span), flow_state);
|
||||||
self.consume_operand(location, (operand2, span), flow_state);
|
self.consume_operand(location, (operand2, span), flow_state);
|
||||||
}
|
}
|
||||||
|
@ -1288,7 +1289,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// nullary ops take no dynamic input; no borrowck effect.
|
// nullary ops take no dynamic input; no borrowck effect.
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::Aggregate(ref aggregate_kind, ref operands) => {
|
Rvalue::Aggregate(aggregate_kind, operands) => {
|
||||||
// We need to report back the list of mutable upvars that were
|
// We need to report back the list of mutable upvars that were
|
||||||
// moved into the closure and subsequently used by the closure,
|
// moved into the closure and subsequently used by the closure,
|
||||||
// in order to populate our used_mut set.
|
// in order to populate our used_mut set.
|
||||||
|
|
|
@ -1189,8 +1189,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) {
|
fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
debug!("stmt kind: {:?}", stmt.kind);
|
debug!("stmt kind: {:?}", stmt.kind);
|
||||||
match stmt.kind {
|
match &stmt.kind {
|
||||||
StatementKind::Assign(box (ref place, ref rv)) => {
|
StatementKind::Assign(box (place, rv)) => {
|
||||||
// Assignments to temporaries are not "interesting";
|
// Assignments to temporaries are not "interesting";
|
||||||
// they are not caused by the user, but rather artifacts
|
// they are not caused by the user, but rather artifacts
|
||||||
// of lowering. Assignments to other sorts of places *are* interesting
|
// of lowering. Assignments to other sorts of places *are* interesting
|
||||||
|
@ -1279,11 +1279,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatementKind::AscribeUserType(box (ref place, ref projection), variance) => {
|
StatementKind::AscribeUserType(box (place, projection), variance) => {
|
||||||
let place_ty = place.ty(body, tcx).ty;
|
let place_ty = place.ty(body, tcx).ty;
|
||||||
if let Err(terr) = self.relate_type_and_user_type(
|
if let Err(terr) = self.relate_type_and_user_type(
|
||||||
place_ty,
|
place_ty,
|
||||||
variance,
|
*variance,
|
||||||
projection,
|
projection,
|
||||||
Locations::All(stmt.source_info.span),
|
Locations::All(stmt.source_info.span),
|
||||||
ConstraintCategory::TypeAnnotation,
|
ConstraintCategory::TypeAnnotation,
|
||||||
|
@ -1300,7 +1300,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatementKind::Intrinsic(box ref kind) => match kind {
|
StatementKind::Intrinsic(box kind) => match kind {
|
||||||
NonDivergingIntrinsic::Assume(op) => self.check_operand(op, location),
|
NonDivergingIntrinsic::Assume(op) => self.check_operand(op, location),
|
||||||
NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
|
NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
|
||||||
stmt.source_info.span,
|
stmt.source_info.span,
|
||||||
|
@ -1328,7 +1328,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
) {
|
) {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
debug!("terminator kind: {:?}", term.kind);
|
debug!("terminator kind: {:?}", term.kind);
|
||||||
match term.kind {
|
match &term.kind {
|
||||||
TerminatorKind::Goto { .. }
|
TerminatorKind::Goto { .. }
|
||||||
| TerminatorKind::Resume
|
| TerminatorKind::Resume
|
||||||
| TerminatorKind::Abort
|
| TerminatorKind::Abort
|
||||||
|
@ -1342,7 +1342,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
// no checks needed for these
|
// no checks needed for these
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminatorKind::DropAndReplace { ref place, ref value, target: _, unwind: _ } => {
|
TerminatorKind::DropAndReplace { place, value, target: _, unwind: _ } => {
|
||||||
let place_ty = place.ty(body, tcx).ty;
|
let place_ty = place.ty(body, tcx).ty;
|
||||||
let rv_ty = value.ty(body, tcx);
|
let rv_ty = value.ty(body, tcx);
|
||||||
|
|
||||||
|
@ -1360,13 +1360,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
|
TerminatorKind::SwitchInt { discr, switch_ty, .. } => {
|
||||||
self.check_operand(discr, term_location);
|
self.check_operand(discr, term_location);
|
||||||
|
|
||||||
let discr_ty = discr.ty(body, tcx);
|
let discr_ty = discr.ty(body, tcx);
|
||||||
if let Err(terr) = self.sub_types(
|
if let Err(terr) = self.sub_types(
|
||||||
discr_ty,
|
discr_ty,
|
||||||
switch_ty,
|
*switch_ty,
|
||||||
term_location.to_locations(),
|
term_location.to_locations(),
|
||||||
ConstraintCategory::Assignment,
|
ConstraintCategory::Assignment,
|
||||||
) {
|
) {
|
||||||
|
@ -1384,14 +1384,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
// FIXME: check the values
|
// FIXME: check the values
|
||||||
}
|
}
|
||||||
TerminatorKind::Call {
|
TerminatorKind::Call { func, args, destination, from_hir_call, target, .. } => {
|
||||||
ref func,
|
|
||||||
ref args,
|
|
||||||
ref destination,
|
|
||||||
from_hir_call,
|
|
||||||
target,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
self.check_operand(func, term_location);
|
self.check_operand(func, term_location);
|
||||||
for arg in args {
|
for arg in args {
|
||||||
self.check_operand(arg, term_location);
|
self.check_operand(arg, term_location);
|
||||||
|
@ -1431,7 +1424,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::Boring,
|
||||||
);
|
);
|
||||||
let sig = self.normalize(sig, term_location);
|
let sig = self.normalize(sig, term_location);
|
||||||
self.check_call_dest(body, term, &sig, *destination, target, term_location);
|
self.check_call_dest(body, term, &sig, *destination, *target, term_location);
|
||||||
|
|
||||||
// The ordinary liveness rules will ensure that all
|
// The ordinary liveness rules will ensure that all
|
||||||
// regions in the type of the callee are live here. We
|
// regions in the type of the callee are live here. We
|
||||||
|
@ -1449,9 +1442,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
.add_element(region_vid, term_location);
|
.add_element(region_vid, term_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.check_call_inputs(body, term, &sig, args, term_location, from_hir_call);
|
self.check_call_inputs(body, term, &sig, args, term_location, *from_hir_call);
|
||||||
}
|
}
|
||||||
TerminatorKind::Assert { ref cond, ref msg, .. } => {
|
TerminatorKind::Assert { cond, msg, .. } => {
|
||||||
self.check_operand(cond, term_location);
|
self.check_operand(cond, term_location);
|
||||||
|
|
||||||
let cond_ty = cond.ty(body, tcx);
|
let cond_ty = cond.ty(body, tcx);
|
||||||
|
@ -1459,7 +1452,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
|
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let AssertKind::BoundsCheck { ref len, ref index } = *msg {
|
if let AssertKind::BoundsCheck { len, index } = msg {
|
||||||
if len.ty(body, tcx) != tcx.types.usize {
|
if len.ty(body, tcx) != tcx.types.usize {
|
||||||
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
|
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
|
||||||
}
|
}
|
||||||
|
@ -1468,7 +1461,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TerminatorKind::Yield { ref value, .. } => {
|
TerminatorKind::Yield { value, .. } => {
|
||||||
self.check_operand(value, term_location);
|
self.check_operand(value, term_location);
|
||||||
|
|
||||||
let value_ty = value.ty(body, tcx);
|
let value_ty = value.ty(body, tcx);
|
||||||
|
@ -2630,7 +2623,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
substs: SubstsRef<'tcx>,
|
substs: SubstsRef<'tcx>,
|
||||||
location: Location,
|
location: Location,
|
||||||
) -> ty::InstantiatedPredicates<'tcx> {
|
) -> ty::InstantiatedPredicates<'tcx> {
|
||||||
if let Some(ref closure_requirements) = tcx.mir_borrowck(def_id).closure_requirements {
|
if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
|
||||||
constraint_conversion::ConstraintConversion::new(
|
constraint_conversion::ConstraintConversion::new(
|
||||||
self.infcx,
|
self.infcx,
|
||||||
self.borrowck_context.universal_regions,
|
self.borrowck_context.universal_regions,
|
||||||
|
|
|
@ -587,9 +587,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
|
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
|
||||||
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
||||||
let fr_substs = match defining_ty {
|
let fr_substs = match defining_ty {
|
||||||
DefiningTy::Closure(_, ref substs)
|
DefiningTy::Closure(_, substs)
|
||||||
| DefiningTy::Generator(_, ref substs, _)
|
| DefiningTy::Generator(_, substs, _)
|
||||||
| DefiningTy::InlineConst(_, ref substs) => {
|
| DefiningTy::InlineConst(_, substs) => {
|
||||||
// In the case of closures, we rely on the fact that
|
// In the case of closures, we rely on the fact that
|
||||||
// the first N elements in the ClosureSubsts are
|
// the first N elements in the ClosureSubsts are
|
||||||
// inherited from the `typeck_root_def_id`.
|
// inherited from the `typeck_root_def_id`.
|
||||||
|
|
|
@ -17,31 +17,22 @@ pub fn expand(
|
||||||
check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler);
|
check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler);
|
||||||
|
|
||||||
let orig_item = item.clone();
|
let orig_item = item.clone();
|
||||||
let not_function = || {
|
|
||||||
ecx.sess
|
|
||||||
.parse_sess
|
|
||||||
.span_diagnostic
|
|
||||||
.span_err(item.span(), "alloc_error_handler must be a function");
|
|
||||||
vec![orig_item.clone()]
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allow using `#[alloc_error_handler]` on an item statement
|
// Allow using `#[alloc_error_handler]` on an item statement
|
||||||
// FIXME - if we get deref patterns, use them to reduce duplication here
|
// FIXME - if we get deref patterns, use them to reduce duplication here
|
||||||
let (item, is_stmt, sig_span) = match &item {
|
let (item, is_stmt, sig_span) =
|
||||||
Annotatable::Item(item) => match item.kind {
|
if let Annotatable::Item(item) = &item
|
||||||
ItemKind::Fn(ref fn_kind) => (item, false, ecx.with_def_site_ctxt(fn_kind.sig.span)),
|
&& let ItemKind::Fn(fn_kind) = &item.kind
|
||||||
_ => return not_function(),
|
{
|
||||||
},
|
(item, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
|
||||||
Annotatable::Stmt(stmt) => match &stmt.kind {
|
} else if let Annotatable::Stmt(stmt) = &item
|
||||||
StmtKind::Item(item_) => match item_.kind {
|
&& let StmtKind::Item(item) = &stmt.kind
|
||||||
ItemKind::Fn(ref fn_kind) => {
|
&& let ItemKind::Fn(fn_kind) = &item.kind
|
||||||
(item_, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
|
{
|
||||||
}
|
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
|
||||||
_ => return not_function(),
|
} else {
|
||||||
},
|
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "alloc_error_handler must be a function");
|
||||||
_ => return not_function(),
|
return vec![orig_item.clone()];
|
||||||
},
|
|
||||||
_ => return not_function(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate a bunch of new items using the AllocFnFactory
|
// Generate a bunch of new items using the AllocFnFactory
|
||||||
|
|
|
@ -191,19 +191,19 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
||||||
///
|
///
|
||||||
/// See [Self::manage_initial_capture] and [Self::manage_try_capture]
|
/// See [Self::manage_initial_capture] and [Self::manage_try_capture]
|
||||||
fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
|
fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
|
||||||
match (*expr).kind {
|
match &mut expr.kind {
|
||||||
ExprKind::AddrOf(_, mutability, ref mut local_expr) => {
|
ExprKind::AddrOf(_, mutability, local_expr) => {
|
||||||
self.with_is_consumed_management(
|
self.with_is_consumed_management(
|
||||||
matches!(mutability, Mutability::Mut),
|
matches!(mutability, Mutability::Mut),
|
||||||
|this| this.manage_cond_expr(local_expr)
|
|this| this.manage_cond_expr(local_expr)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ExprKind::Array(ref mut local_exprs) => {
|
ExprKind::Array(local_exprs) => {
|
||||||
for local_expr in local_exprs {
|
for local_expr in local_exprs {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Binary(ref op, ref mut lhs, ref mut rhs) => {
|
ExprKind::Binary(op, lhs, rhs) => {
|
||||||
self.with_is_consumed_management(
|
self.with_is_consumed_management(
|
||||||
matches!(
|
matches!(
|
||||||
op.node,
|
op.node,
|
||||||
|
@ -226,56 +226,56 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ExprKind::Call(_, ref mut local_exprs) => {
|
ExprKind::Call(_, local_exprs) => {
|
||||||
for local_expr in local_exprs {
|
for local_expr in local_exprs {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Cast(ref mut local_expr, _) => {
|
ExprKind::Cast(local_expr, _) => {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
ExprKind::Index(ref mut prefix, ref mut suffix) => {
|
ExprKind::Index(prefix, suffix) => {
|
||||||
self.manage_cond_expr(prefix);
|
self.manage_cond_expr(prefix);
|
||||||
self.manage_cond_expr(suffix);
|
self.manage_cond_expr(suffix);
|
||||||
}
|
}
|
||||||
ExprKind::MethodCall(ref mut call) => {
|
ExprKind::MethodCall(call) => {
|
||||||
for arg in call.args.iter_mut() {
|
for arg in &mut call.args {
|
||||||
self.manage_cond_expr(arg);
|
self.manage_cond_expr(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Path(_, Path { ref segments, .. }) if let &[ref path_segment] = &segments[..] => {
|
ExprKind::Path(_, Path { segments, .. }) if let [path_segment] = &segments[..] => {
|
||||||
let path_ident = path_segment.ident;
|
let path_ident = path_segment.ident;
|
||||||
self.manage_initial_capture(expr, path_ident);
|
self.manage_initial_capture(expr, path_ident);
|
||||||
}
|
}
|
||||||
ExprKind::Paren(ref mut local_expr) => {
|
ExprKind::Paren(local_expr) => {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
ExprKind::Range(ref mut prefix, ref mut suffix, _) => {
|
ExprKind::Range(prefix, suffix, _) => {
|
||||||
if let Some(ref mut elem) = prefix {
|
if let Some(elem) = prefix {
|
||||||
self.manage_cond_expr(elem);
|
self.manage_cond_expr(elem);
|
||||||
}
|
}
|
||||||
if let Some(ref mut elem) = suffix {
|
if let Some(elem) = suffix {
|
||||||
self.manage_cond_expr(elem);
|
self.manage_cond_expr(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Repeat(ref mut local_expr, ref mut elem) => {
|
ExprKind::Repeat(local_expr, elem) => {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
self.manage_cond_expr(&mut elem.value);
|
self.manage_cond_expr(&mut elem.value);
|
||||||
}
|
}
|
||||||
ExprKind::Struct(ref mut elem) => {
|
ExprKind::Struct(elem) => {
|
||||||
for field in &mut elem.fields {
|
for field in &mut elem.fields {
|
||||||
self.manage_cond_expr(&mut field.expr);
|
self.manage_cond_expr(&mut field.expr);
|
||||||
}
|
}
|
||||||
if let StructRest::Base(ref mut local_expr) = elem.rest {
|
if let StructRest::Base(local_expr) = &mut elem.rest {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Tup(ref mut local_exprs) => {
|
ExprKind::Tup(local_exprs) => {
|
||||||
for local_expr in local_exprs {
|
for local_expr in local_exprs {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Unary(un_op, ref mut local_expr) => {
|
ExprKind::Unary(un_op, local_expr) => {
|
||||||
self.with_is_consumed_management(
|
self.with_is_consumed_management(
|
||||||
matches!(un_op, UnOp::Neg | UnOp::Not),
|
matches!(un_op, UnOp::Neg | UnOp::Not),
|
||||||
|this| this.manage_cond_expr(local_expr)
|
|this| this.manage_cond_expr(local_expr)
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub fn expand_concat(
|
||||||
for e in es {
|
for e in es {
|
||||||
match e.kind {
|
match e.kind {
|
||||||
ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
|
ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
|
||||||
Ok(ast::LitKind::Str(ref s, _) | ast::LitKind::Float(ref s, _)) => {
|
Ok(ast::LitKind::Str(s, _) | ast::LitKind::Float(s, _)) => {
|
||||||
accumulator.push_str(s.as_str());
|
accumulator.push_str(s.as_str());
|
||||||
}
|
}
|
||||||
Ok(ast::LitKind::Char(c)) => {
|
Ok(ast::LitKind::Char(c)) => {
|
||||||
|
|
|
@ -144,8 +144,8 @@ pub fn expand_concat_bytes(
|
||||||
let mut missing_literals = vec![];
|
let mut missing_literals = vec![];
|
||||||
let mut has_errors = false;
|
let mut has_errors = false;
|
||||||
for e in es {
|
for e in es {
|
||||||
match e.kind {
|
match &e.kind {
|
||||||
ast::ExprKind::Array(ref exprs) => {
|
ast::ExprKind::Array(exprs) => {
|
||||||
for expr in exprs {
|
for expr in exprs {
|
||||||
if let Some(elem) =
|
if let Some(elem) =
|
||||||
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
|
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
|
||||||
|
@ -154,7 +154,7 @@ pub fn expand_concat_bytes(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprKind::Repeat(ref expr, ref count) => {
|
ast::ExprKind::Repeat(expr, count) => {
|
||||||
if let ast::ExprKind::Lit(token_lit) = count.value.kind
|
if let ast::ExprKind::Lit(token_lit) = count.value.kind
|
||||||
&& let Ok(ast::LitKind::Int(count_val, _)) =
|
&& let Ok(ast::LitKind::Int(count_val, _)) =
|
||||||
ast::LitKind::from_token_lit(token_lit)
|
ast::LitKind::from_token_lit(token_lit)
|
||||||
|
@ -170,7 +170,7 @@ pub fn expand_concat_bytes(
|
||||||
cx.span_err(count.value.span, "repeat count is not a positive number");
|
cx.span_err(count.value.span, "repeat count is not a positive number");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
|
&ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
|
||||||
Ok(ast::LitKind::Byte(val)) => {
|
Ok(ast::LitKind::Byte(val)) => {
|
||||||
accumulator.push(val);
|
accumulator.push(val);
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ pub fn expand_concat_bytes(
|
||||||
has_errors = true;
|
has_errors = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::ExprKind::IncludedBytes(ref bytes) => {
|
ast::ExprKind::IncludedBytes(bytes) => {
|
||||||
accumulator.extend_from_slice(bytes);
|
accumulator.extend_from_slice(bytes);
|
||||||
}
|
}
|
||||||
ast::ExprKind::Err => {
|
ast::ExprKind::Err => {
|
||||||
|
|
|
@ -32,10 +32,10 @@ pub fn expand_deriving_clone(
|
||||||
let bounds;
|
let bounds;
|
||||||
let substructure;
|
let substructure;
|
||||||
let is_simple;
|
let is_simple;
|
||||||
match *item {
|
match item {
|
||||||
Annotatable::Item(ref annitem) => match annitem.kind {
|
Annotatable::Item(annitem) => match &annitem.kind {
|
||||||
ItemKind::Struct(_, Generics { ref params, .. })
|
ItemKind::Struct(_, Generics { params, .. })
|
||||||
| ItemKind::Enum(_, Generics { ref params, .. }) => {
|
| ItemKind::Enum(_, Generics { params, .. }) => {
|
||||||
let container_id = cx.current_expansion.id.expn_data().parent.expect_local();
|
let container_id = cx.current_expansion.id.expn_data().parent.expect_local();
|
||||||
let has_derive_copy = cx.resolver.has_derive_copy(container_id);
|
let has_derive_copy = cx.resolver.has_derive_copy(container_id);
|
||||||
if has_derive_copy
|
if has_derive_copy
|
||||||
|
@ -166,13 +166,13 @@ fn cs_clone(
|
||||||
};
|
};
|
||||||
|
|
||||||
let vdata;
|
let vdata;
|
||||||
match *substr.fields {
|
match substr.fields {
|
||||||
Struct(vdata_, ref af) => {
|
Struct(vdata_, af) => {
|
||||||
ctor_path = cx.path(trait_span, vec![substr.type_ident]);
|
ctor_path = cx.path(trait_span, vec![substr.type_ident]);
|
||||||
all_fields = af;
|
all_fields = af;
|
||||||
vdata = vdata_;
|
vdata = *vdata_;
|
||||||
}
|
}
|
||||||
EnumMatching(.., variant, ref af) => {
|
EnumMatching(.., variant, af) => {
|
||||||
ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]);
|
ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]);
|
||||||
all_fields = af;
|
all_fields = af;
|
||||||
vdata = &variant.data;
|
vdata = &variant.data;
|
||||||
|
|
|
@ -78,11 +78,11 @@ fn decodable_substructure(
|
||||||
let blkarg = Ident::new(sym::_d, trait_span);
|
let blkarg = Ident::new(sym::_d, trait_span);
|
||||||
let blkdecoder = cx.expr_ident(trait_span, blkarg);
|
let blkdecoder = cx.expr_ident(trait_span, blkarg);
|
||||||
|
|
||||||
let expr = match *substr.fields {
|
let expr = match substr.fields {
|
||||||
StaticStruct(_, ref summary) => {
|
StaticStruct(_, summary) => {
|
||||||
let nfields = match *summary {
|
let nfields = match summary {
|
||||||
Unnamed(ref fields, _) => fields.len(),
|
Unnamed(fields, _) => fields.len(),
|
||||||
Named(ref fields) => fields.len(),
|
Named(fields) => fields.len(),
|
||||||
};
|
};
|
||||||
let fn_read_struct_field_path: Vec<_> =
|
let fn_read_struct_field_path: Vec<_> =
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct_field]);
|
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct_field]);
|
||||||
|
@ -119,7 +119,7 @@ fn decodable_substructure(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
StaticEnum(_, ref fields) => {
|
StaticEnum(_, fields) => {
|
||||||
let variant = Ident::new(sym::i, trait_span);
|
let variant = Ident::new(sym::i, trait_span);
|
||||||
|
|
||||||
let mut arms = Vec::with_capacity(fields.len() + 1);
|
let mut arms = Vec::with_capacity(fields.len() + 1);
|
||||||
|
@ -194,10 +194,10 @@ fn decode_static_fields<F>(
|
||||||
where
|
where
|
||||||
F: FnMut(&mut ExtCtxt<'_>, Span, Symbol, usize) -> P<Expr>,
|
F: FnMut(&mut ExtCtxt<'_>, Span, Symbol, usize) -> P<Expr>,
|
||||||
{
|
{
|
||||||
match *fields {
|
match fields {
|
||||||
Unnamed(ref fields, is_tuple) => {
|
Unnamed(fields, is_tuple) => {
|
||||||
let path_expr = cx.expr_path(outer_pat_path);
|
let path_expr = cx.expr_path(outer_pat_path);
|
||||||
if !is_tuple {
|
if !*is_tuple {
|
||||||
path_expr
|
path_expr
|
||||||
} else {
|
} else {
|
||||||
let fields = fields
|
let fields = fields
|
||||||
|
@ -209,7 +209,7 @@ where
|
||||||
cx.expr_call(trait_span, path_expr, fields)
|
cx.expr_call(trait_span, path_expr, fields)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Named(ref fields) => {
|
Named(fields) => {
|
||||||
// use the field's span to get nicer error messages.
|
// use the field's span to get nicer error messages.
|
||||||
let fields = fields
|
let fields = fields
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -62,15 +62,12 @@ fn default_struct_substructure(
|
||||||
let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
|
let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
|
||||||
|
|
||||||
let expr = match summary {
|
let expr = match summary {
|
||||||
Unnamed(ref fields, is_tuple) => {
|
Unnamed(_, false) => cx.expr_ident(trait_span, substr.type_ident),
|
||||||
if !is_tuple {
|
Unnamed(fields, true) => {
|
||||||
cx.expr_ident(trait_span, substr.type_ident)
|
|
||||||
} else {
|
|
||||||
let exprs = fields.iter().map(|sp| default_call(*sp)).collect();
|
let exprs = fields.iter().map(|sp| default_call(*sp)).collect();
|
||||||
cx.expr_call_ident(trait_span, substr.type_ident, exprs)
|
cx.expr_call_ident(trait_span, substr.type_ident, exprs)
|
||||||
}
|
}
|
||||||
}
|
Named(fields) => {
|
||||||
Named(ref fields) => {
|
|
||||||
let default_fields = fields
|
let default_fields = fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(ident, span)| cx.field_imm(span, ident, default_call(span)))
|
.map(|&(ident, span)| cx.field_imm(span, ident, default_call(span)))
|
||||||
|
|
|
@ -164,8 +164,8 @@ fn encodable_substructure(
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
||||||
match *substr.fields {
|
match substr.fields {
|
||||||
Struct(_, ref fields) => {
|
Struct(_, fields) => {
|
||||||
let fn_emit_struct_field_path =
|
let fn_emit_struct_field_path =
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]);
|
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]);
|
||||||
let mut stmts = Vec::new();
|
let mut stmts = Vec::new();
|
||||||
|
@ -224,7 +224,7 @@ fn encodable_substructure(
|
||||||
BlockOrExpr::new_expr(expr)
|
BlockOrExpr::new_expr(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumMatching(idx, _, variant, ref fields) => {
|
EnumMatching(idx, _, variant, fields) => {
|
||||||
// We're not generating an AST that the borrow checker is expecting,
|
// We're not generating an AST that the borrow checker is expecting,
|
||||||
// so we need to generate a unique local variable to take the
|
// so we need to generate a unique local variable to take the
|
||||||
// mutable loan out on, otherwise we get conflicts which don't
|
// mutable loan out on, otherwise we get conflicts which don't
|
||||||
|
@ -274,7 +274,7 @@ fn encodable_substructure(
|
||||||
vec![
|
vec![
|
||||||
blkencoder,
|
blkencoder,
|
||||||
name,
|
name,
|
||||||
cx.expr_usize(trait_span, idx),
|
cx.expr_usize(trait_span, *idx),
|
||||||
cx.expr_usize(trait_span, fields.len()),
|
cx.expr_usize(trait_span, fields.len()),
|
||||||
blk,
|
blk,
|
||||||
],
|
],
|
||||||
|
|
|
@ -369,16 +369,15 @@ fn find_type_parameters(
|
||||||
|
|
||||||
impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
|
impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
|
||||||
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
||||||
if let ast::TyKind::Path(_, ref path) = ty.kind {
|
if let ast::TyKind::Path(_, path) = &ty.kind
|
||||||
if let Some(segment) = path.segments.first() {
|
&& let Some(segment) = path.segments.first()
|
||||||
if self.ty_param_names.contains(&segment.ident.name) {
|
&& self.ty_param_names.contains(&segment.ident.name)
|
||||||
|
{
|
||||||
self.type_params.push(TypeParameter {
|
self.type_params.push(TypeParameter {
|
||||||
bound_generic_params: self.bound_generic_params_stack.clone(),
|
bound_generic_params: self.bound_generic_params_stack.clone(),
|
||||||
ty: P(ty.clone()),
|
ty: P(ty.clone()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visit::walk_ty(self, ty)
|
visit::walk_ty(self, ty)
|
||||||
}
|
}
|
||||||
|
@ -428,8 +427,8 @@ impl<'a> TraitDef<'a> {
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
from_scratch: bool,
|
from_scratch: bool,
|
||||||
) {
|
) {
|
||||||
match *item {
|
match item {
|
||||||
Annotatable::Item(ref item) => {
|
Annotatable::Item(item) => {
|
||||||
let is_packed = item.attrs.iter().any(|attr| {
|
let is_packed = item.attrs.iter().any(|attr| {
|
||||||
for r in attr::find_repr_attrs(&cx.sess, attr) {
|
for r in attr::find_repr_attrs(&cx.sess, attr) {
|
||||||
if let attr::ReprPacked(_) = r {
|
if let attr::ReprPacked(_) = r {
|
||||||
|
@ -438,10 +437,10 @@ impl<'a> TraitDef<'a> {
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
});
|
});
|
||||||
let has_no_type_params = match item.kind {
|
let has_no_type_params = match &item.kind {
|
||||||
ast::ItemKind::Struct(_, ref generics)
|
ast::ItemKind::Struct(_, generics)
|
||||||
| ast::ItemKind::Enum(_, ref generics)
|
| ast::ItemKind::Enum(_, generics)
|
||||||
| ast::ItemKind::Union(_, ref generics) => !generics
|
| ast::ItemKind::Union(_, generics) => !generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })),
|
.any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })),
|
||||||
|
@ -451,8 +450,8 @@ impl<'a> TraitDef<'a> {
|
||||||
let copy_fields =
|
let copy_fields =
|
||||||
is_packed && has_no_type_params && cx.resolver.has_derive_copy(container_id);
|
is_packed && has_no_type_params && cx.resolver.has_derive_copy(container_id);
|
||||||
|
|
||||||
let newitem = match item.kind {
|
let newitem = match &item.kind {
|
||||||
ast::ItemKind::Struct(ref struct_def, ref generics) => self.expand_struct_def(
|
ast::ItemKind::Struct(struct_def, generics) => self.expand_struct_def(
|
||||||
cx,
|
cx,
|
||||||
&struct_def,
|
&struct_def,
|
||||||
item.ident,
|
item.ident,
|
||||||
|
@ -460,7 +459,7 @@ impl<'a> TraitDef<'a> {
|
||||||
from_scratch,
|
from_scratch,
|
||||||
copy_fields,
|
copy_fields,
|
||||||
),
|
),
|
||||||
ast::ItemKind::Enum(ref enum_def, ref generics) => {
|
ast::ItemKind::Enum(enum_def, generics) => {
|
||||||
// We ignore `is_packed` here, because `repr(packed)`
|
// We ignore `is_packed` here, because `repr(packed)`
|
||||||
// enums cause an error later on.
|
// enums cause an error later on.
|
||||||
//
|
//
|
||||||
|
@ -468,7 +467,7 @@ impl<'a> TraitDef<'a> {
|
||||||
// downstream in blatantly illegal code, so it is fine.
|
// downstream in blatantly illegal code, so it is fine.
|
||||||
self.expand_enum_def(cx, enum_def, item.ident, generics, from_scratch)
|
self.expand_enum_def(cx, enum_def, item.ident, generics, from_scratch)
|
||||||
}
|
}
|
||||||
ast::ItemKind::Union(ref struct_def, ref generics) => {
|
ast::ItemKind::Union(struct_def, generics) => {
|
||||||
if self.supports_unions {
|
if self.supports_unions {
|
||||||
self.expand_struct_def(
|
self.expand_struct_def(
|
||||||
cx,
|
cx,
|
||||||
|
@ -663,12 +662,11 @@ impl<'a> TraitDef<'a> {
|
||||||
|
|
||||||
for field_ty_param in field_ty_params {
|
for field_ty_param in field_ty_params {
|
||||||
// if we have already handled this type, skip it
|
// if we have already handled this type, skip it
|
||||||
if let ast::TyKind::Path(_, ref p) = field_ty_param.ty.kind {
|
if let ast::TyKind::Path(_, p) = &field_ty_param.ty.kind
|
||||||
if p.segments.len() == 1
|
&& let [sole_segment] = &*p.segments
|
||||||
&& ty_param_names.contains(&p.segments[0].ident.name)
|
&& ty_param_names.contains(&sole_segment.ident.name)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
let mut bounds: Vec<_> = self
|
let mut bounds: Vec<_> = self
|
||||||
.additional_bounds
|
.additional_bounds
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl Ty {
|
||||||
self_ty: Ident,
|
self_ty: Ident,
|
||||||
generics: &Generics,
|
generics: &Generics,
|
||||||
) -> ast::Path {
|
) -> ast::Path {
|
||||||
match *self {
|
match self {
|
||||||
Self_ => {
|
Self_ => {
|
||||||
let params: Vec<_> = generics
|
let params: Vec<_> = generics
|
||||||
.params
|
.params
|
||||||
|
@ -135,7 +135,7 @@ impl Ty {
|
||||||
|
|
||||||
cx.path_all(span, false, vec![self_ty], params)
|
cx.path_all(span, false, vec![self_ty], params)
|
||||||
}
|
}
|
||||||
Path(ref p) => p.to_path(cx, span, self_ty, generics),
|
Path(p) => p.to_path(cx, span, self_ty, generics),
|
||||||
Ref(..) => cx.span_bug(span, "ref in a path in generic `derive`"),
|
Ref(..) => cx.span_bug(span, "ref in a path in generic `derive`"),
|
||||||
Unit => cx.span_bug(span, "unit in a path in generic `derive`"),
|
Unit => cx.span_bug(span, "unit in a path in generic `derive`"),
|
||||||
}
|
}
|
||||||
|
@ -180,10 +180,7 @@ impl Bounds {
|
||||||
let params = self
|
let params = self
|
||||||
.bounds
|
.bounds
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| {
|
.map(|&(name, ref bounds)| mk_ty_param(cx, span, name, &bounds, self_ty, self_generics))
|
||||||
let (name, ref bounds) = *t;
|
|
||||||
mk_ty_param(cx, span, name, &bounds, self_ty, self_generics)
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Generics {
|
Generics {
|
||||||
|
|
|
@ -125,12 +125,12 @@ fn inject_impl_of_structural_trait(
|
||||||
structural_path: generic::ty::Path,
|
structural_path: generic::ty::Path,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
) {
|
) {
|
||||||
let Annotatable::Item(ref item) = *item else {
|
let Annotatable::Item(item) = item else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
let generics = match item.kind {
|
let generics = match &item.kind {
|
||||||
ItemKind::Struct(_, ref generics) | ItemKind::Enum(_, ref generics) => generics,
|
ItemKind::Struct(_, generics) | ItemKind::Enum(_, generics) => generics,
|
||||||
// Do not inject `impl Structural for Union`. (`PartialEq` does not
|
// Do not inject `impl Structural for Union`. (`PartialEq` does not
|
||||||
// support unions, so we will see error downstream.)
|
// support unions, so we will see error downstream.)
|
||||||
ItemKind::Union(..) => return,
|
ItemKind::Union(..) => return,
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub fn expand_env<'cx>(
|
||||||
tts: TokenStream,
|
tts: TokenStream,
|
||||||
) -> Box<dyn base::MacResult + 'cx> {
|
) -> Box<dyn base::MacResult + 'cx> {
|
||||||
let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
|
let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
|
||||||
Some(ref exprs) if exprs.is_empty() => {
|
Some(exprs) if exprs.is_empty() => {
|
||||||
cx.span_err(sp, "env! takes 1 or 2 arguments");
|
cx.span_err(sp, "env! takes 1 or 2 arguments");
|
||||||
return DummyResult::any(sp);
|
return DummyResult::any(sp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,23 +13,23 @@ pub(crate) mod printf {
|
||||||
|
|
||||||
impl<'a> Substitution<'a> {
|
impl<'a> Substitution<'a> {
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
match *self {
|
match self {
|
||||||
Substitution::Format(ref fmt) => fmt.span,
|
Substitution::Format(fmt) => fmt.span,
|
||||||
Substitution::Escape(_) => "%%",
|
Substitution::Escape(_) => "%%",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn position(&self) -> Option<InnerSpan> {
|
pub fn position(&self) -> Option<InnerSpan> {
|
||||||
match *self {
|
match self {
|
||||||
Substitution::Format(ref fmt) => Some(fmt.position),
|
Substitution::Format(fmt) => Some(fmt.position),
|
||||||
Substitution::Escape((start, end)) => Some(InnerSpan::new(start, end)),
|
&Substitution::Escape((start, end)) => Some(InnerSpan::new(start, end)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_position(&mut self, start: usize, end: usize) {
|
pub fn set_position(&mut self, start: usize, end: usize) {
|
||||||
match self {
|
match self {
|
||||||
Substitution::Format(ref mut fmt) => fmt.position = InnerSpan::new(start, end),
|
Substitution::Format(fmt) => fmt.position = InnerSpan::new(start, end),
|
||||||
Substitution::Escape(ref mut pos) => *pos = (start, end),
|
Substitution::Escape(pos) => *pos = (start, end),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@ pub(crate) mod printf {
|
||||||
/// This ignores cases where the substitution does not have an exact equivalent, or where
|
/// This ignores cases where the substitution does not have an exact equivalent, or where
|
||||||
/// the substitution would be unnecessary.
|
/// the substitution would be unnecessary.
|
||||||
pub fn translate(&self) -> Result<String, Option<String>> {
|
pub fn translate(&self) -> Result<String, Option<String>> {
|
||||||
match *self {
|
match self {
|
||||||
Substitution::Format(ref fmt) => fmt.translate(),
|
Substitution::Format(fmt) => fmt.translate(),
|
||||||
Substitution::Escape(_) => Err(None),
|
Substitution::Escape(_) => Err(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -635,23 +635,17 @@ pub mod shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn position(&self) -> Option<InnerSpan> {
|
pub fn position(&self) -> Option<InnerSpan> {
|
||||||
match self {
|
let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
|
||||||
Substitution::Ordinal(_, pos)
|
Some(InnerSpan::new(pos.0, pos.1))
|
||||||
| Substitution::Name(_, pos)
|
|
||||||
| Substitution::Escape(pos) => Some(InnerSpan::new(pos.0, pos.1)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_position(&mut self, start: usize, end: usize) {
|
pub fn set_position(&mut self, start: usize, end: usize) {
|
||||||
match self {
|
let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
|
||||||
Substitution::Ordinal(_, ref mut pos)
|
*pos = (start, end);
|
||||||
| Substitution::Name(_, ref mut pos)
|
|
||||||
| Substitution::Escape(ref mut pos) => *pos = (start, end),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn translate(&self) -> Result<String, Option<String>> {
|
pub fn translate(&self) -> Result<String, Option<String>> {
|
||||||
match *self {
|
match self {
|
||||||
Substitution::Ordinal(n, _) => Ok(format!("{{{}}}", n)),
|
Substitution::Ordinal(n, _) => Ok(format!("{{{}}}", n)),
|
||||||
Substitution::Name(n, _) => Ok(format!("{{{}}}", n)),
|
Substitution::Name(n, _) => Ok(format!("{{{}}}", n)),
|
||||||
Substitution::Escape(_) => Err(None),
|
Substitution::Escape(_) => Err(None),
|
||||||
|
|
|
@ -20,26 +20,22 @@ pub fn expand(
|
||||||
check_builtin_macro_attribute(ecx, meta_item, sym::global_allocator);
|
check_builtin_macro_attribute(ecx, meta_item, sym::global_allocator);
|
||||||
|
|
||||||
let orig_item = item.clone();
|
let orig_item = item.clone();
|
||||||
let not_static = || {
|
|
||||||
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics");
|
|
||||||
vec![orig_item.clone()]
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allow using `#[global_allocator]` on an item statement
|
// Allow using `#[global_allocator]` on an item statement
|
||||||
// FIXME - if we get deref patterns, use them to reduce duplication here
|
// FIXME - if we get deref patterns, use them to reduce duplication here
|
||||||
let (item, is_stmt, ty_span) = match &item {
|
let (item, is_stmt, ty_span) =
|
||||||
Annotatable::Item(item) => match item.kind {
|
if let Annotatable::Item(item) = &item
|
||||||
ItemKind::Static(ref ty, ..) => (item, false, ecx.with_def_site_ctxt(ty.span)),
|
&& let ItemKind::Static(ty, ..) = &item.kind
|
||||||
_ => return not_static(),
|
{
|
||||||
},
|
(item, false, ecx.with_def_site_ctxt(ty.span))
|
||||||
Annotatable::Stmt(stmt) => match &stmt.kind {
|
} else if let Annotatable::Stmt(stmt) = &item
|
||||||
StmtKind::Item(item_) => match item_.kind {
|
&& let StmtKind::Item(item) = &stmt.kind
|
||||||
ItemKind::Static(ref ty, ..) => (item_, true, ecx.with_def_site_ctxt(ty.span)),
|
&& let ItemKind::Static(ty, ..) = &item.kind
|
||||||
_ => return not_static(),
|
{
|
||||||
},
|
(item, true, ecx.with_def_site_ctxt(ty.span))
|
||||||
_ => return not_static(),
|
} else {
|
||||||
},
|
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics");
|
||||||
_ => return not_static(),
|
return vec![orig_item.clone()]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate a bunch of new items using the AllocFnFactory
|
// Generate a bunch of new items using the AllocFnFactory
|
||||||
|
|
|
@ -466,7 +466,8 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType {
|
||||||
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
||||||
let has_should_panic_attr = cx.sess.contains_name(&i.attrs, sym::should_panic);
|
let has_should_panic_attr = cx.sess.contains_name(&i.attrs, sym::should_panic);
|
||||||
let sd = &cx.sess.parse_sess.span_diagnostic;
|
let sd = &cx.sess.parse_sess.span_diagnostic;
|
||||||
if let ast::ItemKind::Fn(box ast::Fn { ref sig, ref generics, .. }) = i.kind {
|
match &i.kind {
|
||||||
|
ast::ItemKind::Fn(box ast::Fn { sig, generics, .. }) => {
|
||||||
if let ast::Unsafe::Yes(span) = sig.header.unsafety {
|
if let ast::Unsafe::Yes(span) = sig.header.unsafety {
|
||||||
sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
|
sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
|
||||||
.span_label(span, "`unsafe` because of this")
|
.span_label(span, "`unsafe` because of this")
|
||||||
|
@ -482,9 +483,9 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
||||||
|
|
||||||
// If the termination trait is active, the compiler will check that the output
|
// If the termination trait is active, the compiler will check that the output
|
||||||
// type implements the `Termination` trait as `libtest` enforces that.
|
// type implements the `Termination` trait as `libtest` enforces that.
|
||||||
let has_output = match sig.decl.output {
|
let has_output = match &sig.decl.output {
|
||||||
ast::FnRetTy::Default(..) => false,
|
ast::FnRetTy::Default(..) => false,
|
||||||
ast::FnRetTy::Ty(ref t) if t.kind.is_unit() => false,
|
ast::FnRetTy::Ty(t) if t.kind.is_unit() => false,
|
||||||
_ => true,
|
_ => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -500,7 +501,10 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
||||||
}
|
}
|
||||||
(true, false) => {
|
(true, false) => {
|
||||||
if !generics.params.is_empty() {
|
if !generics.params.is_empty() {
|
||||||
sd.span_err(i.span, "functions used as tests must have signature fn() -> ()");
|
sd.span_err(
|
||||||
|
i.span,
|
||||||
|
"functions used as tests must have signature fn() -> ()",
|
||||||
|
);
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
@ -508,19 +512,21 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
||||||
}
|
}
|
||||||
(false, _) => true,
|
(false, _) => true,
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
_ => {
|
||||||
// should be unreachable because `is_test_fn_item` should catch all non-fn items
|
// should be unreachable because `is_test_fn_item` should catch all non-fn items
|
||||||
|
debug_assert!(false);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
||||||
let has_sig = if let ast::ItemKind::Fn(box ast::Fn { ref sig, .. }) = i.kind {
|
let has_sig = match &i.kind {
|
||||||
// N.B., inadequate check, but we're running
|
// N.B., inadequate check, but we're running
|
||||||
// well before resolve, can't get too deep.
|
// well before resolve, can't get too deep.
|
||||||
sig.decl.inputs.len() == 1
|
ast::ItemKind::Fn(box ast::Fn { sig, .. }) => sig.decl.inputs.len() == 1,
|
||||||
} else {
|
_ => false,
|
||||||
false
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if !has_sig {
|
if !has_sig {
|
||||||
|
|
|
@ -131,8 +131,9 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
||||||
|
|
||||||
// We don't want to recurse into anything other than mods, since
|
// We don't want to recurse into anything other than mods, since
|
||||||
// mods or tests inside of functions will break things
|
// mods or tests inside of functions will break things
|
||||||
if let ast::ItemKind::Mod(_, ModKind::Loaded(.., ref spans)) = item.kind {
|
if let ast::ItemKind::Mod(_, ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. })) =
|
||||||
let ast::ModSpans { inner_span: span, inject_use_span: _ } = *spans;
|
item.kind
|
||||||
|
{
|
||||||
let prev_tests = mem::take(&mut self.tests);
|
let prev_tests = mem::take(&mut self.tests);
|
||||||
noop_visit_item_kind(&mut item.kind, self);
|
noop_visit_item_kind(&mut item.kind, self);
|
||||||
self.add_test_cases(item.id, span, prev_tests);
|
self.add_test_cases(item.id, span, prev_tests);
|
||||||
|
|
|
@ -2352,15 +2352,6 @@ fn add_native_libs_from_crate(
|
||||||
&search_paths.get_or_init(|| archive_search_paths(sess)),
|
&search_paths.get_or_init(|| archive_search_paths(sess)),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// HACK/FIXME: Fixup a circular dependency between libgcc and libc
|
|
||||||
// with glibc. This logic should be moved to the libc crate.
|
|
||||||
if cnum != LOCAL_CRATE
|
|
||||||
&& sess.target.os == "linux"
|
|
||||||
&& sess.target.env == "gnu"
|
|
||||||
&& name == "c"
|
|
||||||
{
|
|
||||||
cmd.link_staticlib("gcc", false);
|
|
||||||
}
|
|
||||||
cmd.link_staticlib(name, verbatim)
|
cmd.link_staticlib(name, verbatim)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1647,6 +1647,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// the fields with the base_expr. This could cause us to hit errors later
|
// the fields with the base_expr. This could cause us to hit errors later
|
||||||
// when certain fields are assumed to exist that in fact do not.
|
// when certain fields are assumed to exist that in fact do not.
|
||||||
if error_happened {
|
if error_happened {
|
||||||
|
if let Some(base_expr) = base_expr {
|
||||||
|
self.check_expr(base_expr);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -523,6 +523,11 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||||
// Consume the expressions supplying values for each field.
|
// Consume the expressions supplying values for each field.
|
||||||
for field in fields {
|
for field in fields {
|
||||||
self.consume_expr(field.expr);
|
self.consume_expr(field.expr);
|
||||||
|
|
||||||
|
// The struct path probably didn't resolve
|
||||||
|
if self.mc.typeck_results.opt_field_index(field.hir_id).is_none() {
|
||||||
|
self.tcx().sess.delay_span_bug(field.span, "couldn't resolve index for field");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let with_expr = match *opt_with {
|
let with_expr = match *opt_with {
|
||||||
|
@ -540,9 +545,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||||
ty::Adt(adt, substs) if adt.is_struct() => {
|
ty::Adt(adt, substs) if adt.is_struct() => {
|
||||||
// Consume those fields of the with expression that are needed.
|
// Consume those fields of the with expression that are needed.
|
||||||
for (f_index, with_field) in adt.non_enum_variant().fields.iter().enumerate() {
|
for (f_index, with_field) in adt.non_enum_variant().fields.iter().enumerate() {
|
||||||
let is_mentioned = fields.iter().any(|f| {
|
let is_mentioned = fields
|
||||||
self.tcx().field_index(f.hir_id, self.mc.typeck_results) == f_index
|
.iter()
|
||||||
});
|
.any(|f| self.mc.typeck_results.opt_field_index(f.hir_id) == Some(f_index));
|
||||||
if !is_mentioned {
|
if !is_mentioned {
|
||||||
let field_place = self.mc.cat_projection(
|
let field_place = self.mc.cat_projection(
|
||||||
&*with_expr,
|
&*with_expr,
|
||||||
|
|
|
@ -259,7 +259,7 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
|
||||||
}
|
}
|
||||||
if let PatKind::Binding(binding_annot, _, ident, None) = fieldpat.pat.kind {
|
if let PatKind::Binding(binding_annot, _, ident, None) = fieldpat.pat.kind {
|
||||||
if cx.tcx.find_field_index(ident, &variant)
|
if cx.tcx.find_field_index(ident, &variant)
|
||||||
== Some(cx.tcx.field_index(fieldpat.hir_id, cx.typeck_results()))
|
== Some(cx.typeck_results().field_index(fieldpat.hir_id))
|
||||||
{
|
{
|
||||||
cx.struct_span_lint(
|
cx.struct_span_lint(
|
||||||
NON_SHORTHAND_FIELD_PATTERNS,
|
NON_SHORTHAND_FIELD_PATTERNS,
|
||||||
|
|
|
@ -667,6 +667,14 @@ impl<'tcx> TypeckResults<'tcx> {
|
||||||
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
|
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn field_index(&self, id: hir::HirId) -> usize {
|
||||||
|
self.field_indices().get(id).cloned().expect("no index for a field")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn opt_field_index(&self, id: hir::HirId) -> Option<usize> {
|
||||||
|
self.field_indices().get(id).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
|
pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
|
||||||
LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
|
LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
|
||||||
}
|
}
|
||||||
|
|
|
@ -2142,10 +2142,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn field_index(self, hir_id: hir::HirId, typeck_results: &TypeckResults<'_>) -> usize {
|
|
||||||
typeck_results.field_indices().get(hir_id).cloned().expect("no index for a field")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> {
|
pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> {
|
||||||
variant
|
variant
|
||||||
.fields
|
.fields
|
||||||
|
|
|
@ -704,7 +704,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
hir::ExprKind::Field(ref source, ..) => ExprKind::Field {
|
hir::ExprKind::Field(ref source, ..) => ExprKind::Field {
|
||||||
lhs: self.mirror_expr(source),
|
lhs: self.mirror_expr(source),
|
||||||
variant_index: VariantIdx::new(0),
|
variant_index: VariantIdx::new(0),
|
||||||
name: Field::new(tcx.field_index(expr.hir_id, self.typeck_results)),
|
name: Field::new(self.typeck_results.field_index(expr.hir_id)),
|
||||||
},
|
},
|
||||||
hir::ExprKind::Cast(ref source, ref cast_ty) => {
|
hir::ExprKind::Cast(ref source, ref cast_ty) => {
|
||||||
// Check for a user-given type annotation on this `cast`
|
// Check for a user-given type annotation on this `cast`
|
||||||
|
@ -1079,7 +1079,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
fields
|
fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| FieldExpr {
|
.map(|field| FieldExpr {
|
||||||
name: Field::new(self.tcx.field_index(field.hir_id, self.typeck_results)),
|
name: Field::new(self.typeck_results.field_index(field.hir_id)),
|
||||||
expr: self.mirror_expr(field.expr),
|
expr: self.mirror_expr(field.expr),
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|
|
@ -321,7 +321,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
let subpatterns = fields
|
let subpatterns = fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| FieldPat {
|
.map(|field| FieldPat {
|
||||||
field: Field::new(self.tcx.field_index(field.hir_id, self.typeck_results)),
|
field: Field::new(self.typeck_results.field_index(field.hir_id)),
|
||||||
pattern: self.lower_pattern(&field.pat),
|
pattern: self.lower_pattern(&field.pat),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
@ -124,7 +124,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
||||||
fn handle_field_access(&mut self, lhs: &hir::Expr<'_>, hir_id: hir::HirId) {
|
fn handle_field_access(&mut self, lhs: &hir::Expr<'_>, hir_id: hir::HirId) {
|
||||||
match self.typeck_results().expr_ty_adjusted(lhs).kind() {
|
match self.typeck_results().expr_ty_adjusted(lhs).kind() {
|
||||||
ty::Adt(def, _) => {
|
ty::Adt(def, _) => {
|
||||||
let index = self.tcx.field_index(hir_id, self.typeck_results());
|
let index = self.typeck_results().field_index(hir_id);
|
||||||
self.insert_def_id(def.non_enum_variant().fields[index].did);
|
self.insert_def_id(def.non_enum_variant().fields[index].did);
|
||||||
}
|
}
|
||||||
ty::Tuple(..) => {}
|
ty::Tuple(..) => {}
|
||||||
|
@ -208,7 +208,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
||||||
if let PatKind::Wild = pat.pat.kind {
|
if let PatKind::Wild = pat.pat.kind {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let index = self.tcx.field_index(pat.hir_id, self.typeck_results());
|
let index = self.typeck_results().field_index(pat.hir_id);
|
||||||
self.insert_def_id(variant.fields[index].did);
|
self.insert_def_id(variant.fields[index].did);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -341,7 +341,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
||||||
fn mark_as_used_if_union(&mut self, adt: ty::AdtDef<'tcx>, fields: &[hir::ExprField<'_>]) {
|
fn mark_as_used_if_union(&mut self, adt: ty::AdtDef<'tcx>, fields: &[hir::ExprField<'_>]) {
|
||||||
if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did().is_local() {
|
if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did().is_local() {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
let index = self.tcx.field_index(field.hir_id, self.typeck_results());
|
let index = self.typeck_results().field_index(field.hir_id);
|
||||||
self.insert_def_id(adt.non_enum_variant().fields[index].did);
|
self.insert_def_id(adt.non_enum_variant().fields[index].did);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1065,9 +1065,9 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
|
||||||
// are checked for privacy (RFC 736). Rather than computing the set of
|
// are checked for privacy (RFC 736). Rather than computing the set of
|
||||||
// unmentioned fields, just check them all.
|
// unmentioned fields, just check them all.
|
||||||
for (vf_index, variant_field) in variant.fields.iter().enumerate() {
|
for (vf_index, variant_field) in variant.fields.iter().enumerate() {
|
||||||
let field = fields.iter().find(|f| {
|
let field = fields
|
||||||
self.tcx.field_index(f.hir_id, self.typeck_results()) == vf_index
|
.iter()
|
||||||
});
|
.find(|f| self.typeck_results().field_index(f.hir_id) == vf_index);
|
||||||
let (use_ctxt, span) = match field {
|
let (use_ctxt, span) = match field {
|
||||||
Some(field) => (field.ident.span, field.span),
|
Some(field) => (field.ident.span, field.span),
|
||||||
None => (base.span, base.span),
|
None => (base.span, base.span),
|
||||||
|
@ -1077,7 +1077,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
|
||||||
} else {
|
} else {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
let use_ctxt = field.ident.span;
|
let use_ctxt = field.ident.span;
|
||||||
let index = self.tcx.field_index(field.hir_id, self.typeck_results());
|
let index = self.typeck_results().field_index(field.hir_id);
|
||||||
self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
|
self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1093,7 +1093,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
|
||||||
let variant = adt.variant_of_res(res);
|
let variant = adt.variant_of_res(res);
|
||||||
for field in fields {
|
for field in fields {
|
||||||
let use_ctxt = field.ident.span;
|
let use_ctxt = field.ident.span;
|
||||||
let index = self.tcx.field_index(field.hir_id, self.typeck_results());
|
let index = self.typeck_results().field_index(field.hir_id);
|
||||||
self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
|
self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub fn is_const_evaluatable<'tcx>(
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<(), NotConstEvaluatable> {
|
) -> Result<(), NotConstEvaluatable> {
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
match unexpanded_ct.kind() {
|
match tcx.expand_abstract_consts(unexpanded_ct).kind() {
|
||||||
ty::ConstKind::Unevaluated(_) | ty::ConstKind::Expr(_) => (),
|
ty::ConstKind::Unevaluated(_) | ty::ConstKind::Expr(_) => (),
|
||||||
ty::ConstKind::Param(_)
|
ty::ConstKind::Param(_)
|
||||||
| ty::ConstKind::Bound(_, _)
|
| ty::ConstKind::Bound(_, _)
|
||||||
|
|
|
@ -212,8 +212,7 @@ pre.rust a,
|
||||||
.mobile-topbar h2 a,
|
.mobile-topbar h2 a,
|
||||||
h1 a,
|
h1 a,
|
||||||
.search-results a,
|
.search-results a,
|
||||||
.module-item .stab,
|
.item-left .stab,
|
||||||
.import-item .stab,
|
|
||||||
.result-name .primitive > i, .result-name .keyword > i {
|
.result-name .primitive > i, .result-name .keyword > i {
|
||||||
color: var(--main-color);
|
color: var(--main-color);
|
||||||
}
|
}
|
||||||
|
@ -1010,8 +1009,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
|
||||||
0 -1px 0 black;
|
0 -1px 0 black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-item .stab,
|
.item-left .stab {
|
||||||
.import-item .stab {
|
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
|
10
src/test/ui/async-await/drop-track-bad-field-in-fru.rs
Normal file
10
src/test/ui/async-await/drop-track-bad-field-in-fru.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// compile-flags: -Zdrop-tracking
|
||||||
|
// edition: 2021
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
async fn foo() {
|
||||||
|
None { value: (), ..Default::default() }.await;
|
||||||
|
//~^ ERROR `Option<_>` is not a future
|
||||||
|
//~| ERROR variant `Option<_>::None` has no field named `value`
|
||||||
|
}
|
23
src/test/ui/async-await/drop-track-bad-field-in-fru.stderr
Normal file
23
src/test/ui/async-await/drop-track-bad-field-in-fru.stderr
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
error[E0559]: variant `Option<_>::None` has no field named `value`
|
||||||
|
--> $DIR/drop-track-bad-field-in-fru.rs:7:12
|
||||||
|
|
|
||||||
|
LL | None { value: (), ..Default::default() }.await;
|
||||||
|
| ^^^^^ `Option<_>::None` does not have this field
|
||||||
|
|
||||||
|
error[E0277]: `Option<_>` is not a future
|
||||||
|
--> $DIR/drop-track-bad-field-in-fru.rs:7:45
|
||||||
|
|
|
||||||
|
LL | None { value: (), ..Default::default() }.await;
|
||||||
|
| ^^^^^^
|
||||||
|
| |
|
||||||
|
| `Option<_>` is not a future
|
||||||
|
| help: remove the `.await`
|
||||||
|
|
|
||||||
|
= help: the trait `Future` is not implemented for `Option<_>`
|
||||||
|
= note: Option<_> must be a future or must implement `IntoFuture` to be awaited
|
||||||
|
= note: required for `Option<_>` to implement `IntoFuture`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0277, E0559.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,12 @@
|
||||||
|
// check-pass
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
#![allow(incomplete_features, unused_braces)]
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
fn foo<const N: usize>() {
|
||||||
|
bar::<{{{{{{ N }}}}}}>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar<const N: usize>() {}
|
||||||
|
|
||||||
|
fn main() {}
|
12
src/test/ui/structs/unresolved-struct-with-fru.rs
Normal file
12
src/test/ui/structs/unresolved-struct-with-fru.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
struct S {
|
||||||
|
a: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s1 = S { a: 1 };
|
||||||
|
|
||||||
|
let _ = || {
|
||||||
|
let s2 = Oops { a: 2, ..s1 };
|
||||||
|
//~^ ERROR cannot find struct, variant or union type `Oops` in this scope
|
||||||
|
};
|
||||||
|
}
|
9
src/test/ui/structs/unresolved-struct-with-fru.stderr
Normal file
9
src/test/ui/structs/unresolved-struct-with-fru.stderr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0422]: cannot find struct, variant or union type `Oops` in this scope
|
||||||
|
--> $DIR/unresolved-struct-with-fru.rs:9:18
|
||||||
|
|
|
||||||
|
LL | let s2 = Oops { a: 2, ..s1 };
|
||||||
|
| ^^^^ not found in this scope
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0422`.
|
Loading…
Add table
Add a link
Reference in a new issue