Auto merge of #31474 - arielb1:mir-typeck, r=nikomatsakis

This should stop broken MIR from annoying us when we try to implement things
This commit is contained in:
bors 2016-02-20 12:38:18 +00:00
commit 6c751e0456
43 changed files with 1509 additions and 190 deletions

View file

@ -21,17 +21,14 @@ extern crate syntax;
use rustc::mir::transform::MirPass;
use rustc::mir::repr::{Mir, Literal};
use rustc::mir::visit::MutVisitor;
use rustc::middle::ty;
use rustc::middle::infer::InferCtxt;
use rustc::middle::const_eval::ConstVal;
use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray};
use rustc_plugin::Registry;
use rustc_front::hir;
use syntax::attr;
struct Pass;
impl MirPass for Pass {
fn run_on_mir<'tcx>(&mut self, mir: &mut Mir<'tcx>, tcx: &ty::ctxt<'tcx>) {
fn run_on_mir<'a, 'tcx>(&mut self, mir: &mut Mir<'tcx>, _: &InferCtxt<'a, 'tcx>) {
Visitor.visit_mir(mir)
}
}

View file

@ -0,0 +1,187 @@
// Copyright 2015 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.
#![feature(augmented_assignments)]
#![feature(op_assign_traits)]
#![feature(rustc_attrs)]
use std::mem;
use std::ops::{
AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, DivAssign, MulAssign, RemAssign,
ShlAssign, ShrAssign, SubAssign,
};
#[derive(Debug, PartialEq)]
struct Int(i32);
struct Slice([i32]);
impl Slice {
fn new(slice: &mut [i32]) -> &mut Slice {
unsafe {
mem::transmute(slice)
}
}
}
fn main() {
main_mir();
}
#[rustc_mir]
fn main_mir() {
let mut x = Int(1);
x += Int(2);
assert_eq!(x, Int(0b11));
x &= Int(0b01);
assert_eq!(x, Int(0b01));
x |= Int(0b10);
assert_eq!(x, Int(0b11));
x ^= Int(0b01);
assert_eq!(x, Int(0b10));
x /= Int(2);
assert_eq!(x, Int(1));
x *= Int(3);
assert_eq!(x, Int(3));
x %= Int(2);
assert_eq!(x, Int(1));
// overloaded RHS
x <<= 1u8;
assert_eq!(x, Int(2));
x <<= 1u16;
assert_eq!(x, Int(4));
x >>= 1u8;
assert_eq!(x, Int(2));
x >>= 1u16;
assert_eq!(x, Int(1));
x -= Int(1);
assert_eq!(x, Int(0));
// indexed LHS
// FIXME(mir-drop): use the vec![..] macro
let mut v = Vec::new();
v.push(Int(1));
v.push(Int(2));
v[0] += Int(2);
assert_eq!(v[0], Int(3));
// unsized RHS
let mut array = [0, 1, 2];
*Slice::new(&mut array) += 1;
assert_eq!(array[0], 1);
assert_eq!(array[1], 2);
assert_eq!(array[2], 3);
}
impl AddAssign for Int {
#[rustc_mir]
fn add_assign(&mut self, rhs: Int) {
self.0 += rhs.0;
}
}
impl BitAndAssign for Int {
#[rustc_mir]
fn bitand_assign(&mut self, rhs: Int) {
self.0 &= rhs.0;
}
}
impl BitOrAssign for Int {
#[rustc_mir]
fn bitor_assign(&mut self, rhs: Int) {
self.0 |= rhs.0;
}
}
impl BitXorAssign for Int {
#[rustc_mir]
fn bitxor_assign(&mut self, rhs: Int) {
self.0 ^= rhs.0;
}
}
impl DivAssign for Int {
#[rustc_mir]
fn div_assign(&mut self, rhs: Int) {
self.0 /= rhs.0;
}
}
impl MulAssign for Int {
#[rustc_mir]
fn mul_assign(&mut self, rhs: Int) {
self.0 *= rhs.0;
}
}
impl RemAssign for Int {
#[rustc_mir]
fn rem_assign(&mut self, rhs: Int) {
self.0 %= rhs.0;
}
}
impl ShlAssign<u8> for Int {
#[rustc_mir]
fn shl_assign(&mut self, rhs: u8) {
self.0 <<= rhs;
}
}
impl ShlAssign<u16> for Int {
#[rustc_mir]
fn shl_assign(&mut self, rhs: u16) {
self.0 <<= rhs;
}
}
impl ShrAssign<u8> for Int {
#[rustc_mir]
fn shr_assign(&mut self, rhs: u8) {
self.0 >>= rhs;
}
}
impl ShrAssign<u16> for Int {
#[rustc_mir]
fn shr_assign(&mut self, rhs: u16) {
self.0 >>= rhs;
}
}
impl SubAssign for Int {
#[rustc_mir]
fn sub_assign(&mut self, rhs: Int) {
self.0 -= rhs.0;
}
}
impl AddAssign<i32> for Slice {
#[rustc_mir]
fn add_assign(&mut self, rhs: i32) {
for lhs in &mut self.0 {
*lhs += rhs;
}
}
}

View file

@ -0,0 +1,41 @@
// 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.
#![feature(rustc_attrs)]
use std::ops::{Deref, DerefMut};
pub struct MyRef(u32);
impl Deref for MyRef {
type Target = u32;
fn deref(&self) -> &u32 { &self.0 }
}
impl DerefMut for MyRef {
fn deref_mut(&mut self) -> &mut u32 { &mut self.0 }
}
#[rustc_mir]
fn deref(x: &MyRef) -> &u32 {
x
}
#[rustc_mir]
fn deref_mut(x: &mut MyRef) -> &mut u32 {
x
}
fn main() {
let mut r = MyRef(2);
assert_eq!(deref(&r) as *const _, &r.0 as *const _);
assert_eq!(deref_mut(&mut r) as *mut _, &mut r.0 as *mut _);
}

View file

@ -0,0 +1,41 @@
// 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.
#![feature(rustc_attrs)]
use std::marker::PhantomData;
pub trait DataBind {
type Data;
}
impl<T> DataBind for Global<T> {
type Data = T;
}
pub struct Global<T>(PhantomData<T>);
pub struct Data {
pub offsets: <Global<[u32; 2]> as DataBind>::Data,
}
#[rustc_mir]
fn create_data() -> Data {
let mut d = Data { offsets: [1, 2] };
d.offsets[0] = 3;
d
}
fn main() {
let d = create_data();
assert_eq!(d.offsets[0], 3);
assert_eq!(d.offsets[1], 2);
}

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(rustc_attrs)]
#![feature(rustc_attrs, unboxed_closures, fn_traits)]
#[rustc_mir]
fn test1(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) {
@ -117,6 +117,27 @@ fn test_fn_impl(f: &&Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 {
f(x, y)
}
#[rustc_mir]
fn test_fn_direct_call<F>(f: &F, x: i32, y: i32) -> i32
where F: Fn(i32, i32) -> i32
{
f.call((x, y))
}
#[rustc_mir]
fn test_fn_const_call<F>(f: &F) -> i32
where F: Fn(i32, i32) -> i32
{
f.call((100, -1))
}
#[rustc_mir]
fn test_fn_nil_call<F>(f: &F) -> i32
where F: Fn() -> i32
{
f()
}
fn main() {
assert_eq!(test1(1, (2, 3), &[4, 5, 6]), (1, (2, 3), &[4, 5, 6][..]));
assert_eq!(test2(98), 98);
@ -128,9 +149,14 @@ fn main() {
assert_eq!(test8(), 2);
assert_eq!(test9(), 41 + 42 * 43);
let closure = |x: i32, y: i32| { x + y };
assert_eq!(test_closure(&closure, 100, 1), 101);
let r = 3;
let closure = |x: i32, y: i32| { r*(x + (y*2)) };
assert_eq!(test_fn_const_call(&closure), 294);
assert_eq!(test_closure(&closure, 100, 1), 306);
let function_object = &closure as &Fn(i32, i32) -> i32;
assert_eq!(test_fn_object(function_object, 100, 2), 102);
assert_eq!(test_fn_impl(&function_object, 100, 3), 103);
assert_eq!(test_fn_object(function_object, 100, 2), 312);
assert_eq!(test_fn_impl(&function_object, 100, 3), 318);
assert_eq!(test_fn_direct_call(&closure, 100, 4), 324);
assert_eq!(test_fn_nil_call(&(|| 42)), 42);
}