Skip to content

Commit 3e0b060

Browse files
Const-check functions in a const impl
1 parent 62ff11f commit 3e0b060

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

src/librustc_mir/const_eval/fn_queries.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ pub fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
2626

2727
/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
2828
pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
29+
// FIXME: check for `rustc_const_unstable` on the containing impl. This should be done by
30+
// propagating it down so it is return by the `lookup_const_stability` query.
2931
if tcx.is_const_fn_raw(def_id) {
3032
let const_stab = tcx.lookup_const_stability(def_id)?;
3133
if const_stab.level.is_unstable() { Some(const_stab.feature) } else { None }
@@ -111,7 +113,18 @@ pub fn provide(providers: &mut Providers<'_>) {
111113
if let Some(whitelisted) = is_const_intrinsic(tcx, def_id) {
112114
whitelisted
113115
} else if let Some(fn_like) = FnLikeNode::from_node(node) {
114-
fn_like.constness() == hir::Constness::Const
116+
if fn_like.constness() == hir::Constness::Const {
117+
return true;
118+
}
119+
120+
// If the function itself is not annotated with `const`, it may still be a `const fn`
121+
// if it resides in a const trait impl.
122+
let parent_id = tcx.hir().get_parent_did(hir_id);
123+
if def_id != parent_id && !parent_id.is_top_level_module() {
124+
is_const_impl_raw(tcx, LocalDefId::from_def_id(parent_id))
125+
} else {
126+
false
127+
}
115128
} else if let hir::Node::Ctor(_) = node {
116129
true
117130
} else {

0 commit comments

Comments
 (0)