提交 8a624b73 编写于 作者: N Niko Matsakis

change `PointerKind::Implicit` to a note

`PointerKind` is included in `LoanPath` and hence forms part of the
equality check; this led to having two unequal paths that both
represent `*x`, depending on whether the `*` was inserted
automatically or explicitly. Bad mojo. The `note` field, in contrast,
is intended more-or-less primarily for this purpose of adding extra
data.
上级 5d0631a6
...@@ -837,17 +837,24 @@ fn determine_pat_move_mode(&mut self, ...@@ -837,17 +837,24 @@ fn determine_pat_move_mode(&mut self,
/// established up front, e.g. via `determine_pat_move_mode` (see /// established up front, e.g. via `determine_pat_move_mode` (see
/// also `walk_irrefutable_pat` for patterns that stand alone). /// also `walk_irrefutable_pat` for patterns that stand alone).
fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) { fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr, pat); debug!("walk_pat(cmt_discr={:?}, pat={:?})", cmt_discr, pat);
let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self; let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| { return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
if let PatKind::Binding(_, canonical_id, ..) = pat.node { if let PatKind::Binding(_, canonical_id, ..) = pat.node {
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, pat, match_mode); debug!(
"walk_pat: binding cmt_pat={:?} pat={:?} match_mode={:?}",
cmt_pat,
pat,
match_mode,
);
let bm = *mc.tables.pat_binding_modes().get(pat.hir_id) let bm = *mc.tables.pat_binding_modes().get(pat.hir_id)
.expect("missing binding mode"); .expect("missing binding mode");
debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
// pat_ty: the type of the binding being produced. // pat_ty: the type of the binding being produced.
let pat_ty = return_if_err!(mc.node_ty(pat.hir_id)); let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
debug!("walk_pat: pat_ty={:?}", pat_ty);
// Each match binding is effectively an assignment to the // Each match binding is effectively an assignment to the
// binding being produced. // binding being produced.
......
...@@ -95,7 +95,7 @@ pub enum Categorization<'tcx> { ...@@ -95,7 +95,7 @@ pub enum Categorization<'tcx> {
StaticItem, StaticItem,
Upvar(Upvar), // upvar referenced by closure env Upvar(Upvar), // upvar referenced by closure env
Local(ast::NodeId), // local variable Local(ast::NodeId), // local variable
Deref(cmt<'tcx>, PointerKind<'tcx>), // deref of a ptr Deref(cmt<'tcx>, PointerKind<'tcx>), // deref of a ptr
Interior(cmt<'tcx>, InteriorKind), // something interior: field, tuple, etc Interior(cmt<'tcx>, InteriorKind), // something interior: field, tuple, etc
Downcast(cmt<'tcx>, DefId), // selects a particular enum variant (*1) Downcast(cmt<'tcx>, DefId), // selects a particular enum variant (*1)
...@@ -120,9 +120,6 @@ pub enum PointerKind<'tcx> { ...@@ -120,9 +120,6 @@ pub enum PointerKind<'tcx> {
/// `*T` /// `*T`
UnsafePtr(hir::Mutability), UnsafePtr(hir::Mutability),
/// Implicit deref of the `&T` that results from an overloaded index `[]`.
Implicit(ty::BorrowKind, ty::Region<'tcx>),
} }
// We use the term "interior" to mean "something reachable from the // We use the term "interior" to mean "something reachable from the
...@@ -172,6 +169,7 @@ pub enum MutabilityCategory { ...@@ -172,6 +169,7 @@ pub enum MutabilityCategory {
pub enum Note { pub enum Note {
NoteClosureEnv(ty::UpvarId), // Deref through closure env NoteClosureEnv(ty::UpvarId), // Deref through closure env
NoteUpvarRef(ty::UpvarId), // Deref through by-ref upvar NoteUpvarRef(ty::UpvarId), // Deref through by-ref upvar
NoteIndex, // Deref as part of desugaring `x[]` into its two components
NoteNone // Nothing special NoteNone // Nothing special
} }
...@@ -231,8 +229,7 @@ fn resolve_field(&self, field_index: usize) -> Option<(&'tcx ty::AdtDef, &'tcx t ...@@ -231,8 +229,7 @@ fn resolve_field(&self, field_index: usize) -> Option<(&'tcx ty::AdtDef, &'tcx t
pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> { pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> {
match self.cat { match self.cat {
Categorization::Deref(ref base_cmt, BorrowedPtr(ty::ImmBorrow, _)) | Categorization::Deref(ref base_cmt, BorrowedPtr(ty::ImmBorrow, _)) => {
Categorization::Deref(ref base_cmt, Implicit(ty::ImmBorrow, _)) => {
// try to figure out where the immutable reference came from // try to figure out where the immutable reference came from
match base_cmt.cat { match base_cmt.cat {
Categorization::Local(node_id) => Categorization::Local(node_id) =>
...@@ -328,7 +325,7 @@ fn from_pointer_kind(base_mutbl: MutabilityCategory, ...@@ -328,7 +325,7 @@ fn from_pointer_kind(base_mutbl: MutabilityCategory,
Unique => { Unique => {
base_mutbl.inherit() base_mutbl.inherit()
} }
BorrowedPtr(borrow_kind, _) | Implicit(borrow_kind, _) => { BorrowedPtr(borrow_kind, _) => {
MutabilityCategory::from_borrow_kind(borrow_kind) MutabilityCategory::from_borrow_kind(borrow_kind)
} }
UnsafePtr(m) => { UnsafePtr(m) => {
...@@ -617,7 +614,7 @@ fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr, ...@@ -617,7 +614,7 @@ fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
} else { } else {
previous()? previous()?
}); });
self.cat_deref(expr, base, false) self.cat_deref(expr, base, NoteNone)
} }
adjustment::Adjust::NeverToAny | adjustment::Adjust::NeverToAny |
...@@ -640,10 +637,10 @@ pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> { ...@@ -640,10 +637,10 @@ pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> {
match expr.node { match expr.node {
hir::ExprUnary(hir::UnDeref, ref e_base) => { hir::ExprUnary(hir::UnDeref, ref e_base) => {
if self.tables.is_method_call(expr) { if self.tables.is_method_call(expr) {
self.cat_overloaded_place(expr, e_base, false) self.cat_overloaded_place(expr, e_base, NoteNone)
} else { } else {
let base_cmt = Rc::new(self.cat_expr(&e_base)?); let base_cmt = Rc::new(self.cat_expr(&e_base)?);
self.cat_deref(expr, base_cmt, false) self.cat_deref(expr, base_cmt, NoteNone)
} }
} }
...@@ -664,7 +661,7 @@ pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> { ...@@ -664,7 +661,7 @@ pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> {
// The call to index() returns a `&T` value, which // The call to index() returns a `&T` value, which
// is an rvalue. That is what we will be // is an rvalue. That is what we will be
// dereferencing. // dereferencing.
self.cat_overloaded_place(expr, base, true) self.cat_overloaded_place(expr, base, NoteIndex)
} else { } else {
let base_cmt = Rc::new(self.cat_expr(&base)?); let base_cmt = Rc::new(self.cat_expr(&base)?);
self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index) self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index)
...@@ -999,12 +996,18 @@ pub fn cat_field<N:ast_node>(&self, ...@@ -999,12 +996,18 @@ pub fn cat_field<N:ast_node>(&self,
ret ret
} }
fn cat_overloaded_place(&self, fn cat_overloaded_place(
expr: &hir::Expr, &self,
base: &hir::Expr, expr: &hir::Expr,
implicit: bool) base: &hir::Expr,
-> McResult<cmt_<'tcx>> { note: Note,
debug!("cat_overloaded_place: implicit={}", implicit); ) -> McResult<cmt_<'tcx>> {
debug!(
"cat_overloaded_place(expr={:?}, base={:?}, note={:?})",
expr,
base,
note,
);
// Reconstruct the output assuming it's a reference with the // Reconstruct the output assuming it's a reference with the
// same region and mutability as the receiver. This holds for // same region and mutability as the receiver. This holds for
...@@ -1024,14 +1027,15 @@ fn cat_overloaded_place(&self, ...@@ -1024,14 +1027,15 @@ fn cat_overloaded_place(&self,
}); });
let base_cmt = Rc::new(self.cat_rvalue_node(expr.id, expr.span, ref_ty)); let base_cmt = Rc::new(self.cat_rvalue_node(expr.id, expr.span, ref_ty));
self.cat_deref(expr, base_cmt, implicit) self.cat_deref(expr, base_cmt, note)
} }
pub fn cat_deref<N:ast_node>(&self, pub fn cat_deref(
node: &N, &self,
base_cmt: cmt<'tcx>, node: &impl ast_node,
implicit: bool) base_cmt: cmt<'tcx>,
-> McResult<cmt_<'tcx>> { note: Note,
) -> McResult<cmt_<'tcx>> {
debug!("cat_deref: base_cmt={:?}", base_cmt); debug!("cat_deref: base_cmt={:?}", base_cmt);
let base_cmt_ty = base_cmt.ty; let base_cmt_ty = base_cmt.ty;
...@@ -1049,7 +1053,7 @@ pub fn cat_deref<N:ast_node>(&self, ...@@ -1049,7 +1053,7 @@ pub fn cat_deref<N:ast_node>(&self,
ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl), ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl),
ty::TyRef(r, _, mutbl) => { ty::TyRef(r, _, mutbl) => {
let bk = ty::BorrowKind::from_mutbl(mutbl); let bk = ty::BorrowKind::from_mutbl(mutbl);
if implicit { Implicit(bk, r) } else { BorrowedPtr(bk, r) } BorrowedPtr(bk, r)
} }
ref ty => bug!("unexpected type in cat_deref: {:?}", ty) ref ty => bug!("unexpected type in cat_deref: {:?}", ty)
}; };
...@@ -1060,7 +1064,7 @@ pub fn cat_deref<N:ast_node>(&self, ...@@ -1060,7 +1064,7 @@ pub fn cat_deref<N:ast_node>(&self,
mutbl: MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr), mutbl: MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr),
cat: Categorization::Deref(base_cmt, ptr), cat: Categorization::Deref(base_cmt, ptr),
ty: deref_ty, ty: deref_ty,
note: NoteNone note: note,
}; };
debug!("cat_deref ret {:?}", ret); debug!("cat_deref ret {:?}", ret);
Ok(ret) Ok(ret)
...@@ -1193,7 +1197,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR ...@@ -1193,7 +1197,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
// step out of sync again. So you'll see below that we always // step out of sync again. So you'll see below that we always
// get the type of the *subpattern* and use that. // get the type of the *subpattern* and use that.
debug!("cat_pattern: {:?} cmt={:?}", pat, cmt); debug!("cat_pattern(pat={:?}, cmt={:?})", pat, cmt);
// If (pattern) adjustments are active for this pattern, adjust the `cmt` correspondingly. // If (pattern) adjustments are active for this pattern, adjust the `cmt` correspondingly.
// `cmt`s are constructed differently from patterns. For example, in // `cmt`s are constructed differently from patterns. For example, in
...@@ -1231,10 +1235,13 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR ...@@ -1231,10 +1235,13 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
.pat_adjustments() .pat_adjustments()
.get(pat.hir_id) .get(pat.hir_id)
.map(|v| v.len()) .map(|v| v.len())
.unwrap_or(0) { .unwrap_or(0)
cmt = Rc::new(self.cat_deref(pat, cmt, true /* implicit */)?); {
debug!("cat_pattern: applying adjustment to cmt={:?}", cmt);
cmt = Rc::new(self.cat_deref(pat, cmt, NoteNone)?);
} }
let cmt = cmt; // lose mutability let cmt = cmt; // lose mutability
debug!("cat_pattern: applied adjustment derefs to get cmt={:?}", cmt);
// Invoke the callback, but only now, after the `cmt` has adjusted. // Invoke the callback, but only now, after the `cmt` has adjusted.
// //
...@@ -1330,7 +1337,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR ...@@ -1330,7 +1337,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
// box p1, &p1, &mut p1. we can ignore the mutability of // box p1, &p1, &mut p1. we can ignore the mutability of
// PatKind::Ref since that information is already contained // PatKind::Ref since that information is already contained
// in the type. // in the type.
let subcmt = Rc::new(self.cat_deref(pat, cmt, false)?); let subcmt = Rc::new(self.cat_deref(pat, cmt, NoteNone)?);
self.cat_pattern_(subcmt, &subpat, op)?; self.cat_pattern_(subcmt, &subpat, op)?;
} }
...@@ -1391,7 +1398,6 @@ pub fn guarantor(&self) -> cmt_<'tcx> { ...@@ -1391,7 +1398,6 @@ pub fn guarantor(&self) -> cmt_<'tcx> {
Categorization::Local(..) | Categorization::Local(..) |
Categorization::Deref(_, UnsafePtr(..)) | Categorization::Deref(_, UnsafePtr(..)) |
Categorization::Deref(_, BorrowedPtr(..)) | Categorization::Deref(_, BorrowedPtr(..)) |
Categorization::Deref(_, Implicit(..)) |
Categorization::Upvar(..) => { Categorization::Upvar(..) => {
(*self).clone() (*self).clone()
} }
...@@ -1411,9 +1417,7 @@ pub fn freely_aliasable(&self) -> Aliasability { ...@@ -1411,9 +1417,7 @@ pub fn freely_aliasable(&self) -> Aliasability {
match self.cat { match self.cat {
Categorization::Deref(ref b, BorrowedPtr(ty::MutBorrow, _)) | Categorization::Deref(ref b, BorrowedPtr(ty::MutBorrow, _)) |
Categorization::Deref(ref b, Implicit(ty::MutBorrow, _)) |
Categorization::Deref(ref b, BorrowedPtr(ty::UniqueImmBorrow, _)) | Categorization::Deref(ref b, BorrowedPtr(ty::UniqueImmBorrow, _)) |
Categorization::Deref(ref b, Implicit(ty::UniqueImmBorrow, _)) |
Categorization::Deref(ref b, Unique) | Categorization::Deref(ref b, Unique) |
Categorization::Downcast(ref b, _) | Categorization::Downcast(ref b, _) |
Categorization::Interior(ref b, _) => { Categorization::Interior(ref b, _) => {
...@@ -1436,8 +1440,7 @@ pub fn freely_aliasable(&self) -> Aliasability { ...@@ -1436,8 +1440,7 @@ pub fn freely_aliasable(&self) -> Aliasability {
} }
} }
Categorization::Deref(_, BorrowedPtr(ty::ImmBorrow, _)) | Categorization::Deref(_, BorrowedPtr(ty::ImmBorrow, _)) => {
Categorization::Deref(_, Implicit(ty::ImmBorrow, _)) => {
FreelyAliasable(AliasableBorrowed) FreelyAliasable(AliasableBorrowed)
} }
} }
...@@ -1460,7 +1463,7 @@ pub fn upvar_cat(&self) -> Option<&Categorization<'tcx>> { ...@@ -1460,7 +1463,7 @@ pub fn upvar_cat(&self) -> Option<&Categorization<'tcx>> {
_ => bug!() _ => bug!()
}) })
} }
NoteNone => None NoteIndex | NoteNone => None
} }
} }
...@@ -1487,9 +1490,6 @@ pub fn descriptive_string(&self, tcx: TyCtxt) -> String { ...@@ -1487,9 +1490,6 @@ pub fn descriptive_string(&self, tcx: TyCtxt) -> String {
Some(_) => bug!(), Some(_) => bug!(),
None => { None => {
match pk { match pk {
Implicit(..) => {
format!("indexed content")
}
Unique => { Unique => {
format!("`Box` content") format!("`Box` content")
} }
...@@ -1497,7 +1497,10 @@ pub fn descriptive_string(&self, tcx: TyCtxt) -> String { ...@@ -1497,7 +1497,10 @@ pub fn descriptive_string(&self, tcx: TyCtxt) -> String {
format!("dereference of raw pointer") format!("dereference of raw pointer")
} }
BorrowedPtr(..) => { BorrowedPtr(..) => {
format!("borrowed content") match self.note {
NoteIndex => format!("indexed content"),
_ => format!("borrowed content"),
}
} }
} }
} }
...@@ -1525,12 +1528,9 @@ pub fn descriptive_string(&self, tcx: TyCtxt) -> String { ...@@ -1525,12 +1528,9 @@ pub fn descriptive_string(&self, tcx: TyCtxt) -> String {
pub fn ptr_sigil(ptr: PointerKind) -> &'static str { pub fn ptr_sigil(ptr: PointerKind) -> &'static str {
match ptr { match ptr {
Unique => "Box", Unique => "Box",
BorrowedPtr(ty::ImmBorrow, _) | BorrowedPtr(ty::ImmBorrow, _) => "&",
Implicit(ty::ImmBorrow, _) => "&", BorrowedPtr(ty::MutBorrow, _) => "&mut",
BorrowedPtr(ty::MutBorrow, _) | BorrowedPtr(ty::UniqueImmBorrow, _) => "&unique",
Implicit(ty::MutBorrow, _) => "&mut",
BorrowedPtr(ty::UniqueImmBorrow, _) |
Implicit(ty::UniqueImmBorrow, _) => "&unique",
UnsafePtr(_) => "*", UnsafePtr(_) => "*",
} }
} }
......
...@@ -137,17 +137,30 @@ fn mark_error(&mut self, err: SelectionError<'tcx>) { ...@@ -137,17 +137,30 @@ fn mark_error(&mut self, err: SelectionError<'tcx>) {
fn push_candidate(&mut self, candidate: ProjectionTyCandidate<'tcx>) -> bool { fn push_candidate(&mut self, candidate: ProjectionTyCandidate<'tcx>) -> bool {
use self::ProjectionTyCandidateSet::*; use self::ProjectionTyCandidateSet::*;
use self::ProjectionTyCandidate::*; use self::ProjectionTyCandidate::*;
// This wacky variable is just used to try and
// make code readable and avoid confusing paths.
// It is assigned a "value" of `()` only on those
// paths in which we wish to convert `*self` to
// ambiguous (and return false, because the candidate
// was not used). On other paths, it is not assigned,
// and hence if those paths *could* reach the code that
// comes after the match, this fn would not compile.
let convert_to_ambigious;
match self { match self {
None => { None => {
*self = Single(candidate); *self = Single(candidate);
true return true;
} }
Single(current) => { Single(current) => {
// Duplicates can happen inside ParamEnv. In the case, we // Duplicates can happen inside ParamEnv. In the case, we
// perform a lazy deduplication. // perform a lazy deduplication.
if current == &candidate { if current == &candidate {
return false; return false;
} }
// Prefer where-clauses. As in select, if there are multiple // Prefer where-clauses. As in select, if there are multiple
// candidates, we prefer where-clause candidates over impls. This // candidates, we prefer where-clause candidates over impls. This
// may seem a bit surprising, since impls are the source of // may seem a bit surprising, since impls are the source of
...@@ -156,17 +169,23 @@ fn push_candidate(&mut self, candidate: ProjectionTyCandidate<'tcx>) -> bool { ...@@ -156,17 +169,23 @@ fn push_candidate(&mut self, candidate: ProjectionTyCandidate<'tcx>) -> bool {
// clauses are the safer choice. See the comment on // clauses are the safer choice. See the comment on
// `select::SelectionCandidate` and #21974 for more details. // `select::SelectionCandidate` and #21974 for more details.
match (current, candidate) { match (current, candidate) {
(ParamEnv(..), ParamEnv(..)) => { *self = Ambiguous; } (ParamEnv(..), ParamEnv(..)) => convert_to_ambigious = (),
(ParamEnv(..), _) => {} (ParamEnv(..), _) => return false,
(_, ParamEnv(..)) => { unreachable!(); } (_, ParamEnv(..)) => { unreachable!(); }
(_, _) => { *self = Ambiguous; } (_, _) => convert_to_ambigious = (),
} }
false
} }
Ambiguous | Error(..) => { Ambiguous | Error(..) => {
false return false;
} }
} }
// We only ever get here when we moved from a single candidate
// to ambiguous.
let () = convert_to_ambigious;
*self = Ambiguous;
false
} }
} }
......
...@@ -180,7 +180,6 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, ...@@ -180,7 +180,6 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
-> Option<mc::cmt_<'tcx>> { -> Option<mc::cmt_<'tcx>> {
match cmt.cat { match cmt.cat {
Categorization::Deref(_, mc::BorrowedPtr(..)) | Categorization::Deref(_, mc::BorrowedPtr(..)) |
Categorization::Deref(_, mc::Implicit(..)) |
Categorization::Deref(_, mc::UnsafePtr(..)) | Categorization::Deref(_, mc::UnsafePtr(..)) |
Categorization::StaticItem => { Categorization::StaticItem => {
Some(cmt.clone()) Some(cmt.clone())
......
...@@ -74,7 +74,6 @@ fn check(&self, cmt: &mc::cmt_<'tcx>, discr_scope: Option<ast::NodeId>) -> R { ...@@ -74,7 +74,6 @@ fn check(&self, cmt: &mc::cmt_<'tcx>, discr_scope: Option<ast::NodeId>) -> R {
Categorization::Local(..) | // L-Local Categorization::Local(..) | // L-Local
Categorization::Upvar(..) | Categorization::Upvar(..) |
Categorization::Deref(_, mc::BorrowedPtr(..)) | // L-Deref-Borrowed Categorization::Deref(_, mc::BorrowedPtr(..)) | // L-Deref-Borrowed
Categorization::Deref(_, mc::Implicit(..)) |
Categorization::Deref(_, mc::UnsafePtr(..)) => { Categorization::Deref(_, mc::UnsafePtr(..)) => {
self.check_scope(self.scope(cmt)) self.check_scope(self.scope(cmt))
} }
...@@ -122,8 +121,7 @@ fn scope(&self, cmt: &mc::cmt_<'tcx>) -> ty::Region<'tcx> { ...@@ -122,8 +121,7 @@ fn scope(&self, cmt: &mc::cmt_<'tcx>) -> ty::Region<'tcx> {
Categorization::Deref(_, mc::UnsafePtr(..)) => { Categorization::Deref(_, mc::UnsafePtr(..)) => {
self.bccx.tcx.types.re_static self.bccx.tcx.types.re_static
} }
Categorization::Deref(_, mc::BorrowedPtr(_, r)) | Categorization::Deref(_, mc::BorrowedPtr(_, r)) => {
Categorization::Deref(_, mc::Implicit(_, r)) => {
r r
} }
Categorization::Downcast(ref cmt, _) | Categorization::Downcast(ref cmt, _) |
......
...@@ -140,7 +140,6 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>, ...@@ -140,7 +140,6 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>,
-> DiagnosticBuilder<'a> { -> DiagnosticBuilder<'a> {
match move_from.cat { match move_from.cat {
Categorization::Deref(_, mc::BorrowedPtr(..)) | Categorization::Deref(_, mc::BorrowedPtr(..)) |
Categorization::Deref(_, mc::Implicit(..)) |
Categorization::Deref(_, mc::UnsafePtr(..)) | Categorization::Deref(_, mc::UnsafePtr(..)) |
Categorization::StaticItem => { Categorization::StaticItem => {
bccx.cannot_move_out_of( bccx.cannot_move_out_of(
......
...@@ -149,7 +149,7 @@ fn restrict(&self, ...@@ -149,7 +149,7 @@ fn restrict(&self,
let result = self.restrict(&cmt_base); let result = self.restrict(&cmt_base);
self.extend(result, &cmt, LpDeref(pk)) self.extend(result, &cmt, LpDeref(pk))
} }
mc::Implicit(bk, lt) | mc::BorrowedPtr(bk, lt) => { mc::BorrowedPtr(bk, lt) => {
// R-Deref-[Mut-]Borrowed // R-Deref-[Mut-]Borrowed
if !self.bccx.is_subregion_of(self.loan_region, lt) { if !self.bccx.is_subregion_of(self.loan_region, lt) {
self.bccx.report( self.bccx.report(
......
...@@ -234,6 +234,7 @@ pub fn check_pat_walk( ...@@ -234,6 +234,7 @@ pub fn check_pat_walk(
.borrow_mut() .borrow_mut()
.pat_binding_modes_mut() .pat_binding_modes_mut()
.insert(pat.hir_id, bm); .insert(pat.hir_id, bm);
debug!("check_pat_walk: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
let typ = self.local_ty(pat.span, pat.id); let typ = self.local_ty(pat.span, pat.id);
match bm { match bm {
ty::BindByReference(mutbl) => { ty::BindByReference(mutbl) => {
......
...@@ -1111,7 +1111,6 @@ fn link_region(&self, ...@@ -1111,7 +1111,6 @@ fn link_region(&self,
borrow_kind, borrow_kind,
borrow_cmt); borrow_cmt);
match borrow_cmt_cat { match borrow_cmt_cat {
Categorization::Deref(ref_cmt, mc::Implicit(ref_kind, ref_region)) |
Categorization::Deref(ref_cmt, mc::BorrowedPtr(ref_kind, ref_region)) => { Categorization::Deref(ref_cmt, mc::BorrowedPtr(ref_kind, ref_region)) => {
match self.link_reborrowed_region(span, match self.link_reborrowed_region(span,
borrow_region, borrow_kind, borrow_region, borrow_kind,
......
...@@ -332,8 +332,7 @@ fn adjust_upvar_borrow_kind_for_consume(&mut self, cmt: &mc::cmt_<'tcx>, ...@@ -332,8 +332,7 @@ fn adjust_upvar_borrow_kind_for_consume(&mut self, cmt: &mc::cmt_<'tcx>,
guarantor.cat guarantor.cat
); );
match guarantor.cat { match guarantor.cat {
Categorization::Deref(_, mc::BorrowedPtr(..)) | Categorization::Deref(_, mc::BorrowedPtr(..)) => {
Categorization::Deref(_, mc::Implicit(..)) => {
debug!( debug!(
"adjust_upvar_borrow_kind_for_consume: found deref with note {:?}", "adjust_upvar_borrow_kind_for_consume: found deref with note {:?}",
cmt.note cmt.note
...@@ -371,7 +370,7 @@ fn adjust_upvar_borrow_kind_for_consume(&mut self, cmt: &mc::cmt_<'tcx>, ...@@ -371,7 +370,7 @@ fn adjust_upvar_borrow_kind_for_consume(&mut self, cmt: &mc::cmt_<'tcx>,
var_name(tcx, upvar_id.var_id), var_name(tcx, upvar_id.var_id),
); );
} }
mc::NoteNone => {} mc::NoteIndex | mc::NoteNone => {}
} }
} }
_ => {} _ => {}
...@@ -393,8 +392,7 @@ fn adjust_upvar_borrow_kind_for_mut(&mut self, cmt: &mc::cmt_<'tcx>) { ...@@ -393,8 +392,7 @@ fn adjust_upvar_borrow_kind_for_mut(&mut self, cmt: &mc::cmt_<'tcx>) {
self.adjust_upvar_borrow_kind_for_mut(&base); self.adjust_upvar_borrow_kind_for_mut(&base);
} }
Categorization::Deref(base, mc::BorrowedPtr(..)) | Categorization::Deref(base, mc::BorrowedPtr(..)) => {
Categorization::Deref(base, mc::Implicit(..)) => {
if !self.try_adjust_upvar_deref(cmt, ty::MutBorrow) { if !self.try_adjust_upvar_deref(cmt, ty::MutBorrow) {
// assignment to deref of an `&mut` // assignment to deref of an `&mut`
// borrowed pointer implies that the // borrowed pointer implies that the
...@@ -426,8 +424,7 @@ fn adjust_upvar_borrow_kind_for_unique(&mut self, cmt: &mc::cmt_<'tcx>) { ...@@ -426,8 +424,7 @@ fn adjust_upvar_borrow_kind_for_unique(&mut self, cmt: &mc::cmt_<'tcx>) {
self.adjust_upvar_borrow_kind_for_unique(&base); self.adjust_upvar_borrow_kind_for_unique(&base);
} }
Categorization::Deref(base, mc::BorrowedPtr(..)) | Categorization::Deref(base, mc::BorrowedPtr(..)) => {
Categorization::Deref(base, mc::Implicit(..)) => {
if !self.try_adjust_upvar_deref(cmt, ty::UniqueImmBorrow) { if !self.try_adjust_upvar_deref(cmt, ty::UniqueImmBorrow) {
// for a borrowed pointer to be unique, its // for a borrowed pointer to be unique, its
// base must be unique // base must be unique
...@@ -487,7 +484,7 @@ fn try_adjust_upvar_deref(&mut self, cmt: &mc::cmt_<'tcx>, borrow_kind: ty::Borr ...@@ -487,7 +484,7 @@ fn try_adjust_upvar_deref(&mut self, cmt: &mc::cmt_<'tcx>, borrow_kind: ty::Borr
true true
} }
mc::NoteNone => false, mc::NoteIndex | mc::NoteNone => false,
} }
} }
......
error[E0499]: cannot borrow `*bar` as mutable more than once at a time
--> $DIR/issue-51117.rs:20:13
|
LL | Some(baz) => {
| --- first mutable borrow occurs here
LL | bar.take(); //~ ERROR cannot borrow
| ^^^ second mutable borrow occurs here
LL | drop(baz);
| --- borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0499`.
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Regression test for #51117 in borrowck interaction with match
// default bindings. The borrow of `*bar` created by `baz` was failing
// to register as a conflict with `bar.take()`.
fn main() {
let mut foo = Some("foo".to_string());
let bar = &mut foo;
match bar {
Some(baz) => {
bar.take(); //~ ERROR cannot borrow
drop(baz);
},
None => unreachable!(),
}
}
error[E0499]: cannot borrow `*bar` as mutable more than once at a time
--> $DIR/issue-51117.rs:20:13
|
LL | Some(baz) => {
| --- first mutable borrow occurs here
LL | bar.take(); //~ ERROR cannot borrow
| ^^^ second mutable borrow occurs here
...
LL | }
| - first borrow ends here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0499`.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册