Skip to content

Commit 779b05d

Browse files
committed
Fix ICE for lib features
1 parent fc239e8 commit 779b05d

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

src/librustc_mir/transform/check_consts/validation.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,9 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
550550
} else if let Some(feature) = is_unstable_const_fn(self.tcx, def_id) {
551551
// Exempt unstable const fns inside of macros or functions with
552552
// `#[allow_internal_unstable]`.
553-
use crate::transform::qualify_min_const_fn::feature_allowed;
553+
use crate::transform::qualify_min_const_fn::lib_feature_allowed;
554554
if !self.span.allows_unstable(feature)
555-
&& !feature_allowed(self.tcx, self.def_id, feature)
555+
&& !lib_feature_allowed(self.tcx, self.def_id, feature)
556556
{
557557
self.check_op(ops::FnCallUnstable(def_id, feature));
558558
}

src/librustc_mir/transform/qualify_min_const_fn.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ fn check_place(
315315
}
316316

317317
/// Returns `true` if the given feature gate is allowed within the function with the given `DefId`.
318-
pub fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
318+
fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
319319
// All features require that the corresponding gate be enabled,
320320
// even if the function has `#[allow_internal_unstable(the_gate)]`.
321321
if !tcx.features().enabled(feature_gate) {
@@ -334,6 +334,26 @@ pub fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -
334334
.map_or(false, |mut features| features.any(|name| name == feature_gate))
335335
}
336336

337+
/// Returns `true` if the given library feature gate is allowed within the function with the given `DefId`.
338+
pub fn lib_feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
339+
// All features require that the corresponding gate be enabled,
340+
// even if the function has `#[allow_internal_unstable(the_gate)]`.
341+
if !tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == feature_gate) {
342+
return false;
343+
}
344+
345+
// If this crate is not using stability attributes, or this function is not claiming to be a
346+
// stable `const fn`, that is all that is required.
347+
if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) {
348+
return true;
349+
}
350+
351+
// However, we cannot allow stable `const fn`s to use unstable features without an explicit
352+
// opt-in via `allow_internal_unstable`.
353+
attr::allow_internal_unstable(&tcx.get_attrs(def_id), &tcx.sess.diagnostic())
354+
.map_or(false, |mut features| features.any(|name| name == feature_gate))
355+
}
356+
337357
fn check_terminator(
338358
tcx: TyCtxt<'tcx>,
339359
body: &'a Body<'tcx>,
@@ -383,7 +403,8 @@ fn check_terminator(
383403
if !crate::const_eval::is_min_const_fn(tcx, fn_def_id)
384404
&& !crate::const_eval::is_unstable_const_fn(tcx, fn_def_id)
385405
.map(|feature| {
386-
span.allows_unstable(feature) || feature_allowed(tcx, def_id, feature)
406+
span.allows_unstable(feature)
407+
|| lib_feature_allowed(tcx, def_id, feature)
387408
})
388409
.unwrap_or(false)
389410
{

0 commit comments

Comments
 (0)