Implement .use keyword as an alias of clone
This commit is contained in:
parent
0cf8dbc96c
commit
05c516446a
36 changed files with 247 additions and 24 deletions
|
@ -582,6 +582,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
| ExprKind::Yield { .. }
|
||||
| ExprKind::ThreadLocalRef(_)
|
||||
| ExprKind::Call { .. }
|
||||
| ExprKind::ByUse { .. }
|
||||
| ExprKind::WrapUnsafeBinder { .. } => {
|
||||
// these are not places, so we need to make a temporary.
|
||||
debug_assert!(!matches!(Category::of(&expr.kind), Some(Category::Place)));
|
||||
|
|
|
@ -572,6 +572,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
);
|
||||
block.and(Rvalue::Use(operand))
|
||||
}
|
||||
|
||||
ExprKind::ByUse { expr, span: _ } => {
|
||||
let operand = unpack!(
|
||||
block =
|
||||
this.as_operand(block, scope, expr, LocalInfo::Boring, NeedsTemporary::No)
|
||||
);
|
||||
block.and(Rvalue::Use(operand))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ impl Category {
|
|||
| ExprKind::RawBorrow { .. }
|
||||
| ExprKind::Yield { .. }
|
||||
| ExprKind::Call { .. }
|
||||
| ExprKind::ByUse { .. }
|
||||
| ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::Into)),
|
||||
|
||||
ExprKind::Array { .. }
|
||||
|
|
|
@ -4,10 +4,12 @@ use rustc_ast::{AsmMacro, InlineAsmOptions};
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::thir::*;
|
||||
use rustc_middle::ty::CanonicalUserTypeAnnotation;
|
||||
use rustc_middle::ty::{CanonicalUserTypeAnnotation, Ty};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
@ -289,6 +291,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
this.diverge_from(block);
|
||||
success.unit()
|
||||
}
|
||||
ExprKind::ByUse { expr, span } => {
|
||||
let place = unpack!(block = this.as_place(block, expr));
|
||||
let ty = place.ty(&this.local_decls, this.tcx).ty;
|
||||
|
||||
// Convert `expr.use` to a call like `Clone::clone(&expr)`
|
||||
let success = this.cfg.start_new_block();
|
||||
let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None);
|
||||
let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0];
|
||||
let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span);
|
||||
let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty);
|
||||
let ref_place = this.temp(ref_ty, span);
|
||||
this.cfg.push_assign(
|
||||
block,
|
||||
source_info,
|
||||
ref_place,
|
||||
Rvalue::Ref(this.tcx.lifetimes.re_erased, BorrowKind::Shared, place),
|
||||
);
|
||||
this.cfg.terminate(
|
||||
block,
|
||||
source_info,
|
||||
TerminatorKind::Call {
|
||||
func,
|
||||
args: [Spanned { node: Operand::Move(ref_place), span: DUMMY_SP }].into(),
|
||||
destination,
|
||||
target: Some(success),
|
||||
unwind: UnwindAction::Unreachable,
|
||||
call_source: CallSource::Misc,
|
||||
fn_span: expr_span,
|
||||
},
|
||||
);
|
||||
success.unit()
|
||||
}
|
||||
ExprKind::Use { source } => this.expr_into_dest(destination, block, source),
|
||||
ExprKind::Borrow { arg, borrow_kind } => {
|
||||
// We don't do this in `as_rvalue` because we use `as_place`
|
||||
|
|
|
@ -451,6 +451,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
| ExprKind::Tuple { .. }
|
||||
| ExprKind::Unary { .. }
|
||||
| ExprKind::Call { .. }
|
||||
| ExprKind::ByUse { .. }
|
||||
| ExprKind::Assign { .. }
|
||||
| ExprKind::AssignOp { .. }
|
||||
| ExprKind::Break { .. }
|
||||
|
|
|
@ -464,6 +464,10 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
hir::ExprKind::Use(expr, span) => {
|
||||
ExprKind::ByUse { expr: self.mirror_expr(expr), span }
|
||||
}
|
||||
|
||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, arg) => {
|
||||
ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg: self.mirror_expr(arg) }
|
||||
}
|
||||
|
|
|
@ -345,6 +345,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
|
|||
| Borrow { .. }
|
||||
| Box { .. }
|
||||
| Call { .. }
|
||||
| ByUse { .. }
|
||||
| Closure { .. }
|
||||
| ConstBlock { .. }
|
||||
| ConstParam { .. }
|
||||
|
|
|
@ -246,6 +246,13 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
|||
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
}
|
||||
ByUse { expr, span } => {
|
||||
print_indented!(self, "ByUse {", depth_lvl);
|
||||
print_indented!(self, "expr:", depth_lvl + 1);
|
||||
self.print_expr(*expr, depth_lvl + 2);
|
||||
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
}
|
||||
Deref { arg } => {
|
||||
print_indented!(self, "Deref {", depth_lvl);
|
||||
self.print_expr(*arg, depth_lvl + 1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue