Skip to content

Commit 235d774

Browse files
committed
Auto merge of #32080 - eddyb:transcendent, r=nikomatsakis
Refactor call & function handling in trans, enable MIR bootstrap. Non-Rust and Rust ABIs were combined into a common codepath, which means: * The ugly `__rust_abi` "clown shoes" shim for C->Rust FFI is gone, fixes #10116. * Methods, *including virtual ones* support non-Rust ABIs, closes #30235. * Non-Rust ABIs also pass fat pointers in two arguments; the result should be identical. * Zero-sized types are never passed as arguments; again, behavior shouldn't change. Additionally, MIR support for calling intrinsics (through old trans) was implemented. Alongside assorted fixes, it enabled MIR to launch 🚀 and do a *complete* bootstrap. To try it yourself, `./configure --enable-orbit` *or* `make RUSTFLAGS="-Z orbit"`.
2 parents 2de6ddd + b12dcde commit 235d774

File tree

155 files changed

+4601
-6369
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+4601
-6369
lines changed

Diff for: configure

+3
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,7 @@ opt dist-host-only 0 "only install bins for the host architecture"
607607
opt inject-std-version 1 "inject the current compiler version of libstd into programs"
608608
opt llvm-version-check 1 "check if the LLVM version is supported, build anyway"
609609
opt rustbuild 0 "use the rust and cargo based build system"
610+
opt orbit 0 "get MIR where it belongs - everywhere; most importantly, in orbit"
610611

611612
# Optimization and debugging options. These may be overridden by the release channel, etc.
612613
opt_nosave optimize 1 "build optimized rust code"
@@ -713,6 +714,8 @@ if [ -n "$CFG_ENABLE_DEBUG_ASSERTIONS" ]; then putvar CFG_ENABLE_DEBUG_ASSERTION
713714
if [ -n "$CFG_ENABLE_DEBUGINFO" ]; then putvar CFG_ENABLE_DEBUGINFO; fi
714715
if [ -n "$CFG_ENABLE_DEBUG_JEMALLOC" ]; then putvar CFG_ENABLE_DEBUG_JEMALLOC; fi
715716

717+
if [ -n "$CFG_ENABLE_ORBIT" ]; then putvar CFG_ENABLE_ORBIT; fi
718+
716719
# A magic value that allows the compiler to use unstable features
717720
# during the bootstrap even when doing so would normally be an error
718721
# because of feature staging or because the build turns on

Diff for: mk/main.mk

+5
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ ifdef CFG_ENABLE_DEBUGINFO
134134
CFG_RUSTC_FLAGS += -g
135135
endif
136136

137+
ifdef CFG_ENABLE_ORBIT
138+
$(info cfg: launching MIR (CFG_ENABLE_ORBIT))
139+
CFG_RUSTC_FLAGS += -Z orbit
140+
endif
141+
137142
ifdef SAVE_TEMPS
138143
CFG_RUSTC_FLAGS += --save-temps
139144
endif

Diff for: src/compiletest/header.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub struct TestProps {
3131
pub pp_exact: Option<PathBuf>,
3232
// Modules from aux directory that should be compiled
3333
pub aux_builds: Vec<String> ,
34+
// Environment settings to use for compiling
35+
pub rustc_env: Vec<(String,String)> ,
3436
// Environment settings to use during execution
3537
pub exec_env: Vec<(String,String)> ,
3638
// Lines to check if they appear in the expected debugger output
@@ -77,6 +79,7 @@ pub fn load_props(testfile: &Path) -> TestProps {
7779
pp_exact: pp_exact,
7880
aux_builds: aux_builds,
7981
revisions: vec![],
82+
rustc_env: vec![],
8083
exec_env: exec_env,
8184
check_lines: check_lines,
8285
build_aux_docs: build_aux_docs,
@@ -153,10 +156,14 @@ pub fn load_props_into(props: &mut TestProps, testfile: &Path, cfg: Option<&str>
153156
props.aux_builds.push(ab);
154157
}
155158

156-
if let Some(ee) = parse_exec_env(ln) {
159+
if let Some(ee) = parse_env(ln, "exec-env") {
157160
props.exec_env.push(ee);
158161
}
159162

163+
if let Some(ee) = parse_env(ln, "rustc-env") {
164+
props.rustc_env.push(ee);
165+
}
166+
160167
if let Some(cl) = parse_check_line(ln) {
161168
props.check_lines.push(cl);
162169
}
@@ -372,8 +379,8 @@ fn parse_pretty_compare_only(line: &str) -> bool {
372379
parse_name_directive(line, "pretty-compare-only")
373380
}
374381

375-
fn parse_exec_env(line: &str) -> Option<(String, String)> {
376-
parse_name_value_directive(line, "exec-env").map(|nv| {
382+
fn parse_env(line: &str, name: &str) -> Option<(String, String)> {
383+
parse_name_value_directive(line, name).map(|nv| {
377384
// nv is either FOO or FOO=BAR
378385
let mut strs: Vec<String> = nv
379386
.splitn(2, '=')

Diff for: src/compiletest/runtest.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -863,12 +863,28 @@ fn cleanup_debug_info_options(options: &Option<String>) -> Option<String> {
863863
"-g".to_owned(),
864864
"--debuginfo".to_owned()
865865
];
866-
let new_options =
866+
let mut new_options =
867867
split_maybe_args(options).into_iter()
868868
.filter(|x| !options_to_remove.contains(x))
869-
.collect::<Vec<String>>()
870-
.join(" ");
871-
Some(new_options)
869+
.collect::<Vec<String>>();
870+
871+
let mut i = 0;
872+
while i + 1 < new_options.len() {
873+
if new_options[i] == "-Z" {
874+
// FIXME #31005 MIR missing debuginfo currently.
875+
if new_options[i + 1] == "orbit" {
876+
// Remove "-Z" and "orbit".
877+
new_options.remove(i);
878+
new_options.remove(i);
879+
continue;
880+
}
881+
// Always skip over -Z's argument.
882+
i += 1;
883+
}
884+
i += 1;
885+
}
886+
887+
Some(new_options.join(" "))
872888
}
873889

874890
fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String]) {
@@ -1386,7 +1402,7 @@ fn compose_and_run_compiler(config: &Config, props: &TestProps,
13861402
compose_and_run(config,
13871403
testpaths,
13881404
args,
1389-
Vec::new(),
1405+
props.rustc_env.clone(),
13901406
&config.compile_lib_path,
13911407
Some(aux_dir.to_str().unwrap()),
13921408
input)

Diff for: src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
#![feature(reflect)]
7373
#![feature(unwind_attributes)]
7474
#![feature(repr_simd, platform_intrinsics)]
75+
#![feature(rustc_attrs)]
7576
#![feature(staged_api)]
7677
#![feature(unboxed_closures)]
7778

Diff for: src/libcore/num/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,7 @@ macro_rules! int_impl {
10081008
/// ```
10091009
#[stable(feature = "rust1", since = "1.0.0")]
10101010
#[inline]
1011+
#[cfg_attr(not(stage0), rustc_no_mir)] // FIXME #29769 MIR overflow checking is TBD.
10111012
pub fn pow(self, mut exp: u32) -> Self {
10121013
let mut base = self;
10131014
let mut acc = Self::one();
@@ -1049,6 +1050,7 @@ macro_rules! int_impl {
10491050
/// ```
10501051
#[stable(feature = "rust1", since = "1.0.0")]
10511052
#[inline]
1053+
#[cfg_attr(not(stage0), rustc_no_mir)] // FIXME #29769 MIR overflow checking is TBD.
10521054
pub fn abs(self) -> Self {
10531055
if self.is_negative() {
10541056
// Note that the #[inline] above means that the overflow
@@ -2013,6 +2015,7 @@ macro_rules! uint_impl {
20132015
/// ```
20142016
#[stable(feature = "rust1", since = "1.0.0")]
20152017
#[inline]
2018+
#[cfg_attr(not(stage0), rustc_no_mir)] // FIXME #29769 MIR overflow checking is TBD.
20162019
pub fn pow(self, mut exp: u32) -> Self {
20172020
let mut base = self;
20182021
let mut acc = Self::one();

Diff for: src/librustc/front/map/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use middle::def_id::DefId;
2222

2323
use syntax::abi::Abi;
2424
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID};
25+
use syntax::attr::ThinAttributesExt;
2526
use syntax::codemap::{Span, Spanned};
2627
use syntax::parse::token;
2728

@@ -718,6 +719,8 @@ impl<'ast> Map<'ast> {
718719
Some(NodeTraitItem(ref ti)) => Some(&ti.attrs[..]),
719720
Some(NodeImplItem(ref ii)) => Some(&ii.attrs[..]),
720721
Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]),
722+
Some(NodeExpr(ref e)) => Some(e.attrs.as_attr_slice()),
723+
Some(NodeStmt(ref s)) => Some(s.node.attrs()),
721724
// unit/tuple structs take the attributes straight from
722725
// the struct definition.
723726
Some(NodeStructCtor(_)) => {

Diff for: src/librustc/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ mod macros;
7373
pub mod diagnostics;
7474

7575
pub mod back {
76-
pub use rustc_back::abi;
7776
pub use rustc_back::rpath;
7877
pub use rustc_back::svh;
7978
}

Diff for: src/librustc/middle/cfg/construct.rs

+4-13
Original file line numberDiff line numberDiff line change
@@ -354,19 +354,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
354354
self.straightline(expr, pred, Some(&**e).into_iter())
355355
}
356356

357-
hir::ExprInlineAsm(ref inline_asm) => {
358-
let inputs = inline_asm.inputs.iter();
359-
let outputs = inline_asm.outputs.iter();
360-
let post_inputs = self.exprs(inputs.map(|a| {
361-
debug!("cfg::construct InlineAsm id:{} input:{:?}", expr.id, a);
362-
let &(_, ref expr) = a;
363-
&**expr
364-
}), pred);
365-
let post_outputs = self.exprs(outputs.map(|a| {
366-
debug!("cfg::construct InlineAsm id:{} output:{:?}", expr.id, a);
367-
&*a.expr
368-
}), post_inputs);
369-
self.add_ast_node(expr.id, &[post_outputs])
357+
hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
358+
let post_outputs = self.exprs(outputs.iter().map(|e| &**e), pred);
359+
let post_inputs = self.exprs(inputs.iter().map(|e| &**e), post_outputs);
360+
self.add_ast_node(expr.id, &[post_inputs])
370361
}
371362

372363
hir::ExprClosure(..) |

Diff for: src/librustc/middle/check_match.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -475,9 +475,9 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
475475
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
476476
match def {
477477
Some(Def::AssociatedConst(did)) |
478-
Some(Def::Const(did)) => match lookup_const_by_id(self.tcx, did,
479-
Some(pat.id), None) {
480-
Some((const_expr, _const_ty)) => {
478+
Some(Def::Const(did)) => {
479+
let substs = Some(self.tcx.node_id_item_substs(pat.id).substs);
480+
if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) {
481481
const_expr_to_pat(self.tcx, const_expr, pat.span).map(|new_pat| {
482482

483483
if let Some(ref mut renaming_map) = self.renaming_map {
@@ -487,14 +487,13 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
487487

488488
new_pat
489489
})
490-
}
491-
None => {
490+
} else {
492491
self.failed = true;
493492
span_err!(self.tcx.sess, pat.span, E0158,
494493
"statics cannot be referenced in patterns");
495494
pat
496495
}
497-
},
496+
}
498497
_ => noop_fold_pat(pat, self)
499498
}
500499
}

Diff for: src/librustc/middle/const_eval.rs

+25-42
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use front::map::blocks::FnLikeNode;
1919
use middle::cstore::{self, CrateStore, InlinedItem};
2020
use middle::{infer, subst, traits};
2121
use middle::def::Def;
22-
use middle::subst::Subst;
2322
use middle::def_id::DefId;
2423
use middle::pat_util::def_to_path;
2524
use middle::ty::{self, Ty, TyCtxt};
@@ -89,16 +88,13 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::TyCtxt,
8988
}
9089

9190
/// * `def_id` is the id of the constant.
92-
/// * `maybe_ref_id` is the id of the expr referencing the constant.
93-
/// * `param_substs` is the monomorphization substitution for the expression.
91+
/// * `substs` is the monomorphized substitutions for the expression.
9492
///
95-
/// `maybe_ref_id` and `param_substs` are optional and are used for
96-
/// finding substitutions in associated constants. This generally
97-
/// happens in late/trans const evaluation.
93+
/// `substs` is optional and is used for associated constants.
94+
/// This generally happens in late/trans const evaluation.
9895
pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
9996
def_id: DefId,
100-
maybe_ref_id: Option<ast::NodeId>,
101-
param_substs: Option<&'tcx subst::Substs<'tcx>>)
97+
substs: Option<subst::Substs<'tcx>>)
10298
-> Option<(&'tcx Expr, Option<ty::Ty<'tcx>>)> {
10399
if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
104100
match tcx.map.find(node_id) {
@@ -111,28 +107,20 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
111107
},
112108
Some(ast_map::NodeTraitItem(ti)) => match ti.node {
113109
hir::ConstTraitItem(_, _) => {
114-
match maybe_ref_id {
115-
// If we have a trait item, and we know the expression
116-
// that's the source of the obligation to resolve it,
110+
if let Some(substs) = substs {
111+
// If we have a trait item and the substitutions for it,
117112
// `resolve_trait_associated_const` will select an impl
118113
// or the default.
119-
Some(ref_id) => {
120-
let trait_id = tcx.trait_of_item(def_id)
121-
.unwrap();
122-
let mut substs = tcx.node_id_item_substs(ref_id)
123-
.substs;
124-
if let Some(param_substs) = param_substs {
125-
substs = substs.subst(tcx, param_substs);
126-
}
127-
resolve_trait_associated_const(tcx, ti, trait_id, substs)
128-
}
114+
let trait_id = tcx.trait_of_item(def_id).unwrap();
115+
resolve_trait_associated_const(tcx, ti, trait_id, substs)
116+
} else {
129117
// Technically, without knowing anything about the
130118
// expression that generates the obligation, we could
131119
// still return the default if there is one. However,
132120
// it's safer to return `None` than to return some value
133121
// that may differ from what you would get from
134122
// correctly selecting an impl.
135-
None => None
123+
None
136124
}
137125
}
138126
_ => None
@@ -153,7 +141,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
153141
}
154142
None => {}
155143
}
156-
let mut used_ref_id = false;
144+
let mut used_substs = false;
157145
let expr_ty = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
158146
cstore::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
159147
hir::ItemConst(ref ty, ref const_expr) => {
@@ -163,21 +151,15 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
163151
},
164152
cstore::FoundAst::Found(&InlinedItem::TraitItem(trait_id, ref ti)) => match ti.node {
165153
hir::ConstTraitItem(_, _) => {
166-
used_ref_id = true;
167-
match maybe_ref_id {
154+
used_substs = true;
155+
if let Some(substs) = substs {
168156
// As mentioned in the comments above for in-crate
169157
// constants, we only try to find the expression for
170158
// a trait-associated const if the caller gives us
171-
// the expression that refers to it.
172-
Some(ref_id) => {
173-
let mut substs = tcx.node_id_item_substs(ref_id)
174-
.substs;
175-
if let Some(param_substs) = param_substs {
176-
substs = substs.subst(tcx, param_substs);
177-
}
178-
resolve_trait_associated_const(tcx, ti, trait_id, substs)
179-
}
180-
None => None
159+
// the substitutions for the reference to it.
160+
resolve_trait_associated_const(tcx, ti, trait_id, substs)
161+
} else {
162+
None
181163
}
182164
}
183165
_ => None
@@ -190,10 +172,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
190172
},
191173
_ => None
192174
};
193-
// If we used the reference expression, particularly to choose an impl
175+
// If we used the substitutions, particularly to choose an impl
194176
// of a trait-associated const, don't cache that, because the next
195177
// lookup with the same def_id may yield a different result.
196-
if !used_ref_id {
178+
if !used_substs {
197179
tcx.extern_const_statics
198180
.borrow_mut()
199181
.insert(def_id, expr_ty.map(|(e, t)| (e.id, t)));
@@ -389,7 +371,8 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
389371
PatKind::Path(path.clone()),
390372
Some(Def::Const(def_id)) |
391373
Some(Def::AssociatedConst(def_id)) => {
392-
let (expr, _ty) = lookup_const_by_id(tcx, def_id, Some(expr.id), None).unwrap();
374+
let substs = Some(tcx.node_id_item_substs(expr.id).substs);
375+
let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap();
393376
return const_expr_to_pat(tcx, expr, span);
394377
},
395378
_ => unreachable!(),
@@ -788,12 +771,12 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
788771
match opt_def {
789772
Def::Const(def_id) |
790773
Def::AssociatedConst(def_id) => {
791-
let maybe_ref_id = if let ExprTypeChecked = ty_hint {
792-
Some(e.id)
774+
let substs = if let ExprTypeChecked = ty_hint {
775+
Some(tcx.node_id_item_substs(e.id).substs)
793776
} else {
794777
None
795778
};
796-
if let Some((e, ty)) = lookup_const_by_id(tcx, def_id, maybe_ref_id, None) {
779+
if let Some((e, ty)) = lookup_const_by_id(tcx, def_id, substs) {
797780
let item_hint = match ty {
798781
Some(ty) => ty_hint.checked_or(ty),
799782
None => ty_hint,
@@ -1077,7 +1060,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
10771060
traits::VtableImpl(ref impl_data) => {
10781061
match tcx.associated_consts(impl_data.impl_def_id)
10791062
.iter().find(|ic| ic.name == ti.name) {
1080-
Some(ic) => lookup_const_by_id(tcx, ic.def_id, None, None),
1063+
Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
10811064
None => match ti.node {
10821065
hir::ConstTraitItem(ref ty, Some(ref expr)) => {
10831066
Some((&*expr, ast_ty_to_prim_ty(tcx, ty)))

0 commit comments

Comments
 (0)