Skip to content
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

Rollup of 9 pull requests #41246

Merged
merged 27 commits into from
Apr 12, 2017
Merged
Changes from 4 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
768e707
kill the `CheckLoops` DepNode
nikomatsakis Apr 4, 2017
f3b876c
kill `CheckStaticRecursion`
nikomatsakis Apr 4, 2017
a83734d
remove `EffectCheck`
nikomatsakis Apr 4, 2017
a2a4fad
kill `Liveness`
nikomatsakis Apr 4, 2017
a4d7c1f
push `borrowck` into its own task
nikomatsakis Apr 4, 2017
44e414c
Use proper span for tuple index parsed as float
estebank Apr 5, 2017
d94f2c9
Update cargo submodules
alexcrichton Apr 8, 2017
0303a33
Fix pairs of doubles using an illegal <8 x i8> vector.
eddyb Apr 10, 2017
384ec80
store Spans for all MIR locals
arielb1 Apr 11, 2017
0144613
Move rvalue checking to MIR
arielb1 Apr 11, 2017
540a069
address review comments
arielb1 Apr 11, 2017
2389830
Highlight and simplify mismatched types
estebank Feb 17, 2017
ed7b6c3
Minor nits in primitive str
projektir Apr 12, 2017
f391451
COPYRIGHT: remove hoedown license
nodakai Apr 10, 2017
2e327a6
fix nit
nikomatsakis Apr 12, 2017
c008cd7
Make compiletest write test output to different files for different r…
michaelwoerister Apr 6, 2017
bc7af81
ICH: Hash everything that gets encoded into crate metadata.
michaelwoerister Apr 5, 2017
ca2dce9
ICH: Replace old, transitive metadata hashing with direct hashing app…
michaelwoerister Apr 5, 2017
49082ae
Rollup merge of #41063 - nikomatsakis:issue-40746-always-exec-loops, …
TimNN Apr 12, 2017
918e35a
Rollup merge of #41087 - estebank:tuple-float-index, r=arielb1
TimNN Apr 12, 2017
1b006b7
Rollup merge of #41141 - michaelwoerister:direct-metadata-ich-final, …
TimNN Apr 12, 2017
9275c9c
Rollup merge of #41166 - alexcrichton:update-cargo, r=brson
TimNN Apr 12, 2017
5c23e70
Rollup merge of #41183 - nodakai:remove-hoedown-license, r=TimNN
TimNN Apr 12, 2017
afb300d
Rollup merge of #41205 - estebank:shorter-mismatched-types-2, r=nikom…
TimNN Apr 12, 2017
092f19a
Rollup merge of #41206 - eddyb:avoid-illegal-vectors, r=nagisa
TimNN Apr 12, 2017
1dd9801
Rollup merge of #41232 - arielb1:mir-rvalues, r=eddyb
TimNN Apr 12, 2017
d4d35cf
Rollup merge of #41243 - projektir:prim_str_docs, r=GuillaumeGomez
TimNN Apr 12, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/librustc/ich/impls_mir.rs
Original file line number Diff line number Diff line change
@@ -22,7 +22,8 @@ impl_stable_hash_for!(struct mir::SourceInfo { span, scope });
impl_stable_hash_for!(enum mir::Mutability { Mut, Not });
impl_stable_hash_for!(enum mir::BorrowKind { Shared, Unique, Mut });
impl_stable_hash_for!(enum mir::LocalKind { Var, Temp, Arg, ReturnPointer });
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { mutability, ty, name, source_info });
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { mutability, ty, name, source_info,
is_user_variable});
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
impl_stable_hash_for!(struct mir::Terminator<'tcx> { source_info, kind });
40 changes: 23 additions & 17 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -197,10 +197,10 @@ impl<'tcx> Mir<'tcx> {
pub fn temps_iter<'a>(&'a self) -> impl Iterator<Item=Local> + 'a {
(self.arg_count+1..self.local_decls.len()).filter_map(move |index| {
let local = Local::new(index);
if self.local_decls[local].source_info.is_none() {
Some(local)
} else {
if self.local_decls[local].is_user_variable {
None
} else {
Some(local)
}
})
}
@@ -210,10 +210,10 @@ impl<'tcx> Mir<'tcx> {
pub fn vars_iter<'a>(&'a self) -> impl Iterator<Item=Local> + 'a {
(self.arg_count+1..self.local_decls.len()).filter_map(move |index| {
let local = Local::new(index);
if self.local_decls[local].source_info.is_none() {
None
} else {
if self.local_decls[local].is_user_variable {
Some(local)
} else {
None
}
})
}
@@ -370,6 +370,9 @@ pub struct LocalDecl<'tcx> {
/// Temporaries and the return pointer are always mutable.
pub mutability: Mutability,

/// True if this corresponds to a user-declared local variable.
pub is_user_variable: bool,

/// Type of this local.
pub ty: Ty<'tcx>,

@@ -379,37 +382,40 @@ pub struct LocalDecl<'tcx> {
/// to generate better debuginfo.
pub name: Option<Name>,

/// For user-declared variables, stores their source information.
///
/// For temporaries, this is `None`.
///
/// This is the primary way to differentiate between user-declared
/// variables and compiler-generated temporaries.
pub source_info: Option<SourceInfo>,
/// Source info of the local.
pub source_info: SourceInfo,
}

impl<'tcx> LocalDecl<'tcx> {
/// Create a new `LocalDecl` for a temporary.
#[inline]
pub fn new_temp(ty: Ty<'tcx>) -> Self {
pub fn new_temp(ty: Ty<'tcx>, span: Span) -> Self {
LocalDecl {
mutability: Mutability::Mut,
ty: ty,
name: None,
source_info: None,
source_info: SourceInfo {
span: span,
scope: ARGUMENT_VISIBILITY_SCOPE
},
is_user_variable: false
}
}

/// Builds a `LocalDecl` for the return pointer.
///
/// This must be inserted into the `local_decls` list as the first local.
#[inline]
pub fn new_return_pointer(return_ty: Ty) -> LocalDecl {
pub fn new_return_pointer(return_ty: Ty, span: Span) -> LocalDecl {
LocalDecl {
mutability: Mutability::Mut,
ty: return_ty,
source_info: None,
source_info: SourceInfo {
span: span,
scope: ARGUMENT_VISIBILITY_SCOPE
},
name: None, // FIXME maybe we do want some name here?
is_user_variable: false
}
}
}
5 changes: 2 additions & 3 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
@@ -630,12 +630,11 @@ macro_rules! make_mir_visitor {
ref $($mutability)* ty,
name: _,
ref $($mutability)* source_info,
is_user_variable: _,
} = *local_decl;

self.visit_ty(ty);
if let Some(ref $($mutability)* info) = *source_info {
self.visit_source_info(info);
}
self.visit_source_info(source_info);
}

fn super_visibility_scope(&mut self,
6 changes: 3 additions & 3 deletions src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
Original file line number Diff line number Diff line change
@@ -307,12 +307,12 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
data
}

fn create_drop_flag(&mut self, index: MovePathIndex) {
fn create_drop_flag(&mut self, index: MovePathIndex, span: Span) {
let tcx = self.tcx;
let patch = &mut self.patch;
debug!("create_drop_flag({:?})", self.mir.span);
self.drop_flags.entry(index).or_insert_with(|| {
patch.new_temp(tcx.types.bool)
patch.new_temp(tcx.types.bool, span)
});
}

@@ -374,7 +374,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
debug!("collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}",
child, location, path, (maybe_live, maybe_dead));
if maybe_live && maybe_dead {
self.create_drop_flag(child)
self.create_drop_flag(child, terminator.source_info.span)
}
});
}
8 changes: 2 additions & 6 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ use rustc_typeck as typeck;
use rustc_privacy;
use rustc_plugin::registry::Registry;
use rustc_plugin as plugin;
use rustc_passes::{ast_validation, no_asm, loops, consts, rvalues,
use rustc_passes::{ast_validation, no_asm, loops, consts,
static_recursion, hir_stats, mir_stats};
use rustc_const_eval::check_match;
use super::Compilation;
@@ -958,10 +958,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
"liveness checking",
|| middle::liveness::check_crate(tcx));

time(time_passes,
"rvalue checking",
|| rvalues::check_crate(tcx));

time(time_passes,
"MIR dump",
|| mir::mir_map::build_mir_for_crate(tcx));
@@ -977,8 +973,8 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
// in stage 4 below.
passes.push_hook(box mir::transform::dump_mir::DumpMir);
passes.push_pass(box mir::transform::simplify::SimplifyCfg::new("initial"));
passes.push_pass(box mir::transform::qualify_consts::QualifyAndPromoteConstants);
passes.push_pass(box mir::transform::type_check::TypeckMir);
passes.push_pass(box mir::transform::qualify_consts::QualifyAndPromoteConstants);
passes.push_pass(
box mir::transform::simplify_branches::SimplifyBranches::new("initial"));
passes.push_pass(box mir::transform::simplify::SimplifyCfg::new("qualify-consts"));
3 changes: 2 additions & 1 deletion src/librustc_mir/build/expr/as_lvalue.rs
Original file line number Diff line number Diff line change
@@ -62,7 +62,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let idx = unpack!(block = this.as_operand(block, None, index));

// bounds check:
let (len, lt) = (this.temp(usize_ty.clone()), this.temp(bool_ty));
let (len, lt) = (this.temp(usize_ty.clone(), expr_span),
this.temp(bool_ty, expr_span));
this.cfg.push_assign(block, source_info, // len = len(slice)
&len, Rvalue::Len(slice.clone()));
this.cfg.push_assign(block, source_info, // lt = idx < len
14 changes: 7 additions & 7 deletions src/librustc_mir/build/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
@@ -82,7 +82,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let bool_ty = this.hir.bool_ty();

let minval = this.minval_literal(expr_span, expr.ty);
let is_min = this.temp(bool_ty);
let is_min = this.temp(bool_ty, expr_span);

this.cfg.push_assign(block, source_info, &is_min,
Rvalue::BinaryOp(BinOp::Eq, arg.clone(), minval));
@@ -95,7 +95,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
ExprKind::Box { value, value_extents } => {
let value = this.hir.mirror(value);
let result = this.temp(expr.ty);
let result = this.temp(expr.ty, expr_span);
// to start, malloc some memory of suitable type (thus far, uninitialized):
this.cfg.push_assign(block, source_info, &result, Rvalue::Box(value.ty));
this.in_scope(value_extents, block, |this| {
@@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let bool_ty = self.hir.bool_ty();
if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() {
let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty], false);
let result_value = self.temp(result_tup);
let result_value = self.temp(result_tup, span);

self.cfg.push_assign(block, source_info,
&result_value, Rvalue::CheckedBinaryOp(op,
@@ -301,7 +301,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
};

// Check for / 0
let is_zero = self.temp(bool_ty);
let is_zero = self.temp(bool_ty, span);
let zero = self.zero_literal(span, ty);
self.cfg.push_assign(block, source_info, &is_zero,
Rvalue::BinaryOp(BinOp::Eq, rhs.clone(), zero));
@@ -315,9 +315,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let neg_1 = self.neg_1_literal(span, ty);
let min = self.minval_literal(span, ty);

let is_neg_1 = self.temp(bool_ty);
let is_min = self.temp(bool_ty);
let of = self.temp(bool_ty);
let is_neg_1 = self.temp(bool_ty, span);
let is_min = self.temp(bool_ty, span);
let of = self.temp(bool_ty, span);

// this does (rhs == -1) & (lhs == MIN). It could short-circuit instead

2 changes: 1 addition & 1 deletion src/librustc_mir/build/expr/as_temp.rs
Original file line number Diff line number Diff line change
@@ -44,8 +44,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}

let expr_ty = expr.ty.clone();
let temp = this.temp(expr_ty.clone());
let expr_span = expr.span;
let temp = this.temp(expr_ty.clone(), expr_span);
let source_info = this.source_info(expr_span);

if expr.temp_lifetime_was_shrunk && this.hir.needs_drop(expr_ty) {
2 changes: 1 addition & 1 deletion src/librustc_mir/build/expr/stmt.rs
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
_ => {
let expr_ty = expr.ty;
let temp = this.temp(expr.ty.clone());
let temp = this.temp(expr.ty.clone(), expr_span);
unpack!(block = this.into(&temp, block, expr));
unpack!(block = this.build_drop(block, expr_span, temp, expr_ty));
block.unit()
3 changes: 2 additions & 1 deletion src/librustc_mir/build/matches/mod.rs
Original file line number Diff line number Diff line change
@@ -710,7 +710,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
mutability: mutability,
ty: var_ty.clone(),
name: Some(name),
source_info: Some(source_info),
source_info: source_info,
is_user_variable: true,
});
self.var_indices.insert(var_id, var);

13 changes: 7 additions & 6 deletions src/librustc_mir/build/matches/test.rs
Original file line number Diff line number Diff line change
@@ -210,7 +210,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
debug!("num_enum_variants: {}, tested variants: {:?}, variants: {:?}",
num_enum_variants, values, variants);
let discr_ty = adt_def.repr.discr_type().to_ty(tcx);
let discr = self.temp(discr_ty);
let discr = self.temp(discr_ty, test.span);
self.cfg.push_assign(block, source_info, &discr,
Rvalue::Discriminant(lvalue.clone()));
assert_eq!(values.len() + 1, targets.len());
@@ -270,7 +270,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
if let ty::TyRef(region, mt) = ty.sty {
if let ty::TyArray(_, _) = mt.ty.sty {
ty = tcx.mk_imm_ref(region, tcx.mk_slice(tcx.types.u8));
let val_slice = self.temp(ty);
let val_slice = self.temp(ty, test.span);
self.cfg.push_assign(block, source_info, &val_slice,
Rvalue::Cast(CastKind::Unsize, val, ty));
val = Operand::Consume(val_slice);
@@ -285,7 +285,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
value: value.clone()
});

let slice = self.temp(ty);
let slice = self.temp(ty, test.span);
self.cfg.push_assign(block, source_info, &slice,
Rvalue::Cast(CastKind::Unsize, array, ty));
Operand::Consume(slice)
@@ -304,7 +304,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty]);

let bool_ty = self.hir.bool_ty();
let eq_result = self.temp(bool_ty);
let eq_result = self.temp(bool_ty, test.span);
let eq_block = self.cfg.start_new_block();
let cleanup = self.diverge_cleanup();
self.cfg.terminate(block, source_info, TerminatorKind::Call {
@@ -349,7 +349,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {

TestKind::Len { len, op } => {
let (usize_ty, bool_ty) = (self.hir.usize_ty(), self.hir.bool_ty());
let (actual, result) = (self.temp(usize_ty), self.temp(bool_ty));
let (actual, result) = (self.temp(usize_ty, test.span),
self.temp(bool_ty, test.span));

// actual = len(lvalue)
self.cfg.push_assign(block, source_info,
@@ -383,7 +384,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
left: Operand<'tcx>,
right: Operand<'tcx>) -> BasicBlock {
let bool_ty = self.hir.bool_ty();
let result = self.temp(bool_ty);
let result = self.temp(bool_ty, span);

// result = op(left, right)
let source_info = self.source_info(span);
6 changes: 3 additions & 3 deletions src/librustc_mir/build/misc.rs
Original file line number Diff line number Diff line change
@@ -27,8 +27,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
///
/// NB: **No cleanup is scheduled for this temporary.** You should
/// call `schedule_drop` once the temporary is initialized.
pub fn temp(&mut self, ty: Ty<'tcx>) -> Lvalue<'tcx> {
let temp = self.local_decls.push(LocalDecl::new_temp(ty));
pub fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Lvalue<'tcx> {
let temp = self.local_decls.push(LocalDecl::new_temp(ty, span));
let lvalue = Lvalue::Local(temp);
debug!("temp: created temp {:?} with type {:?}",
lvalue, self.local_decls[temp].ty);
@@ -106,7 +106,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
value: u64)
-> Lvalue<'tcx> {
let usize_ty = self.hir.usize_ty();
let temp = self.temp(usize_ty);
let temp = self.temp(usize_ty, source_info.span);
self.cfg.push_assign_constant(
block, source_info, &temp,
Constant {
12 changes: 9 additions & 3 deletions src/librustc_mir/build/mod.rs
Original file line number Diff line number Diff line change
@@ -249,7 +249,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
visibility_scopes: IndexVec::new(),
visibility_scope: ARGUMENT_VISIBILITY_SCOPE,
breakable_scopes: vec![],
local_decls: IndexVec::from_elem_n(LocalDecl::new_return_pointer(return_ty), 1),
local_decls: IndexVec::from_elem_n(LocalDecl::new_return_pointer(return_ty,
span), 1),
var_indices: NodeMap(),
unit_temp: None,
cached_resume_block: None,
@@ -304,8 +305,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
self.local_decls.push(LocalDecl {
mutability: Mutability::Not,
ty: ty,
source_info: None,
source_info: SourceInfo {
scope: ARGUMENT_VISIBILITY_SCOPE,
span: pattern.map_or(self.fn_span, |pat| pat.span)
},
name: name,
is_user_variable: false,
});
}

@@ -341,7 +346,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
Some(ref tmp) => tmp.clone(),
None => {
let ty = self.hir.unit_ty();
let tmp = self.temp(ty);
let fn_span = self.fn_span;
let tmp = self.temp(ty, fn_span);
self.unit_temp = Some(tmp.clone());
tmp
}
33 changes: 33 additions & 0 deletions src/librustc_mir/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -244,6 +244,39 @@ let baz: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
```
"##,

E0161: r##"
A value was moved. However, its size was not known at compile time, and only
values of a known size can be moved.
Erroneous code example:
```compile_fail
#![feature(box_syntax)]
fn main() {
let array: &[isize] = &[1, 2, 3];
let _x: Box<[isize]> = box *array;
// error: cannot move a value of type [isize]: the size of [isize] cannot
// be statically determined
}
```
In Rust, you can only move a value when its size is known at compile time.
To work around this restriction, consider "hiding" the value behind a reference:
either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
it around as usual. Example:
```
#![feature(box_syntax)]
fn main() {
let array: &[isize] = &[1, 2, 3];
let _x: Box<&[isize]> = box array; // ok!
}
```
"##,

E0396: r##"
The value behind a raw pointer can't be determined at compile-time
(or even link-time), which means it can't be used in a constant
23 changes: 14 additions & 9 deletions src/librustc_mir/shim.rs
Original file line number Diff line number Diff line change
@@ -137,16 +137,20 @@ enum CallKind {
Direct(DefId),
}

fn temp_decl(mutability: Mutability, ty: Ty) -> LocalDecl {
LocalDecl { mutability, ty, name: None, source_info: None }
fn temp_decl(mutability: Mutability, ty: Ty, span: Span) -> LocalDecl {
LocalDecl {
mutability, ty, name: None,
source_info: SourceInfo { scope: ARGUMENT_VISIBILITY_SCOPE, span },
is_user_variable: false
}
}

fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>)
fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>, span: Span)
-> IndexVec<Local, LocalDecl<'tcx>>
{
iter::once(temp_decl(Mutability::Mut, sig.output()))
iter::once(temp_decl(Mutability::Mut, sig.output(), span))
.chain(sig.inputs().iter().map(
|ity| temp_decl(Mutability::Not, ity)))
|ity| temp_decl(Mutability::Not, ity, span)))
.collect()
}

@@ -188,7 +192,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
),
IndexVec::new(),
sig.output(),
local_decls_for_sig(&sig),
local_decls_for_sig(&sig, span),
sig.inputs().len(),
vec![],
span
@@ -297,7 +301,7 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,

debug!("build_call_shim: sig={:?}", sig);

let mut local_decls = local_decls_for_sig(&sig);
let mut local_decls = local_decls_for_sig(&sig, span);
let source_info = SourceInfo { span, scope: ARGUMENT_VISIBILITY_SCOPE };

let rcvr_arg = Local::new(1+0);
@@ -317,7 +321,8 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
tcx.mk_ref(re_erased, ty::TypeAndMut {
ty: sig.inputs()[0],
mutbl: hir::Mutability::MutMutable
})
}),
span
));
statements.push(Statement {
source_info: source_info,
@@ -442,7 +447,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,

debug!("build_ctor: def_id={:?} sig={:?} fields={:?}", def_id, sig, fields);

let local_decls = local_decls_for_sig(&sig);
let local_decls = local_decls_for_sig(&sig, span);

let source_info = SourceInfo {
span: span,
15 changes: 6 additions & 9 deletions src/librustc_mir/transform/inline.rs
Original file line number Diff line number Diff line change
@@ -461,11 +461,8 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
for loc in callee_mir.vars_and_temps_iter() {
let mut local = callee_mir.local_decls[loc].clone();

if let Some(ref mut source_info) = local.source_info {
source_info.scope = scope_map[source_info.scope];

source_info.span = callsite.location.span;
}
local.source_info.scope = scope_map[local.source_info.scope];
local.source_info.span = callsite.location.span;

let idx = caller_mir.local_decls.push(local);
local_map.push(idx);
@@ -506,7 +503,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {

let ty = dest.ty(caller_mir, self.tcx);

let temp = LocalDecl::new_temp(ty);
let temp = LocalDecl::new_temp(ty, callsite.location.span);

let tmp = caller_mir.local_decls.push(temp);
let tmp = Lvalue::Local(tmp);
@@ -590,7 +587,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
arg.deref());

let ty = arg.ty(caller_mir, self.tcx);
let ref_tmp = LocalDecl::new_temp(ty);
let ref_tmp = LocalDecl::new_temp(ty, callsite.location.span);
let ref_tmp = caller_mir.local_decls.push(ref_tmp);
let ref_tmp = Lvalue::Local(ref_tmp);

@@ -611,7 +608,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {

let raw_ptr = Rvalue::Cast(CastKind::Misc, Operand::Consume(ref_tmp), ptr_ty);

let cast_tmp = LocalDecl::new_temp(ptr_ty);
let cast_tmp = LocalDecl::new_temp(ptr_ty, callsite.location.span);
let cast_tmp = caller_mir.local_decls.push(cast_tmp);
let cast_tmp = Lvalue::Local(cast_tmp);

@@ -645,7 +642,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {

let ty = arg.ty(caller_mir, tcx);

let arg_tmp = LocalDecl::new_temp(ty);
let arg_tmp = LocalDecl::new_temp(ty, callsite.location.span);
let arg_tmp = caller_mir.local_decls.push(arg_tmp);
let arg_tmp = Lvalue::Local(arg_tmp);

6 changes: 4 additions & 2 deletions src/librustc_mir/transform/promote_consts.rs
Original file line number Diff line number Diff line change
@@ -208,7 +208,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {

let no_stmts = self.source[loc.block].statements.len();
let new_temp = self.promoted.local_decls.push(
LocalDecl::new_temp(self.source.local_decls[temp].ty));
LocalDecl::new_temp(self.source.local_decls[temp].ty,
self.source.local_decls[temp].source_info.span));

debug!("promote({:?} @ {:?}/{:?}, {:?})",
temp, loc, no_stmts, self.keep_original);
@@ -379,7 +380,8 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
};

// Declare return pointer local
let initial_locals = iter::once(LocalDecl::new_return_pointer(ty)).collect();
let initial_locals = iter::once(LocalDecl::new_return_pointer(ty, span))
.collect();

let mut promoter = Promoter {
promoted: Mir::new(
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
@@ -881,7 +881,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
// Avoid a generic error for other uses of arguments.
if self.qualif.intersects(Qualif::FN_ARGUMENT) {
let decl = &self.mir.local_decls[index];
span_err!(self.tcx.sess, decl.source_info.unwrap().span, E0022,
span_err!(self.tcx.sess, decl.source_info.span, E0022,
"arguments of constant functions can only \
be immutable by-value bindings");
return;
52 changes: 48 additions & 4 deletions src/librustc_mir/transform/type_check.rs
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ use std::fmt;
use syntax::ast;
use syntax_pos::{Span, DUMMY_SP};

use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::indexed_vec::Idx;

fn mirbug(tcx: TyCtxt, span: Span, msg: &str) {
@@ -87,6 +88,11 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
self.sanitize_type(rvalue, rval_ty);
}

fn visit_local_decl(&mut self, local_decl: &LocalDecl<'tcx>) {
self.super_local_decl(local_decl);
self.sanitize_type(local_decl, local_decl.ty);
}

fn visit_mir(&mut self, mir: &Mir<'tcx>) {
self.sanitize_type(&"return type", mir.return_ty);
for local_decl in &mir.local_decls {
@@ -317,6 +323,7 @@ pub struct TypeChecker<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
fulfillment_cx: traits::FulfillmentContext<'tcx>,
last_span: Span,
body_id: ast::NodeId,
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
}

impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
@@ -326,6 +333,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
fulfillment_cx: traits::FulfillmentContext::new(),
last_span: DUMMY_SP,
body_id: body_id,
reported_errors: FxHashSet(),
}
}

@@ -641,9 +649,43 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
}
}

fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
fn check_local(&mut self, mir: &Mir<'gcx>, local: Local, local_decl: &LocalDecl<'gcx>) {
match mir.local_kind(local) {
LocalKind::ReturnPointer | LocalKind::Arg => {
// return values of normal functions are required to be
// sized by typeck, but return values of ADT constructors are
// not because we don't include a `Self: Sized` bounds on them.
//
// Unbound parts of arguments were never required to be Sized
// - maybe we should make that a warning.
return
}
LocalKind::Var | LocalKind::Temp => {}
}

let span = local_decl.source_info.span;
let ty = local_decl.ty;
if !ty.is_sized(self.tcx().global_tcx(), self.infcx.param_env(), span) {
// in current MIR construction, all non-control-flow rvalue
// expressions evaluate through `as_temp` or `into` a return
// slot or local, so to find all unsized rvalues it is enough
// to check all temps, return slots and locals.
if let None = self.reported_errors.replace((ty, span)) {
span_err!(self.tcx().sess, span, E0161,
"cannot move a value of type {0}: the size of {0} \
cannot be statically determined", ty);
}
}
}

fn typeck_mir(&mut self, mir: &Mir<'gcx>) {
self.last_span = mir.span;
debug!("run_on_mir: {:?}", mir.span);

for (local, local_decl) in mir.local_decls.iter_enumerated() {
self.check_local(mir, local, local_decl);
}

for block in mir.basic_blocks() {
for stmt in &block.statements {
if stmt.source_info.span != DUMMY_SP {
@@ -698,16 +740,18 @@ impl TypeckMir {
impl<'tcx> MirPass<'tcx> for TypeckMir {
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource, mir: &mut Mir<'tcx>) {
debug!("run_pass: {}", tcx.node_path_str(src.item_id()));
let item_id = src.item_id();
let def_id = tcx.hir.local_def_id(item_id);
debug!("run_pass: {}", tcx.item_path_str(def_id));

if tcx.sess.err_count() > 0 {
// compiling a broken program can obviously result in a
// broken MIR, so try not to report duplicate errors.
return;
}
let param_env = ty::ParameterEnvironment::for_item(tcx, src.item_id());
let param_env = ty::ParameterEnvironment::for_item(tcx, item_id);
tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
let mut checker = TypeChecker::new(&infcx, src.item_id());
let mut checker = TypeChecker::new(&infcx, item_id);
{
let mut verifier = TypeVerifier::new(&mut checker, mir);
verifier.visit_mir(mir);
2 changes: 1 addition & 1 deletion src/librustc_mir/util/elaborate_drops.rs
Original file line number Diff line number Diff line change
@@ -686,7 +686,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
}

fn new_temp(&mut self, ty: Ty<'tcx>) -> Local {
self.elaborator.patch().new_temp(ty)
self.elaborator.patch().new_temp(ty, self.source_info.span)
}

fn terminator_loc(&mut self, bb: BasicBlock) -> Location {
5 changes: 3 additions & 2 deletions src/librustc_mir/util/patch.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
use rustc::ty::Ty;
use rustc::mir::*;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use syntax_pos::Span;

/// This struct represents a patch to MIR, which can add
/// new statements and basic blocks and patch over block
@@ -92,10 +93,10 @@ impl<'tcx> MirPatch<'tcx> {
}
}

pub fn new_temp(&mut self, ty: Ty<'tcx>) -> Local {
pub fn new_temp(&mut self, ty: Ty<'tcx>, span: Span) -> Local {
let index = self.next_local;
self.next_local += 1;
self.new_locals.push(LocalDecl::new_temp(ty));
self.new_locals.push(LocalDecl::new_temp(ty, span));
Local::new(index as usize)
}

4 changes: 2 additions & 2 deletions src/librustc_mir/util/pretty.rs
Original file line number Diff line number Diff line change
@@ -196,8 +196,8 @@ fn write_scope_tree(tcx: TyCtxt,
// User variable types (including the user's name in a comment).
for local in mir.vars_iter() {
let var = &mir.local_decls[local];
let (name, source_info) = if var.source_info.unwrap().scope == child {
(var.name.unwrap(), var.source_info.unwrap())
let (name, source_info) = if var.source_info.scope == child {
(var.name.unwrap(), var.source_info)
} else {
// Not a variable or not declared in this scope.
continue;
33 changes: 0 additions & 33 deletions src/librustc_passes/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -82,39 +82,6 @@ extern {
```
"##,

E0161: r##"
A value was moved. However, its size was not known at compile time, and only
values of a known size can be moved.
Erroneous code example:
```compile_fail
#![feature(box_syntax)]
fn main() {
let array: &[isize] = &[1, 2, 3];
let _x: Box<[isize]> = box *array;
// error: cannot move a value of type [isize]: the size of [isize] cannot
// be statically determined
}
```
In Rust, you can only move a value when its size is known at compile time.
To work around this restriction, consider "hiding" the value behind a reference:
either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
it around as usual. Example:
```
#![feature(box_syntax)]
fn main() {
let array: &[isize] = &[1, 2, 3];
let _x: Box<&[isize]> = box array; // ok!
}
```
"##,

E0265: r##"
This error indicates that a static or constant references itself.
All statics and constants need to resolve to a value in an acyclic manner.
1 change: 0 additions & 1 deletion src/librustc_passes/lib.rs
Original file line number Diff line number Diff line change
@@ -47,5 +47,4 @@ pub mod hir_stats;
pub mod loops;
pub mod mir_stats;
pub mod no_asm;
pub mod rvalues;
pub mod static_recursion;
103 changes: 0 additions & 103 deletions src/librustc_passes/rvalues.rs

This file was deleted.

2 changes: 1 addition & 1 deletion src/librustc_trans/debuginfo/create_scope_map.rs
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ pub fn create_mir_scopes(ccx: &CrateContext, mir: &Mir, debug_context: &Function
let mut has_variables = BitVector::new(mir.visibility_scopes.len());
for var in mir.vars_iter() {
let decl = &mir.local_decls[var];
has_variables.insert(decl.source_info.unwrap().scope.index());
has_variables.insert(decl.source_info.scope.index());
}

// Instantiate all scopes.
5 changes: 2 additions & 3 deletions src/librustc_trans/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -255,8 +255,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(

if let Some(name) = decl.name {
// User variable
let source_info = decl.source_info.unwrap();
let debug_scope = mircx.scopes[source_info.scope];
let debug_scope = mircx.scopes[decl.source_info.scope];
let dbg = debug_scope.is_valid() && bcx.sess().opts.debuginfo == FullDebugInfo;

if !lvalue_locals.contains(local.index()) && !dbg {
@@ -268,7 +267,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
assert!(!ty.has_erasable_regions());
let lvalue = LvalueRef::alloca(&bcx, ty, &name.as_str());
if dbg {
let (scope, span) = mircx.debug_loc(source_info);
let (scope, span) = mircx.debug_loc(decl.source_info);
declare_local(&bcx, &mircx.debug_context, name, ty, scope,
VariableAccess::DirectVariable { alloca: lvalue.llval },
VariableKind::LocalVariable, span);
18 changes: 18 additions & 0 deletions src/test/compile-fail/issue-41139.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2017 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.

trait Trait {}

fn get_function<'a>() -> &'a Fn() -> Trait { panic!("") }

fn main() {
let t : &Trait = &get_function()();
//~^ ERROR cannot move a value of type Trait + 'static
}