rustc_borrowck
: remove ref
patterns
This commit is contained in:
parent
c5351ad4dc
commit
c75817fb1b
13 changed files with 145 additions and 160 deletions
|
@ -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`.
|
||||||
|
|
Loading…
Add table
Reference in a new issue