stop having identity casts be lexprs

that made no sense (see test), and was incompatible with borrowck.

Fixes #36936.
This commit is contained in:
Ariel Ben-Yehuda 2016-10-04 01:13:36 +03:00
parent f3745653e1
commit c2a0859b3e
7 changed files with 47 additions and 2 deletions

View File

@ -96,6 +96,7 @@ fn expr_as_lvalue(&mut self,
ExprKind::LogicalOp { .. } |
ExprKind::Box { .. } |
ExprKind::Cast { .. } |
ExprKind::Use { .. } |
ExprKind::NeverToAny { .. } |
ExprKind::ReifyFnPointer { .. } |
ExprKind::UnsafeFnPointer { .. } |

View File

@ -115,6 +115,10 @@ fn expr_as_rvalue(&mut self,
let source = unpack!(block = this.as_operand(block, source));
block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty))
}
ExprKind::Use { source } => {
let source = unpack!(block = this.as_operand(block, source));
block.and(Rvalue::Use(source))
}
ExprKind::ReifyFnPointer { source } => {
let source = unpack!(block = this.as_operand(block, source));
block.and(Rvalue::Cast(CastKind::ReifyFnPointer, source, expr.ty))

View File

@ -68,6 +68,7 @@ pub fn of<'tcx>(ek: &ExprKind<'tcx>) -> Option<Category> {
ExprKind::Binary { .. } |
ExprKind::Box { .. } |
ExprKind::Cast { .. } |
ExprKind::Use { .. } |
ExprKind::ReifyFnPointer { .. } |
ExprKind::UnsafeFnPointer { .. } |
ExprKind::Unsize { .. } |

View File

@ -249,6 +249,7 @@ pub fn into_expr(&mut self,
ExprKind::Binary { .. } |
ExprKind::Box { .. } |
ExprKind::Cast { .. } |
ExprKind::Use { .. } |
ExprKind::ReifyFnPointer { .. } |
ExprKind::UnsafeFnPointer { .. } |
ExprKind::Unsize { .. } |

View File

@ -600,8 +600,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// Check to see if this cast is a "coercion cast", where the cast is actually done
// using a coercion (or is a no-op).
if let Some(&TyCastKind::CoercionCast) = cx.tcx.cast_kinds.borrow().get(&source.id) {
// Skip the actual cast itexpr, as it's now a no-op.
return source.make_mirror(cx);
// Convert the lexpr to a vexpr.
ExprKind::Use { source: source.to_ref() }
} else {
ExprKind::Cast { source: source.to_ref() }
}

View File

@ -139,6 +139,9 @@ pub enum ExprKind<'tcx> {
Cast {
source: ExprRef<'tcx>,
},
Use {
source: ExprRef<'tcx>,
}, // Use a lexpr to get a vexpr.
NeverToAny {
source: ExprRef<'tcx>,
},

View File

@ -0,0 +1,35 @@
// Copyright 2016 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.
// check that casts are not being treated as lexprs.
fn main() {
let mut a = 0i32;
let b = &(a as i32);
a = 1;
assert_ne!(&a as *const i32, b as *const i32);
assert_eq!(*b, 0);
assert_eq!(issue_36936(), 1);
}
struct A(u32);
impl Drop for A {
fn drop(&mut self) {
self.0 = 0;
}
}
fn issue_36936() -> u32 {
let a = &(A(1) as A);
a.0
}