stop having identity casts be lexprs
that made no sense (see test), and was incompatible with borrowck. Fixes #36936.
This commit is contained in:
parent
f3745653e1
commit
c2a0859b3e
@ -96,6 +96,7 @@ fn expr_as_lvalue(&mut self,
|
||||
ExprKind::LogicalOp { .. } |
|
||||
ExprKind::Box { .. } |
|
||||
ExprKind::Cast { .. } |
|
||||
ExprKind::Use { .. } |
|
||||
ExprKind::NeverToAny { .. } |
|
||||
ExprKind::ReifyFnPointer { .. } |
|
||||
ExprKind::UnsafeFnPointer { .. } |
|
||||
|
@ -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))
|
||||
|
@ -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 { .. } |
|
||||
|
@ -249,6 +249,7 @@ pub fn into_expr(&mut self,
|
||||
ExprKind::Binary { .. } |
|
||||
ExprKind::Box { .. } |
|
||||
ExprKind::Cast { .. } |
|
||||
ExprKind::Use { .. } |
|
||||
ExprKind::ReifyFnPointer { .. } |
|
||||
ExprKind::UnsafeFnPointer { .. } |
|
||||
ExprKind::Unsize { .. } |
|
||||
|
@ -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() }
|
||||
}
|
||||
|
@ -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>,
|
||||
},
|
||||
|
35
src/test/run-pass/issue-36936.rs
Normal file
35
src/test/run-pass/issue-36936.rs
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user