Skip to content

Rollup of 5 pull requests #30793

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
9 changes: 4 additions & 5 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ use middle::const_eval::{const_expr_to_pat, lookup_const_by_id};
use middle::const_eval::EvalHint::ExprTypeChecked;
use middle::def::*;
use middle::def_id::{DefId};
use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Init};
use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode};
use middle::expr_use_visitor::WriteAndRead;
use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor};
use middle::expr_use_visitor::{LoanCause, MutateMode};
use middle::expr_use_visitor as euv;
use middle::infer;
use middle::mem_categorization::{cmt};
Expand Down Expand Up @@ -1161,10 +1160,10 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
fn decl_without_init(&mut self, _: NodeId, _: Span) {}
fn mutate(&mut self, _: NodeId, span: Span, _: cmt, mode: MutateMode) {
match mode {
JustWrite | WriteAndRead => {
MutateMode::JustWrite | MutateMode::WriteAndRead => {
span_err!(self.cx.tcx.sess, span, E0302, "cannot assign in a pattern guard")
}
Init => {}
MutateMode::Init => {}
}
}
}
Expand Down
13 changes: 8 additions & 5 deletions src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
//! normal visitor, which just walks the entire body in one shot, the
//! `ExprUseVisitor` determines how expressions are being used.

pub use self::MutateMode::*;
pub use self::LoanCause::*;
pub use self::ConsumeMode::*;
pub use self::MoveReason::*;
Expand Down Expand Up @@ -465,7 +464,11 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
self.consume_expr(&*output.expr);
} else {
self.mutate_expr(expr, &*output.expr,
if output.is_rw { WriteAndRead } else { JustWrite });
if output.is_rw {
MutateMode::WriteAndRead
} else {
MutateMode::JustWrite
});
}
}
}
Expand Down Expand Up @@ -519,7 +522,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}

hir::ExprAssign(ref lhs, ref rhs) => {
self.mutate_expr(expr, &**lhs, JustWrite);
self.mutate_expr(expr, &**lhs, MutateMode::JustWrite);
self.consume_expr(&**rhs);
}

Expand All @@ -532,7 +535,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
assert!(::rustc_front::util::is_by_value_binop(op.node));

if !self.walk_overloaded_operator(expr, lhs, vec![rhs], PassArgs::ByValue) {
self.mutate_expr(expr, &**lhs, WriteAndRead);
self.mutate_expr(expr, &**lhs, MutateMode::WriteAndRead);
self.consume_expr(&**rhs);
}
}
Expand Down Expand Up @@ -991,7 +994,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
let def = def_map.borrow().get(&pat.id).unwrap().full_def();
match mc.cat_def(pat.id, pat.span, pat_ty, def) {
Ok(binding_cmt) => {
delegate.mutate(pat.id, pat.span, binding_cmt, Init);
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
}
Err(_) => { }
}
Expand Down
13 changes: 11 additions & 2 deletions src/librustc/mir/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,19 @@ impl<'tcx> CallKind<'tcx> {
}
}

pub fn destination(&self) -> Option<Lvalue<'tcx>> {
pub fn destination(&self) -> Option<&Lvalue<'tcx>> {
match *self {
CallKind::Converging { ref destination, .. } |
CallKind::ConvergingCleanup { ref destination, .. } => Some(destination.clone()),
CallKind::ConvergingCleanup { ref destination, .. } => Some(destination),
CallKind::Diverging |
CallKind::DivergingCleanup(_) => None
}
}

pub fn destination_mut(&mut self) -> Option<&mut Lvalue<'tcx>> {
match *self {
CallKind::Converging { ref mut destination, .. } |
CallKind::ConvergingCleanup { ref mut destination, .. } => Some(destination),
CallKind::Diverging |
CallKind::DivergingCleanup(_) => None
}
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_borrowck/borrowck/check_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use self::UseError::*;
use borrowck::*;
use borrowck::InteriorKind::{InteriorElement, InteriorField};
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::expr_use_visitor::MutateMode;
use rustc::middle::infer;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
Expand Down Expand Up @@ -161,7 +162,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
match opt_loan_path(&assignee_cmt) {
Some(lp) => {
match mode {
euv::Init | euv::JustWrite => {
MutateMode::Init | MutateMode::JustWrite => {
// In a case like `path = 1`, then path does not
// have to be *FULLY* initialized, but we still
// must be careful lest it contains derefs of
Expand All @@ -171,7 +172,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
MovedInUse,
&lp);
}
euv::WriteAndRead => {
MutateMode::WriteAndRead => {
// In a case like `path += 1`, then path must be
// fully initialized, since we will read it before
// we write it.
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_borrowck/borrowck/move_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use rustc::middle::dataflow::BitwiseOperator;
use rustc::middle::dataflow::DataFlowOperator;
use rustc::middle::dataflow::KillFrom;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::expr_use_visitor::MutateMode;
use rustc::middle::ty;
use rustc::util::nodemap::{FnvHashMap, NodeSet};

Expand Down Expand Up @@ -406,10 +407,10 @@ impl<'tcx> MoveData<'tcx> {
self.fragments.borrow_mut().add_assignment(path_index);

match mode {
euv::Init | euv::JustWrite => {
MutateMode::Init | MutateMode::JustWrite => {
self.assignee_ids.borrow_mut().insert(assignee_id);
}
euv::WriteAndRead => { }
MutateMode::WriteAndRead => { }
}

let assignment = Assignment {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn write_basic_block<W: Write>(block: BasicBlock, mir: &Mir, w: &mut W) -> io::R
}

// Terminator at the bottom.
try!(writeln!(w, "{0}{0}{1:?};", INDENT, data.terminator));
try!(writeln!(w, "{0}{0}{1:?};", INDENT, data.terminator()));

writeln!(w, "{}}}", INDENT)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/erase_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl<'a, 'tcx> EraseRegions<'a, 'tcx> {
*switch_ty = self.tcx.erase_regions(switch_ty);
},
Terminator::Call { ref mut func, ref mut args, ref mut kind } => {
if let Some(ref mut destination) = kind.destination() {
if let Some(destination) = kind.destination_mut() {
self.erase_regions_lvalue(destination);
}
self.erase_regions_operand(func);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {

debug!("(build reduced graph for item) found extern `{}`",
module_to_string(&*external_module));
self.check_for_conflicts_between_external_crates(&**parent, name, sp);
self.check_for_conflicts_for_external_crate(&parent, name, sp);
parent.external_module_children
.borrow_mut()
.insert(name, external_module.clone());
Expand Down
33 changes: 21 additions & 12 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ enum SuggestionType {
}

pub enum ResolutionError<'a> {
/// error E0260: name conflicts with an extern crate
NameConflictsWithExternCrate(Name),
/// error E0401: can't use type parameters from outer function
TypeParametersFromOuterFunction,
/// error E0402: cannot use an outer type parameter in this context
Expand Down Expand Up @@ -228,6 +230,14 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
}

match resolution_error {
ResolutionError::NameConflictsWithExternCrate(name) => {
struct_span_err!(resolver.session,
span,
E0260,
"the name `{}` conflicts with an external crate \
that has been imported into this module",
name)
}
ResolutionError::TypeParametersFromOuterFunction => {
struct_span_err!(resolver.session,
span,
Expand Down Expand Up @@ -1297,19 +1307,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}

/// Checks that the names of external crates don't collide with other
/// external crates.
fn check_for_conflicts_between_external_crates(&self,
module: &Module,
name: Name,
span: Span) {
/// Check that an external crate doesn't collide with items or other external crates.
fn check_for_conflicts_for_external_crate(&self, module: &Module, name: Name, span: Span) {
if module.external_module_children.borrow().contains_key(&name) {
span_err!(self.session,
span,
E0259,
"an external crate named `{}` has already been imported into this module",
name);
}
match module.children.borrow().get(&name) {
Some(name_bindings) if name_bindings.type_ns.defined() => {
resolve_error(self,
name_bindings.type_ns.span().unwrap_or(codemap::DUMMY_SP),
ResolutionError::NameConflictsWithExternCrate(name));
}
_ => {},
}
}

/// Checks that the names of items don't collide with external crates.
Expand All @@ -1318,12 +1332,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
name: Name,
span: Span) {
if module.external_module_children.borrow().contains_key(&name) {
span_err!(self.session,
span,
E0260,
"the name `{}` conflicts with an external crate that has been imported \
into this module",
name);
resolve_error(self, span, ResolutionError::NameConflictsWithExternCrate(name));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/trans/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
let mut llargs = Vec::with_capacity(args.len() + 1);

// Prepare the return value destination
let (ret_dest_ty, must_copy_dest) = if let Some(ref d) = kind.destination() {
let (ret_dest_ty, must_copy_dest) = if let Some(d) = kind.destination() {
let dest = self.trans_lvalue(bcx, d);
let ret_ty = dest.ty.to_ty(bcx.tcx());
if type_of::return_uses_outptr(bcx.ccx(), ret_ty) {
Expand Down
15 changes: 5 additions & 10 deletions src/librustc_trans/trans/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ use middle::ty::{Ty, TypeFoldable};
use rustc::middle::const_eval::ConstVal;
use rustc::mir::repr as mir;
use trans::common::{self, Block, C_bool, C_bytes, C_floating_f64, C_integral, C_str_slice};
use trans::consts::{self, TrueConst};
use trans::{type_of, expr};

use trans::consts;
use trans::expr;
use trans::type_of;

use super::operand::{OperandRef, OperandValue};
use super::MirContext;


impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
pub fn trans_constval(&mut self,
bcx: Block<'bcx, 'tcx>,
Expand Down Expand Up @@ -66,13 +67,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
ConstVal::Uint(v) => C_integral(llty, v, false),
ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()),
ConstVal::ByteStr(ref v) => consts::addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"),
ConstVal::Struct(id) | ConstVal::Tuple(id) => {
let expr = bcx.tcx().map.expect_expr(id);
match consts::const_expr(ccx, expr, param_substs, None, TrueConst::Yes) {
Ok((val, _)) => val,
Err(e) => panic!("const eval failure: {}", e.description()),
}
},
ConstVal::Struct(id) | ConstVal::Tuple(id) |
ConstVal::Array(id, _) | ConstVal::Repeat(id, _) => {
let expr = bcx.tcx().map.expect_expr(id);
expr::trans(bcx, expr).datum.val
Expand Down
32 changes: 32 additions & 0 deletions src/test/run-pass/mir_constval_adts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 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)]

#[derive(PartialEq, Debug)]
struct Point {
_x: i32,
_y: i32,
}
const STRUCT: Point = Point { _x: 42, _y: 42 };
const TUPLE1: (i32, i32) = (42, 42);
const TUPLE2: (&'static str, &'static str) = ("hello","world");

#[rustc_mir]
fn mir() -> (Point, (i32, i32), (&'static str, &'static str)){
let struct1 = STRUCT;
let tuple1 = TUPLE1;
let tuple2 = TUPLE2;
(struct1, tuple1, tuple2)
}

fn main(){
assert_eq!(mir(), (STRUCT, TUPLE1, TUPLE2));
}