diff options
| author | Gary Guo <gary@garyguo.net> | 2020-06-26 23:33:35 +0100 |
|---|---|---|
| committer | Gary Guo <gary@garyguo.net> | 2020-06-27 00:53:18 +0100 |
| commit | 779b05d16a38fec347a874210e2ae54579a8f5c1 (patch) | |
| tree | 4f8d6719b6c4bedbeba4a7e0d1ff5b59e1db3b64 | |
| parent | fc239e82fe1ef91632dfa858487d89141aaab7a7 (diff) | |
| download | rust-779b05d16a38fec347a874210e2ae54579a8f5c1.tar.gz rust-779b05d16a38fec347a874210e2ae54579a8f5c1.zip | |
Fix ICE for lib features
| -rw-r--r-- | src/librustc_mir/transform/check_consts/validation.rs | 4 | ||||
| -rw-r--r-- | src/librustc_mir/transform/qualify_min_const_fn.rs | 25 |
2 files changed, 25 insertions, 4 deletions
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 80257260f01..bd9d33e67f8 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -550,9 +550,9 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { } else if let Some(feature) = is_unstable_const_fn(self.tcx, def_id) { // Exempt unstable const fns inside of macros or functions with // `#[allow_internal_unstable]`. - use crate::transform::qualify_min_const_fn::feature_allowed; + use crate::transform::qualify_min_const_fn::lib_feature_allowed; if !self.span.allows_unstable(feature) - && !feature_allowed(self.tcx, self.def_id, feature) + && !lib_feature_allowed(self.tcx, self.def_id, feature) { self.check_op(ops::FnCallUnstable(def_id, feature)); } diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 6f252ad4ed5..7c54acf2163 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -315,7 +315,7 @@ fn check_place( } /// Returns `true` if the given feature gate is allowed within the function with the given `DefId`. -pub fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool { +fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool { // All features require that the corresponding gate be enabled, // even if the function has `#[allow_internal_unstable(the_gate)]`. if !tcx.features().enabled(feature_gate) { @@ -334,6 +334,26 @@ pub fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) - .map_or(false, |mut features| features.any(|name| name == feature_gate)) } +/// Returns `true` if the given library feature gate is allowed within the function with the given `DefId`. +pub fn lib_feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool { + // All features require that the corresponding gate be enabled, + // even if the function has `#[allow_internal_unstable(the_gate)]`. + if !tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == feature_gate) { + return false; + } + + // If this crate is not using stability attributes, or this function is not claiming to be a + // stable `const fn`, that is all that is required. + if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) { + return true; + } + + // However, we cannot allow stable `const fn`s to use unstable features without an explicit + // opt-in via `allow_internal_unstable`. + attr::allow_internal_unstable(&tcx.get_attrs(def_id), &tcx.sess.diagnostic()) + .map_or(false, |mut features| features.any(|name| name == feature_gate)) +} + fn check_terminator( tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, @@ -383,7 +403,8 @@ fn check_terminator( if !crate::const_eval::is_min_const_fn(tcx, fn_def_id) && !crate::const_eval::is_unstable_const_fn(tcx, fn_def_id) .map(|feature| { - span.allows_unstable(feature) || feature_allowed(tcx, def_id, feature) + span.allows_unstable(feature) + || lib_feature_allowed(tcx, def_id, feature) }) .unwrap_or(false) { |
