Skip to content

Commit 43dd3d5

Browse files
committed
Auto merge of #103284 - compiler-errors:const-sad, r=oli-obk
Revert "Unify tcx.constness and param env constness checks" Too much of a perf regression #102975 (comment), and an attempt in #103263 didn't fix it except for just a tiny bit. This change isn't really needed (see #102830 (comment)), so this should be an easy revert.
2 parents 629a414 + 751ac6c commit 43dd3d5

File tree

5 files changed

+123
-101
lines changed

5 files changed

+123
-101
lines changed

compiler/rustc_const_eval/src/const_eval/fn_queries.rs

+16-56
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
2525
/// report whether said intrinsic has a `rustc_const_{un,}stable` attribute. Otherwise, return
2626
/// `Constness::NotConst`.
2727
fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
28-
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
29-
match tcx.hir().get(hir_id) {
30-
hir::Node::Ctor(_) => hir::Constness::Const,
28+
let def_id = def_id.expect_local();
29+
let node = tcx.hir().get_by_def_id(def_id);
3130

31+
match node {
32+
hir::Node::Ctor(_) => hir::Constness::Const,
33+
hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
3234
hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
3335
// Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
3436
// foreign items cannot be evaluated at compile-time.
@@ -39,62 +41,20 @@ fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
3941
};
4042
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
4143
}
44+
_ => {
45+
if let Some(fn_kind) = node.fn_kind() {
46+
if fn_kind.constness() == hir::Constness::Const {
47+
return hir::Constness::Const;
48+
}
4249

43-
hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. })
44-
if tcx.is_const_default_method(def_id) =>
45-
{
46-
hir::Constness::Const
47-
}
48-
49-
hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. })
50-
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. })
51-
| hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. })
52-
| hir::Node::AnonConst(_)
53-
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
54-
| hir::Node::ImplItem(hir::ImplItem {
55-
kind:
56-
hir::ImplItemKind::Fn(
57-
hir::FnSig {
58-
header: hir::FnHeader { constness: hir::Constness::Const, .. },
59-
..
60-
},
61-
..,
62-
),
63-
..
64-
}) => hir::Constness::Const,
65-
66-
hir::Node::ImplItem(hir::ImplItem {
67-
kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..),
68-
..
69-
}) => {
70-
let parent_hir_id = tcx.hir().get_parent_node(hir_id);
71-
match tcx.hir().get(parent_hir_id) {
72-
hir::Node::Item(hir::Item {
73-
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
74-
..
75-
}) => *constness,
76-
_ => span_bug!(
77-
tcx.def_span(parent_hir_id.owner),
78-
"impl item's parent node is not an impl",
79-
),
50+
// If the function itself is not annotated with `const`, it may still be a `const fn`
51+
// if it resides in a const trait impl.
52+
let is_const = is_parent_const_impl_raw(tcx, def_id);
53+
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
54+
} else {
55+
hir::Constness::NotConst
8056
}
8157
}
82-
83-
hir::Node::Item(hir::Item {
84-
kind: hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
85-
..
86-
})
87-
| hir::Node::TraitItem(hir::TraitItem {
88-
kind:
89-
hir::TraitItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
90-
..
91-
})
92-
| hir::Node::Item(hir::Item {
93-
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
94-
..
95-
}) => *constness,
96-
97-
_ => hir::Constness::NotConst,
9858
}
9959
}
10060

compiler/rustc_metadata/src/rmeta/encoder.rs

+15-41
Original file line numberDiff line numberDiff line change
@@ -1094,43 +1094,6 @@ fn should_encode_const(def_kind: DefKind) -> bool {
10941094
}
10951095
}
10961096

1097-
fn should_encode_constness(def_kind: DefKind) -> bool {
1098-
match def_kind {
1099-
DefKind::Struct
1100-
| DefKind::Union
1101-
| DefKind::Enum
1102-
| DefKind::Trait
1103-
| DefKind::AssocTy
1104-
| DefKind::Fn
1105-
| DefKind::Const
1106-
| DefKind::Static(..)
1107-
| DefKind::Ctor(..)
1108-
| DefKind::AssocFn
1109-
| DefKind::AssocConst
1110-
| DefKind::AnonConst
1111-
| DefKind::InlineConst
1112-
| DefKind::OpaqueTy
1113-
| DefKind::ImplTraitPlaceholder
1114-
| DefKind::Impl
1115-
| DefKind::Closure
1116-
| DefKind::Generator
1117-
| DefKind::TyAlias => true,
1118-
DefKind::Variant
1119-
| DefKind::TraitAlias
1120-
| DefKind::ForeignTy
1121-
| DefKind::Field
1122-
| DefKind::TyParam
1123-
| DefKind::Mod
1124-
| DefKind::ForeignMod
1125-
| DefKind::ConstParam
1126-
| DefKind::Macro(..)
1127-
| DefKind::Use
1128-
| DefKind::LifetimeParam
1129-
| DefKind::GlobalAsm
1130-
| DefKind::ExternCrate => false,
1131-
}
1132-
}
1133-
11341097
fn should_encode_trait_impl_trait_tys<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
11351098
if tcx.def_kind(def_id) != DefKind::AssocFn {
11361099
return false;
@@ -1239,9 +1202,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
12391202
{
12401203
record!(self.tables.trait_impl_trait_tys[def_id] <- table);
12411204
}
1242-
if should_encode_constness(def_kind) {
1243-
self.tables.constness.set(def_id.index, tcx.constness(def_id));
1244-
}
12451205
}
12461206
let inherent_impls = tcx.crate_inherent_impls(());
12471207
for (def_id, implementations) in inherent_impls.inherent_impls.iter() {
@@ -1269,6 +1229,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
12691229
};
12701230

12711231
record!(self.tables.variant_data[def_id] <- data);
1232+
self.tables.constness.set(def_id.index, hir::Constness::Const);
12721233
record_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
12731234
assert!(f.did.is_local());
12741235
f.did.index
@@ -1296,6 +1257,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
12961257
};
12971258

12981259
record!(self.tables.variant_data[def_id] <- data);
1260+
self.tables.constness.set(def_id.index, hir::Constness::Const);
12991261
if variant.ctor_kind == CtorKind::Fn {
13001262
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
13011263
}
@@ -1359,6 +1321,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13591321

13601322
record!(self.tables.repr_options[def_id] <- adt_def.repr());
13611323
record!(self.tables.variant_data[def_id] <- data);
1324+
self.tables.constness.set(def_id.index, hir::Constness::Const);
13621325
if variant.ctor_kind == CtorKind::Fn {
13631326
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
13641327
}
@@ -1394,6 +1357,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13941357
}
13951358
};
13961359
self.tables.asyncness.set(def_id.index, m_sig.header.asyncness);
1360+
self.tables.constness.set(def_id.index, hir::Constness::NotConst);
13971361
}
13981362
ty::AssocKind::Type => {
13991363
self.encode_explicit_item_bounds(def_id);
@@ -1418,6 +1382,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14181382
let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
14191383
self.tables.asyncness.set(def_id.index, sig.header.asyncness);
14201384
record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
1385+
// Can be inside `impl const Trait`, so using sig.header.constness is not reliable
1386+
let constness = if self.tcx.is_const_fn_raw(def_id) {
1387+
hir::Constness::Const
1388+
} else {
1389+
hir::Constness::NotConst
1390+
};
1391+
self.tables.constness.set(def_id.index, constness);
14211392
}
14221393
ty::AssocKind::Const | ty::AssocKind::Type => {}
14231394
}
@@ -1555,6 +1526,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
15551526
hir::ItemKind::Fn(ref sig, .., body) => {
15561527
self.tables.asyncness.set(def_id.index, sig.header.asyncness);
15571528
record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
1529+
self.tables.constness.set(def_id.index, sig.header.constness);
15581530
}
15591531
hir::ItemKind::Macro(ref macro_def, _) => {
15601532
if macro_def.macro_rules {
@@ -1575,6 +1547,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
15751547
hir::ItemKind::Struct(ref struct_def, _) => {
15761548
let adt_def = self.tcx.adt_def(def_id);
15771549
record!(self.tables.repr_options[def_id] <- adt_def.repr());
1550+
self.tables.constness.set(def_id.index, hir::Constness::Const);
15781551

15791552
// Encode def_ids for each field and method
15801553
// for methods, write all the stuff get_trait_method
@@ -1603,8 +1576,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
16031576
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
16041577
});
16051578
}
1606-
hir::ItemKind::Impl(hir::Impl { defaultness, .. }) => {
1579+
hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
16071580
self.tables.impl_defaultness.set(def_id.index, *defaultness);
1581+
self.tables.constness.set(def_id.index, *constness);
16081582

16091583
let trait_ref = self.tcx.impl_trait_ref(def_id);
16101584
if let Some(trait_ref) = trait_ref {

compiler/rustc_ty_utils/src/ty.rs

+73-1
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,82 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
137137
let local_did = def_id.as_local();
138138
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
139139

140+
// FIXME(consts): This is not exactly in line with the constness query.
141+
let constness = match hir_id {
142+
Some(hir_id) => match tcx.hir().get(hir_id) {
143+
hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. })
144+
if tcx.is_const_default_method(def_id) =>
145+
{
146+
hir::Constness::Const
147+
}
148+
149+
hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. })
150+
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. })
151+
| hir::Node::TraitItem(hir::TraitItem {
152+
kind: hir::TraitItemKind::Const(..), ..
153+
})
154+
| hir::Node::AnonConst(_)
155+
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
156+
| hir::Node::ImplItem(hir::ImplItem {
157+
kind:
158+
hir::ImplItemKind::Fn(
159+
hir::FnSig {
160+
header: hir::FnHeader { constness: hir::Constness::Const, .. },
161+
..
162+
},
163+
..,
164+
),
165+
..
166+
}) => hir::Constness::Const,
167+
168+
hir::Node::ImplItem(hir::ImplItem {
169+
kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..),
170+
..
171+
}) => {
172+
let parent_hir_id = tcx.hir().get_parent_node(hir_id);
173+
match tcx.hir().get(parent_hir_id) {
174+
hir::Node::Item(hir::Item {
175+
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
176+
..
177+
}) => *constness,
178+
_ => span_bug!(
179+
tcx.def_span(parent_hir_id.owner),
180+
"impl item's parent node is not an impl",
181+
),
182+
}
183+
}
184+
185+
hir::Node::Item(hir::Item {
186+
kind:
187+
hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
188+
..
189+
})
190+
| hir::Node::TraitItem(hir::TraitItem {
191+
kind:
192+
hir::TraitItemKind::Fn(
193+
hir::FnSig { header: hir::FnHeader { constness, .. }, .. },
194+
..,
195+
),
196+
..
197+
})
198+
| hir::Node::Item(hir::Item {
199+
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
200+
..
201+
}) => *constness,
202+
203+
_ => hir::Constness::NotConst,
204+
},
205+
// FIXME(consts): It's suspicious that a param-env for a foreign item
206+
// will always have NotConst param-env, though we don't typically use
207+
// that param-env for anything meaningful right now, so it's likely
208+
// not an issue.
209+
None => hir::Constness::NotConst,
210+
};
211+
140212
let unnormalized_env = ty::ParamEnv::new(
141213
tcx.intern_predicates(&predicates),
142214
traits::Reveal::UserFacing,
143-
tcx.constness(def_id),
215+
constness,
144216
);
145217

146218
let body_id =

src/test/ui/rfc-2632-const-trait-impl/issue-102985.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ struct Bug {
44
inner: [(); match || 1 {
55
n => n(),
66
//~^ ERROR the trait bound
7-
//~| ERROR cannot call non-const fn `Bug::inner::{constant#0}::{closure#0}` in constants
7+
//~| ERROR the trait bound
8+
//~| ERROR cannot call non-const closure in constants
89
}],
910
}
1011

src/test/ui/rfc-2632-const-trait-impl/issue-102985.stderr

+17-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,30 @@ LL | n => n(),
1212
| ^^^
1313
= note: wrap the `[closure@$DIR/issue-102985.rs:4:23: 4:25]` in a closure with no arguments: `|| { /* code */ }`
1414

15-
error[E0015]: cannot call non-const fn `Bug::inner::{constant#0}::{closure#0}` in constants
15+
error[E0277]: the trait bound `[closure@$DIR/issue-102985.rs:4:23: 4:25]: ~const Fn<()>` is not satisfied
16+
--> $DIR/issue-102985.rs:5:14
17+
|
18+
LL | n => n(),
19+
| ^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-102985.rs:4:23: 4:25]`
20+
|
21+
= help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-102985.rs:4:23: 4:25]`
22+
note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-102985.rs:4:23: 4:25]`, but that implementation is not `const`
23+
--> $DIR/issue-102985.rs:5:14
24+
|
25+
LL | n => n(),
26+
| ^^^
27+
= note: wrap the `[closure@$DIR/issue-102985.rs:4:23: 4:25]` in a closure with no arguments: `|| { /* code */ }`
28+
29+
error[E0015]: cannot call non-const closure in constants
1630
--> $DIR/issue-102985.rs:5:14
1731
|
1832
LL | n => n(),
1933
| ^^^
2034
|
35+
= note: closures need an RFC before allowed to be called in constants
2136
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
2237

23-
error: aborting due to 2 previous errors
38+
error: aborting due to 3 previous errors
2439

2540
Some errors have detailed explanations: E0015, E0277.
2641
For more information about an error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)