mirror of
https://git.proxmox.com/git/rustc
synced 2025-05-29 23:20:30 +00:00
New upstream version 1.26.2+dfsg1
This commit is contained in:
parent
564c78a28d
commit
2c912e08a8
10
RELEASES.md
10
RELEASES.md
@ -1,3 +1,13 @@
|
|||||||
|
Version 1.26.2 (2018-06-05)
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Compatibility Notes
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- [The borrow checker was fixed to avoid unsoundness when using match ergonomics][51117]
|
||||||
|
|
||||||
|
[51117]: https://github.com/rust-lang/rust/issues/51117
|
||||||
|
|
||||||
Version 1.26.1 (2018-05-29)
|
Version 1.26.1 (2018-05-29)
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
827013a31b88e536e85b8e6ceb5b9988042ec335
|
594fb253c2b02b320c728391a425d028e6dc7a09
|
@ -24,7 +24,7 @@ use Build;
|
|||||||
use config::Config;
|
use config::Config;
|
||||||
|
|
||||||
// The version number
|
// The version number
|
||||||
pub const CFG_RELEASE_NUM: &str = "1.26.1";
|
pub const CFG_RELEASE_NUM: &str = "1.26.2";
|
||||||
|
|
||||||
pub struct GitInfo {
|
pub struct GitInfo {
|
||||||
inner: Option<Info>,
|
inner: Option<Info>,
|
||||||
|
@ -845,17 +845,24 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||||||
/// 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> {
|
|||||||
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> {
|
|||||||
|
|
||||||
/// `*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
|
||||||
@ -161,6 +158,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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,8 +222,7 @@ impl<'tcx> cmt_<'tcx> {
|
|||||||
|
|
||||||
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) =>
|
||||||
@ -321,7 +318,7 @@ impl 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) => {
|
||||||
@ -610,7 +607,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
previous()?
|
previous()?
|
||||||
};
|
};
|
||||||
self.cat_deref(expr, base, false)
|
self.cat_deref(expr, base, NoteNone)
|
||||||
}
|
}
|
||||||
|
|
||||||
adjustment::Adjust::NeverToAny |
|
adjustment::Adjust::NeverToAny |
|
||||||
@ -633,10 +630,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, '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 = self.cat_expr(&e_base)?;
|
let base_cmt = self.cat_expr(&e_base)?;
|
||||||
self.cat_deref(expr, base_cmt, false)
|
self.cat_deref(expr, base_cmt, NoteNone)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,7 +658,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, '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 = self.cat_expr(&base)?;
|
let base_cmt = self.cat_expr(&base)?;
|
||||||
self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index)
|
self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index)
|
||||||
@ -1012,12 +1009,18 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
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
|
||||||
@ -1037,14 +1040,15 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let base_cmt = self.cat_rvalue_node(expr.id, expr.span, ref_ty);
|
let base_cmt = 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;
|
||||||
@ -1060,9 +1064,9 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
let ptr = match base_cmt.ty.sty {
|
let ptr = match base_cmt.ty.sty {
|
||||||
ty::TyAdt(def, ..) if def.is_box() => Unique,
|
ty::TyAdt(def, ..) if def.is_box() => Unique,
|
||||||
ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl),
|
ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl),
|
||||||
ty::TyRef(r, mt) => {
|
ty::TyRef(r, ty) => {
|
||||||
let bk = ty::BorrowKind::from_mutbl(mt.mutbl);
|
let bk = ty::BorrowKind::from_mutbl(ty.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)
|
||||||
};
|
};
|
||||||
@ -1073,7 +1077,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
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)
|
||||||
@ -1207,7 +1211,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
// 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
|
||||||
@ -1245,10 +1249,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
.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 = self.cat_deref(pat, cmt, true /* implicit */)?;
|
{
|
||||||
|
debug!("cat_pattern: applying adjustment to cmt={:?}", cmt);
|
||||||
|
cmt = 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.
|
||||||
//
|
//
|
||||||
@ -1342,7 +1349,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
// 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 = self.cat_deref(pat, cmt, false)?;
|
let subcmt = self.cat_deref(pat, cmt, NoteNone)?;
|
||||||
self.cat_pattern_(subcmt, &subpat, op)?;
|
self.cat_pattern_(subcmt, &subpat, op)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1403,7 +1410,6 @@ impl<'tcx> 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(..) => {
|
||||||
Rc::new((*self).clone())
|
Rc::new((*self).clone())
|
||||||
}
|
}
|
||||||
@ -1423,9 +1429,7 @@ impl<'tcx> cmt_<'tcx> {
|
|||||||
|
|
||||||
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, _) => {
|
||||||
@ -1448,8 +1452,7 @@ impl<'tcx> cmt_<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Categorization::Deref(_, BorrowedPtr(ty::ImmBorrow, _)) |
|
Categorization::Deref(_, BorrowedPtr(ty::ImmBorrow, _)) => {
|
||||||
Categorization::Deref(_, Implicit(ty::ImmBorrow, _)) => {
|
|
||||||
FreelyAliasable(AliasableBorrowed)
|
FreelyAliasable(AliasableBorrowed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1471,7 +1474,7 @@ impl<'tcx> cmt_<'tcx> {
|
|||||||
_ => bug!()
|
_ => bug!()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
NoteNone => None
|
NoteIndex | NoteNone => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1500,9 +1503,6 @@ impl<'tcx> cmt_<'tcx> {
|
|||||||
Some(_) => bug!(),
|
Some(_) => bug!(),
|
||||||
None => {
|
None => {
|
||||||
match pk {
|
match pk {
|
||||||
Implicit(..) => {
|
|
||||||
format!("indexed content")
|
|
||||||
}
|
|
||||||
Unique => {
|
Unique => {
|
||||||
format!("`Box` content")
|
format!("`Box` content")
|
||||||
}
|
}
|
||||||
@ -1510,7 +1510,10 @@ impl<'tcx> cmt_<'tcx> {
|
|||||||
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"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1541,12 +1544,9 @@ impl<'tcx> cmt_<'tcx> {
|
|||||||
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 @@ impl<'tcx> ProjectionTyCandidateSet<'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 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
|
|||||||
// 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,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())
|
||||||
|
@ -75,7 +75,6 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
|
|||||||
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))
|
||||||
}
|
}
|
||||||
@ -123,8 +122,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, '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>,
|
|||||||
-> 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(
|
||||||
|
@ -147,7 +147,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
|
|||||||
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(
|
||||||
|
@ -236,6 +236,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
.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) => {
|
||||||
|
@ -1114,7 +1114,6 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
borrow_kind,
|
borrow_kind,
|
||||||
borrow_cmt);
|
borrow_cmt);
|
||||||
match borrow_cmt.cat.clone() {
|
match borrow_cmt.cat.clone() {
|
||||||
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,
|
||||||
|
@ -328,8 +328,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, '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
|
||||||
@ -367,7 +366,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
|
|||||||
var_name(tcx, upvar_id.var_id),
|
var_name(tcx, upvar_id.var_id),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
mc::NoteNone => {}
|
mc::NoteIndex | mc::NoteNone => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -389,8 +388,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, '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
|
||||||
@ -422,8 +420,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, '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
|
||||||
@ -481,7 +478,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
mc::NoteNone => false,
|
mc::NoteIndex | mc::NoteNone => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
25
src/test/ui/borrowck/issue-51117.rs
Normal file
25
src/test/ui/borrowck/issue-51117.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// 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!(),
|
||||||
|
}
|
||||||
|
}
|
14
src/test/ui/borrowck/issue-51117.stderr
Normal file
14
src/test/ui/borrowck/issue-51117.stderr
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
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`.
|
Loading…
Reference in New Issue
Block a user