Skip to content

Commit d290217

Browse files
nikomatsakispietroalbini
authored andcommitted
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.
1 parent 561310c commit d290217

File tree

13 files changed

+139
-68
lines changed

13 files changed

+139
-68
lines changed

src/librustc/middle/expr_use_visitor.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -837,17 +837,24 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
837837
/// established up front, e.g. via `determine_pat_move_mode` (see
838838
/// also `walk_irrefutable_pat` for patterns that stand alone).
839839
fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
840-
debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr, pat);
840+
debug!("walk_pat(cmt_discr={:?}, pat={:?})", cmt_discr, pat);
841841

842842
let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
843843
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
844844
if let PatKind::Binding(_, canonical_id, ..) = pat.node {
845-
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, pat, match_mode);
845+
debug!(
846+
"walk_pat: binding cmt_pat={:?} pat={:?} match_mode={:?}",
847+
cmt_pat,
848+
pat,
849+
match_mode,
850+
);
846851
let bm = *mc.tables.pat_binding_modes().get(pat.hir_id)
847852
.expect("missing binding mode");
853+
debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
848854

849855
// pat_ty: the type of the binding being produced.
850856
let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
857+
debug!("walk_pat: pat_ty={:?}", pat_ty);
851858

852859
// Each match binding is effectively an assignment to the
853860
// binding being produced.

src/librustc/middle/mem_categorization.rs

+45-45
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ pub enum Categorization<'tcx> {
9595
StaticItem,
9696
Upvar(Upvar), // upvar referenced by closure env
9797
Local(ast::NodeId), // local variable
98-
Deref(cmt<'tcx>, PointerKind<'tcx>), // deref of a ptr
98+
Deref(cmt<'tcx>, PointerKind<'tcx>), // deref of a ptr
9999
Interior(cmt<'tcx>, InteriorKind), // something interior: field, tuple, etc
100100
Downcast(cmt<'tcx>, DefId), // selects a particular enum variant (*1)
101101

@@ -120,9 +120,6 @@ pub enum PointerKind<'tcx> {
120120

121121
/// `*T`
122122
UnsafePtr(hir::Mutability),
123-
124-
/// Implicit deref of the `&T` that results from an overloaded index `[]`.
125-
Implicit(ty::BorrowKind, ty::Region<'tcx>),
126123
}
127124

128125
// We use the term "interior" to mean "something reachable from the
@@ -172,6 +169,7 @@ pub enum MutabilityCategory {
172169
pub enum Note {
173170
NoteClosureEnv(ty::UpvarId), // Deref through closure env
174171
NoteUpvarRef(ty::UpvarId), // Deref through by-ref upvar
172+
NoteIndex, // Deref as part of desugaring `x[]` into its two components
175173
NoteNone // Nothing special
176174
}
177175

@@ -231,8 +229,7 @@ impl<'tcx> cmt_<'tcx> {
231229

232230
pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> {
233231
match self.cat {
234-
Categorization::Deref(ref base_cmt, BorrowedPtr(ty::ImmBorrow, _)) |
235-
Categorization::Deref(ref base_cmt, Implicit(ty::ImmBorrow, _)) => {
232+
Categorization::Deref(ref base_cmt, BorrowedPtr(ty::ImmBorrow, _)) => {
236233
// try to figure out where the immutable reference came from
237234
match base_cmt.cat {
238235
Categorization::Local(node_id) =>
@@ -328,7 +325,7 @@ impl MutabilityCategory {
328325
Unique => {
329326
base_mutbl.inherit()
330327
}
331-
BorrowedPtr(borrow_kind, _) | Implicit(borrow_kind, _) => {
328+
BorrowedPtr(borrow_kind, _) => {
332329
MutabilityCategory::from_borrow_kind(borrow_kind)
333330
}
334331
UnsafePtr(m) => {
@@ -617,7 +614,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
617614
} else {
618615
previous()?
619616
});
620-
self.cat_deref(expr, base, false)
617+
self.cat_deref(expr, base, NoteNone)
621618
}
622619

623620
adjustment::Adjust::NeverToAny |
@@ -640,10 +637,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
640637
match expr.node {
641638
hir::ExprUnary(hir::UnDeref, ref e_base) => {
642639
if self.tables.is_method_call(expr) {
643-
self.cat_overloaded_place(expr, e_base, false)
640+
self.cat_overloaded_place(expr, e_base, NoteNone)
644641
} else {
645642
let base_cmt = Rc::new(self.cat_expr(&e_base)?);
646-
self.cat_deref(expr, base_cmt, false)
643+
self.cat_deref(expr, base_cmt, NoteNone)
647644
}
648645
}
649646

@@ -664,7 +661,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
664661
// The call to index() returns a `&T` value, which
665662
// is an rvalue. That is what we will be
666663
// dereferencing.
667-
self.cat_overloaded_place(expr, base, true)
664+
self.cat_overloaded_place(expr, base, NoteIndex)
668665
} else {
669666
let base_cmt = Rc::new(self.cat_expr(&base)?);
670667
self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index)
@@ -998,12 +995,18 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
998995
ret
999996
}
1000997

1001-
fn cat_overloaded_place(&self,
1002-
expr: &hir::Expr,
1003-
base: &hir::Expr,
1004-
implicit: bool)
1005-
-> McResult<cmt_<'tcx>> {
1006-
debug!("cat_overloaded_place: implicit={}", implicit);
998+
fn cat_overloaded_place(
999+
&self,
1000+
expr: &hir::Expr,
1001+
base: &hir::Expr,
1002+
note: Note,
1003+
) -> McResult<cmt_<'tcx>> {
1004+
debug!(
1005+
"cat_overloaded_place(expr={:?}, base={:?}, note={:?})",
1006+
expr,
1007+
base,
1008+
note,
1009+
);
10071010

10081011
// Reconstruct the output assuming it's a reference with the
10091012
// same region and mutability as the receiver. This holds for
@@ -1023,14 +1026,15 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10231026
});
10241027

10251028
let base_cmt = Rc::new(self.cat_rvalue_node(expr.id, expr.span, ref_ty));
1026-
self.cat_deref(expr, base_cmt, implicit)
1029+
self.cat_deref(expr, base_cmt, note)
10271030
}
10281031

1029-
pub fn cat_deref<N:ast_node>(&self,
1030-
node: &N,
1031-
base_cmt: cmt<'tcx>,
1032-
implicit: bool)
1033-
-> McResult<cmt_<'tcx>> {
1032+
pub fn cat_deref(
1033+
&self,
1034+
node: &impl ast_node,
1035+
base_cmt: cmt<'tcx>,
1036+
note: Note,
1037+
) -> McResult<cmt_<'tcx>> {
10341038
debug!("cat_deref: base_cmt={:?}", base_cmt);
10351039

10361040
let base_cmt_ty = base_cmt.ty;
@@ -1048,7 +1052,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10481052
ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl),
10491053
ty::TyRef(r, mt) => {
10501054
let bk = ty::BorrowKind::from_mutbl(mt.mutbl);
1051-
if implicit { Implicit(bk, r) } else { BorrowedPtr(bk, r) }
1055+
BorrowedPtr(bk, r)
10521056
}
10531057
ref ty => bug!("unexpected type in cat_deref: {:?}", ty)
10541058
};
@@ -1059,7 +1063,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10591063
mutbl: MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr),
10601064
cat: Categorization::Deref(base_cmt, ptr),
10611065
ty: deref_ty,
1062-
note: NoteNone
1066+
note: note,
10631067
};
10641068
debug!("cat_deref ret {:?}", ret);
10651069
Ok(ret)
@@ -1192,7 +1196,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
11921196
// step out of sync again. So you'll see below that we always
11931197
// get the type of the *subpattern* and use that.
11941198

1195-
debug!("cat_pattern: {:?} cmt={:?}", pat, cmt);
1199+
debug!("cat_pattern(pat={:?}, cmt={:?})", pat, cmt);
11961200

11971201
// If (pattern) adjustments are active for this pattern, adjust the `cmt` correspondingly.
11981202
// `cmt`s are constructed differently from patterns. For example, in
@@ -1230,10 +1234,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
12301234
.pat_adjustments()
12311235
.get(pat.hir_id)
12321236
.map(|v| v.len())
1233-
.unwrap_or(0) {
1234-
cmt = Rc::new(self.cat_deref(pat, cmt, true /* implicit */)?);
1237+
.unwrap_or(0)
1238+
{
1239+
debug!("cat_pattern: applying adjustment to cmt={:?}", cmt);
1240+
cmt = Rc::new(self.cat_deref(pat, cmt, NoteNone)?);
12351241
}
12361242
let cmt = cmt; // lose mutability
1243+
debug!("cat_pattern: applied adjustment derefs to get cmt={:?}", cmt);
12371244

12381245
// Invoke the callback, but only now, after the `cmt` has adjusted.
12391246
//
@@ -1329,7 +1336,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
13291336
// box p1, &p1, &mut p1. we can ignore the mutability of
13301337
// PatKind::Ref since that information is already contained
13311338
// in the type.
1332-
let subcmt = Rc::new(self.cat_deref(pat, cmt, false)?);
1339+
let subcmt = Rc::new(self.cat_deref(pat, cmt, NoteNone)?);
13331340
self.cat_pattern_(subcmt, &subpat, op)?;
13341341
}
13351342

@@ -1390,7 +1397,6 @@ impl<'tcx> cmt_<'tcx> {
13901397
Categorization::Local(..) |
13911398
Categorization::Deref(_, UnsafePtr(..)) |
13921399
Categorization::Deref(_, BorrowedPtr(..)) |
1393-
Categorization::Deref(_, Implicit(..)) |
13941400
Categorization::Upvar(..) => {
13951401
(*self).clone()
13961402
}
@@ -1410,9 +1416,7 @@ impl<'tcx> cmt_<'tcx> {
14101416

14111417
match self.cat {
14121418
Categorization::Deref(ref b, BorrowedPtr(ty::MutBorrow, _)) |
1413-
Categorization::Deref(ref b, Implicit(ty::MutBorrow, _)) |
14141419
Categorization::Deref(ref b, BorrowedPtr(ty::UniqueImmBorrow, _)) |
1415-
Categorization::Deref(ref b, Implicit(ty::UniqueImmBorrow, _)) |
14161420
Categorization::Deref(ref b, Unique) |
14171421
Categorization::Downcast(ref b, _) |
14181422
Categorization::Interior(ref b, _) => {
@@ -1435,8 +1439,7 @@ impl<'tcx> cmt_<'tcx> {
14351439
}
14361440
}
14371441

1438-
Categorization::Deref(_, BorrowedPtr(ty::ImmBorrow, _)) |
1439-
Categorization::Deref(_, Implicit(ty::ImmBorrow, _)) => {
1442+
Categorization::Deref(_, BorrowedPtr(ty::ImmBorrow, _)) => {
14401443
FreelyAliasable(AliasableBorrowed)
14411444
}
14421445
}
@@ -1459,7 +1462,7 @@ impl<'tcx> cmt_<'tcx> {
14591462
_ => bug!()
14601463
})
14611464
}
1462-
NoteNone => None
1465+
NoteIndex | NoteNone => None
14631466
}
14641467
}
14651468

@@ -1486,17 +1489,17 @@ impl<'tcx> cmt_<'tcx> {
14861489
Some(_) => bug!(),
14871490
None => {
14881491
match pk {
1489-
Implicit(..) => {
1490-
format!("indexed content")
1491-
}
14921492
Unique => {
14931493
format!("`Box` content")
14941494
}
14951495
UnsafePtr(..) => {
14961496
format!("dereference of raw pointer")
14971497
}
14981498
BorrowedPtr(..) => {
1499-
format!("borrowed content")
1499+
match self.note {
1500+
NoteIndex => format!("indexed content"),
1501+
_ => format!("borrowed content"),
1502+
}
15001503
}
15011504
}
15021505
}
@@ -1524,12 +1527,9 @@ impl<'tcx> cmt_<'tcx> {
15241527
pub fn ptr_sigil(ptr: PointerKind) -> &'static str {
15251528
match ptr {
15261529
Unique => "Box",
1527-
BorrowedPtr(ty::ImmBorrow, _) |
1528-
Implicit(ty::ImmBorrow, _) => "&",
1529-
BorrowedPtr(ty::MutBorrow, _) |
1530-
Implicit(ty::MutBorrow, _) => "&mut",
1531-
BorrowedPtr(ty::UniqueImmBorrow, _) |
1532-
Implicit(ty::UniqueImmBorrow, _) => "&unique",
1530+
BorrowedPtr(ty::ImmBorrow, _) => "&",
1531+
BorrowedPtr(ty::MutBorrow, _) => "&mut",
1532+
BorrowedPtr(ty::UniqueImmBorrow, _) => "&unique",
15331533
UnsafePtr(_) => "*",
15341534
}
15351535
}

src/librustc/traits/project.rs

+25-6
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,30 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
137137
fn push_candidate(&mut self, candidate: ProjectionTyCandidate<'tcx>) -> bool {
138138
use self::ProjectionTyCandidateSet::*;
139139
use self::ProjectionTyCandidate::*;
140+
141+
// This wacky variable is just used to try and
142+
// make code readable and avoid confusing paths.
143+
// It is assigned a "value" of `()` only on those
144+
// paths in which we wish to convert `*self` to
145+
// ambiguous (and return false, because the candidate
146+
// was not used). On other paths, it is not assigned,
147+
// and hence if those paths *could* reach the code that
148+
// comes after the match, this fn would not compile.
149+
let convert_to_ambigious;
150+
140151
match self {
141152
None => {
142153
*self = Single(candidate);
143-
true
154+
return true;
144155
}
156+
145157
Single(current) => {
146158
// Duplicates can happen inside ParamEnv. In the case, we
147159
// perform a lazy deduplication.
148160
if current == &candidate {
149161
return false;
150162
}
163+
151164
// Prefer where-clauses. As in select, if there are multiple
152165
// candidates, we prefer where-clause candidates over impls. This
153166
// may seem a bit surprising, since impls are the source of
@@ -156,17 +169,23 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
156169
// clauses are the safer choice. See the comment on
157170
// `select::SelectionCandidate` and #21974 for more details.
158171
match (current, candidate) {
159-
(ParamEnv(..), ParamEnv(..)) => { *self = Ambiguous; }
160-
(ParamEnv(..), _) => {}
172+
(ParamEnv(..), ParamEnv(..)) => convert_to_ambigious = (),
173+
(ParamEnv(..), _) => return false,
161174
(_, ParamEnv(..)) => { unreachable!(); }
162-
(_, _) => { *self = Ambiguous; }
175+
(_, _) => convert_to_ambigious = (),
163176
}
164-
false
165177
}
178+
166179
Ambiguous | Error(..) => {
167-
false
180+
return false;
168181
}
169182
}
183+
184+
// We only ever get here when we moved from a single candidate
185+
// to ambiguous.
186+
let () = convert_to_ambigious;
187+
*self = Ambiguous;
188+
false
170189
}
171190
}
172191

src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs

-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
180180
-> Option<mc::cmt_<'tcx>> {
181181
match cmt.cat {
182182
Categorization::Deref(_, mc::BorrowedPtr(..)) |
183-
Categorization::Deref(_, mc::Implicit(..)) |
184183
Categorization::Deref(_, mc::UnsafePtr(..)) |
185184
Categorization::StaticItem => {
186185
Some(cmt.clone())

src/librustc_borrowck/borrowck/gather_loans/lifetime.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
7474
Categorization::Local(..) | // L-Local
7575
Categorization::Upvar(..) |
7676
Categorization::Deref(_, mc::BorrowedPtr(..)) | // L-Deref-Borrowed
77-
Categorization::Deref(_, mc::Implicit(..)) |
7877
Categorization::Deref(_, mc::UnsafePtr(..)) => {
7978
self.check_scope(self.scope(cmt))
8079
}
@@ -122,8 +121,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
122121
Categorization::Deref(_, mc::UnsafePtr(..)) => {
123122
self.bccx.tcx.types.re_static
124123
}
125-
Categorization::Deref(_, mc::BorrowedPtr(_, r)) |
126-
Categorization::Deref(_, mc::Implicit(_, r)) => {
124+
Categorization::Deref(_, mc::BorrowedPtr(_, r)) => {
127125
r
128126
}
129127
Categorization::Downcast(ref cmt, _) |

src/librustc_borrowck/borrowck/gather_loans/move_error.rs

-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>,
140140
-> DiagnosticBuilder<'a> {
141141
match move_from.cat {
142142
Categorization::Deref(_, mc::BorrowedPtr(..)) |
143-
Categorization::Deref(_, mc::Implicit(..)) |
144143
Categorization::Deref(_, mc::UnsafePtr(..)) |
145144
Categorization::StaticItem => {
146145
bccx.cannot_move_out_of(

src/librustc_borrowck/borrowck/gather_loans/restrictions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
148148
let result = self.restrict(&cmt_base);
149149
self.extend(result, &cmt, LpDeref(pk))
150150
}
151-
mc::Implicit(bk, lt) | mc::BorrowedPtr(bk, lt) => {
151+
mc::BorrowedPtr(bk, lt) => {
152152
// R-Deref-[Mut-]Borrowed
153153
if !self.bccx.is_subregion_of(self.loan_region, lt) {
154154
self.bccx.report(

src/librustc_typeck/check/_match.rs

+1
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
236236
.borrow_mut()
237237
.pat_binding_modes_mut()
238238
.insert(pat.hir_id, bm);
239+
debug!("check_pat_walk: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
239240
let typ = self.local_ty(pat.span, pat.id);
240241
match bm {
241242
ty::BindByReference(mutbl) => {

src/librustc_typeck/check/regionck.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,6 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
11131113
borrow_kind,
11141114
borrow_cmt);
11151115
match borrow_cmt_cat {
1116-
Categorization::Deref(ref_cmt, mc::Implicit(ref_kind, ref_region)) |
11171116
Categorization::Deref(ref_cmt, mc::BorrowedPtr(ref_kind, ref_region)) => {
11181117
match self.link_reborrowed_region(span,
11191118
borrow_region, borrow_kind,

0 commit comments

Comments
 (0)