Don't promote to 'static the result of dereferences.
This commit is contained in:
parent
6cf081c8c5
commit
121499a119
2 changed files with 46 additions and 15 deletions
|
|
@ -491,9 +491,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||
this.add(Qualif::STATIC);
|
||||
}
|
||||
|
||||
this.add(Qualif::NOT_CONST);
|
||||
|
||||
let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx);
|
||||
if let ty::TyRawPtr(_) = base_ty.sty {
|
||||
this.add(Qualif::NOT_CONST);
|
||||
if this.mode != Mode::Fn {
|
||||
struct_span_err!(this.tcx.sess,
|
||||
this.span, E0396,
|
||||
|
|
@ -570,7 +571,38 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||
|
||||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
// Recurse through operands and places.
|
||||
self.super_rvalue(rvalue, location);
|
||||
if let Rvalue::Ref(region, kind, ref place) = *rvalue {
|
||||
let mut is_reborrow = false;
|
||||
if let Place::Projection(ref proj) = *place {
|
||||
if let ProjectionElem::Deref = proj.elem {
|
||||
let base_ty = proj.base.ty(self.mir, self.tcx).to_ty(self.tcx);
|
||||
if let ty::TyRef(..) = base_ty.sty {
|
||||
is_reborrow = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if is_reborrow {
|
||||
self.nest(|this| {
|
||||
this.super_place(place, PlaceContext::Borrow {
|
||||
region,
|
||||
kind
|
||||
}, location);
|
||||
if !this.try_consume() {
|
||||
return;
|
||||
}
|
||||
|
||||
if this.qualif.intersects(Qualif::STATIC_REF) {
|
||||
this.qualif = this.qualif - Qualif::STATIC_REF;
|
||||
this.add(Qualif::STATIC);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
self.super_rvalue(rvalue, location);
|
||||
}
|
||||
} else {
|
||||
self.super_rvalue(rvalue, location);
|
||||
}
|
||||
|
||||
match *rvalue {
|
||||
Rvalue::Use(_) |
|
||||
|
|
|
|||
|
|
@ -352,14 +352,9 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
|
|||
hir::ExprBox(_) => {
|
||||
v.promotable = false;
|
||||
}
|
||||
hir::ExprUnary(op, ref inner) => {
|
||||
match v.tables.node_id_to_type(inner.hir_id).sty {
|
||||
ty::TyRawPtr(_) => {
|
||||
assert!(op == hir::UnDeref);
|
||||
|
||||
v.promotable = false;
|
||||
}
|
||||
_ => {}
|
||||
hir::ExprUnary(op, _) => {
|
||||
if op == hir::UnDeref {
|
||||
v.promotable = false;
|
||||
}
|
||||
}
|
||||
hir::ExprBinary(op, ref lhs, _) => {
|
||||
|
|
@ -548,7 +543,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
|
|||
fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr) {
|
||||
use rustc::ty::adjustment::*;
|
||||
|
||||
for adjustment in v.tables.expr_adjustments(e) {
|
||||
let mut adjustments = v.tables.expr_adjustments(e).iter().peekable();
|
||||
while let Some(adjustment) = adjustments.next() {
|
||||
match adjustment.kind {
|
||||
Adjust::NeverToAny |
|
||||
Adjust::ReifyFnPointer |
|
||||
|
|
@ -558,11 +554,14 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp
|
|||
Adjust::Borrow(_) |
|
||||
Adjust::Unsize => {}
|
||||
|
||||
Adjust::Deref(ref overloaded) => {
|
||||
if overloaded.is_some() {
|
||||
v.promotable = false;
|
||||
break;
|
||||
Adjust::Deref(_) => {
|
||||
if let Some(next_adjustment) = adjustments.peek() {
|
||||
if let Adjust::Borrow(_) = next_adjustment.kind {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
v.promotable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue