Skip to content

Commit ba92154

Browse files
committed
Auto merge of #51570 - oli-obk:demotion, r=<try>
Do not promote constants that contain unpromotable code r? @eddyb cc @nikomatsakis I'll add more tests, just getting this out for a crater run
2 parents c45ae9e + 1030037 commit ba92154

25 files changed

+457
-154
lines changed

src/librustc/hir/map/blocks.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ impl MaybeFnLike for ast::Item {
5252
}
5353
}
5454

55+
impl MaybeFnLike for ast::ImplItem {
56+
fn is_fn_like(&self) -> bool {
57+
match self.node { ast::ImplItemKind::Method(..) => true, _ => false, }
58+
}
59+
}
60+
5561
impl MaybeFnLike for ast::TraitItem {
5662
fn is_fn_like(&self) -> bool {
5763
match self.node {
@@ -144,7 +150,7 @@ impl<'a> FnLikeNode<'a> {
144150
let fn_like = match node {
145151
map::NodeItem(item) => item.is_fn_like(),
146152
map::NodeTraitItem(tm) => tm.is_fn_like(),
147-
map::NodeImplItem(_) => true,
153+
map::NodeImplItem(it) => it.is_fn_like(),
148154
map::NodeExpr(e) => e.is_fn_like(),
149155
_ => false
150156
};

src/librustc/ty/steal.rs

+5
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ impl<T> Steal<T> {
4949
})
5050
}
5151

52+
/// In case of cyclic queries, use this function to break the cycle
53+
pub fn try_borrow(&self) -> ReadGuard<Option<T>> {
54+
self.value.borrow()
55+
}
56+
5257
pub fn steal(&self) -> T {
5358
let value_ref = &mut *self.value.try_write().expect("stealing value which is locked");
5459
let value = mem::replace(value_ref, None);

src/librustc_metadata/decoder.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,9 @@ impl<'tcx> EntryKind<'tcx> {
415415
EntryKind::ForeignMutStatic => Def::Static(did, true),
416416
EntryKind::Struct(_, _) => Def::Struct(did),
417417
EntryKind::Union(_, _) => Def::Union(did),
418-
EntryKind::Fn(_) |
418+
EntryKind::Fn(..) |
419419
EntryKind::ForeignFn(_) => Def::Fn(did),
420-
EntryKind::Method(_) => Def::Method(did),
420+
EntryKind::Method(..) => Def::Method(did),
421421
EntryKind::Type => Def::TyAlias(did),
422422
EntryKind::AssociatedType(_) => Def::AssociatedTy(did),
423423
EntryKind::Mod(_) => Def::Mod(did),
@@ -765,7 +765,13 @@ impl<'a, 'tcx> CrateMetadata {
765765
match self.entry(id).kind {
766766
EntryKind::AssociatedConst(_, data, _) |
767767
EntryKind::Const(data, _) => data.ast_promotable,
768-
_ => bug!(),
768+
EntryKind::Fn(ref data) => {
769+
data.decode(self).qualif.map_or(false, |q| q.ast_promotable)
770+
},
771+
EntryKind::Method(ref data) => {
772+
data.decode(self).fn_data.qualif.map_or(false, |q| q.ast_promotable)
773+
},
774+
_ => bug!("{:?}", id),
769775
}
770776
}
771777

@@ -791,6 +797,8 @@ impl<'a, 'tcx> CrateMetadata {
791797
EntryKind::AssociatedConst(AssociatedContainer::ImplFinal, qualif, _) => {
792798
qualif.mir
793799
}
800+
EntryKind::Method(data) => data.decode(self).fn_data.qualif.map_or(0, |q| q.mir),
801+
EntryKind::Fn(data) => data.decode(self).qualif.map_or(0, |q| q.mir),
794802
_ => bug!(),
795803
}
796804
}

src/librustc_metadata/encoder.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
827827
constness: hir::Constness::NotConst,
828828
arg_names,
829829
sig: self.lazy(&tcx.fn_sig(def_id)),
830+
qualif: None,
830831
}
831832
} else {
832833
bug!()
@@ -880,6 +881,20 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
880881
!self.tcx.sess.opts.output_types.should_codegen()
881882
}
882883

884+
fn const_fn_qualif(
885+
&self,
886+
def_id: DefId,
887+
body_id: hir::BodyId,
888+
span: Span,
889+
) -> Option<ConstQualif> {
890+
if self.tcx.is_const_fn(def_id) {
891+
let mir = self.tcx.at(span).mir_const_qualif(def_id).0;
892+
Some(self.const_qualif(mir, body_id))
893+
} else {
894+
None
895+
}
896+
}
897+
883898
fn const_qualif(&self, mir: u8, body_id: hir::BodyId) -> ConstQualif {
884899
let body_owner_def_id = self.tcx.hir.body_owner_def_id(body_id);
885900
let ast_promotable = self.tcx.const_is_rvalue_promotable_to_static(body_owner_def_id);
@@ -915,11 +930,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
915930
}
916931
}
917932
ty::AssociatedKind::Method => {
918-
let fn_data = if let hir::ImplItemKind::Method(ref sig, body) = ast_item.node {
933+
let fn_data = if let hir::ImplItemKind::Method(ref sig, body_id) = ast_item.node {
919934
FnData {
920935
constness: sig.constness,
921-
arg_names: self.encode_fn_arg_names_for_body(body),
936+
arg_names: self.encode_fn_arg_names_for_body(body_id),
922937
sig: self.lazy(&tcx.fn_sig(def_id)),
938+
qualif: self.const_fn_qualif(def_id, body_id, ast_item.span),
923939
}
924940
} else {
925941
bug!()
@@ -1045,13 +1061,13 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
10451061
self.encode_rendered_const_for_body(body_id)
10461062
)
10471063
}
1048-
hir::ItemFn(_, _, constness, .., body) => {
1064+
hir::ItemFn(_, _, constness, .., body_id) => {
10491065
let data = FnData {
10501066
constness,
1051-
arg_names: self.encode_fn_arg_names_for_body(body),
1067+
arg_names: self.encode_fn_arg_names_for_body(body_id),
10521068
sig: self.lazy(&tcx.fn_sig(def_id)),
1069+
qualif: self.const_fn_qualif(def_id, body_id, item.span),
10531070
};
1054-
10551071
EntryKind::Fn(self.lazy(&data))
10561072
}
10571073
hir::ItemMod(ref m) => {
@@ -1565,6 +1581,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
15651581
constness: hir::Constness::NotConst,
15661582
arg_names: self.encode_fn_arg_names(names),
15671583
sig: self.lazy(&tcx.fn_sig(def_id)),
1584+
qualif: None,
15681585
};
15691586
EntryKind::ForeignFn(self.lazy(&data))
15701587
}

src/librustc_metadata/schema.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -434,9 +434,10 @@ pub struct FnData<'tcx> {
434434
pub constness: hir::Constness,
435435
pub arg_names: LazySeq<ast::Name>,
436436
pub sig: Lazy<ty::PolyFnSig<'tcx>>,
437+
pub qualif: Option<ConstQualif>,
437438
}
438439

439-
impl_stable_hash_for!(struct FnData<'tcx> { constness, arg_names, sig });
440+
impl_stable_hash_for!(struct FnData<'tcx> { constness, arg_names, sig, qualif });
440441

441442
#[derive(RustcEncodable, RustcDecodable)]
442443
pub struct VariantData<'tcx> {

src/librustc_mir/build/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use util as mir_util;
3535

3636
/// Construct the MIR for a given def-id.
3737
pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'tcx> {
38-
let id = tcx.hir.as_local_node_id(def_id).unwrap();
38+
let id = tcx.hir.as_local_node_id(def_id).expect("can't build non-local MIR");
3939
let unsupported = || {
4040
span_bug!(tcx.hir.span(id), "can't build MIR for {:?}", def_id);
4141
};

src/librustc_mir/transform/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
210210
// Ensure that we compute the `mir_const_qualif` for constants at
211211
// this point, before we steal the mir-const result.
212212
let _ = tcx.mir_const_qualif(def_id);
213+
} else if tcx.is_const_fn(def_id) {
214+
// Ensure that we compute the `mir_const_qualif` for const fns at
215+
// this point, before we steal the mir-const result.
216+
let _ = tcx.mir_const_qualif(def_id);
213217
}
214218

215219
let mut mir = tcx.mir_const(def_id).steal();

0 commit comments

Comments
 (0)