Rollup merge of #102830 - compiler-errors:constness-parity, r=fee1-dead
Unify `tcx.constness` query and param env constness checks The checks that we do in the `constness` query seem inconsistent with the checks that we do to determine if an item's param-env is const, so I merged them into the `constness` query and call that from the `param_env` query. I'm not sure if this totally makes sense -- is there a case where `tcx.param_env()` would return a const param-env for an item whose `tcx.constness()` is `Constness::NotConst`? Because if not, it seems a bit dangerous that these two differ. Luckily, not many places actually use `tcx.constness()`, and the checks in `tcx.param_env()` seem stricter than the checks in `tcx.constness()` (at least for the types of items we type-check). Also, due to the way that `tcx.param_env()` is implemented, it _never_ used to return a const param-env for a item coming from a different crate, which also seems dangerous (though also probably not weaponizable currently, because we seldom actually compute the param-env for a non-local item).
This commit is contained in:
commit
c763ebc72f
3 changed files with 98 additions and 99 deletions
|
@ -25,12 +25,10 @@ pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
||||||
/// report whether said intrinsic has a `rustc_const_{un,}stable` attribute. Otherwise, return
|
/// report whether said intrinsic has a `rustc_const_{un,}stable` attribute. Otherwise, return
|
||||||
/// `Constness::NotConst`.
|
/// `Constness::NotConst`.
|
||||||
fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
|
fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
|
||||||
let def_id = def_id.expect_local();
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||||
let node = tcx.hir().get_by_def_id(def_id);
|
match tcx.hir().get(hir_id) {
|
||||||
|
|
||||||
match node {
|
|
||||||
hir::Node::Ctor(_) => hir::Constness::Const,
|
hir::Node::Ctor(_) => hir::Constness::Const,
|
||||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
|
|
||||||
hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
|
hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
|
||||||
// Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
|
// Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
|
||||||
// foreign items cannot be evaluated at compile-time.
|
// foreign items cannot be evaluated at compile-time.
|
||||||
|
@ -41,20 +39,62 @@ fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
|
||||||
};
|
};
|
||||||
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
|
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
|
||||||
}
|
}
|
||||||
_ => {
|
|
||||||
if let Some(fn_kind) = node.fn_kind() {
|
|
||||||
if fn_kind.constness() == hir::Constness::Const {
|
|
||||||
return hir::Constness::Const;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the function itself is not annotated with `const`, it may still be a `const fn`
|
hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. })
|
||||||
// if it resides in a const trait impl.
|
if tcx.is_const_default_method(def_id) =>
|
||||||
let is_const = is_parent_const_impl_raw(tcx, def_id);
|
{
|
||||||
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
|
hir::Constness::Const
|
||||||
} else {
|
}
|
||||||
hir::Constness::NotConst
|
|
||||||
|
hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. })
|
||||||
|
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. })
|
||||||
|
| hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. })
|
||||||
|
| hir::Node::AnonConst(_)
|
||||||
|
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
|
||||||
|
| hir::Node::ImplItem(hir::ImplItem {
|
||||||
|
kind:
|
||||||
|
hir::ImplItemKind::Fn(
|
||||||
|
hir::FnSig {
|
||||||
|
header: hir::FnHeader { constness: hir::Constness::Const, .. },
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..,
|
||||||
|
),
|
||||||
|
..
|
||||||
|
}) => hir::Constness::Const,
|
||||||
|
|
||||||
|
hir::Node::ImplItem(hir::ImplItem {
|
||||||
|
kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..),
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
let parent_hir_id = tcx.hir().get_parent_node(hir_id);
|
||||||
|
match tcx.hir().get(parent_hir_id) {
|
||||||
|
hir::Node::Item(hir::Item {
|
||||||
|
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
|
||||||
|
..
|
||||||
|
}) => *constness,
|
||||||
|
_ => span_bug!(
|
||||||
|
tcx.def_span(parent_hir_id.owner),
|
||||||
|
"impl item's parent node is not an impl",
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hir::Node::Item(hir::Item {
|
||||||
|
kind: hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
|
||||||
|
..
|
||||||
|
})
|
||||||
|
| hir::Node::TraitItem(hir::TraitItem {
|
||||||
|
kind:
|
||||||
|
hir::TraitItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
|
||||||
|
..
|
||||||
|
})
|
||||||
|
| hir::Node::Item(hir::Item {
|
||||||
|
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
|
||||||
|
..
|
||||||
|
}) => *constness,
|
||||||
|
|
||||||
|
_ => hir::Constness::NotConst,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1059,6 +1059,43 @@ fn should_encode_const(def_kind: DefKind) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn should_encode_constness(def_kind: DefKind) -> bool {
|
||||||
|
match def_kind {
|
||||||
|
DefKind::Struct
|
||||||
|
| DefKind::Union
|
||||||
|
| DefKind::Enum
|
||||||
|
| DefKind::Trait
|
||||||
|
| DefKind::AssocTy
|
||||||
|
| DefKind::Fn
|
||||||
|
| DefKind::Const
|
||||||
|
| DefKind::Static(..)
|
||||||
|
| DefKind::Ctor(..)
|
||||||
|
| DefKind::AssocFn
|
||||||
|
| DefKind::AssocConst
|
||||||
|
| DefKind::AnonConst
|
||||||
|
| DefKind::InlineConst
|
||||||
|
| DefKind::OpaqueTy
|
||||||
|
| DefKind::ImplTraitPlaceholder
|
||||||
|
| DefKind::Impl
|
||||||
|
| DefKind::Closure
|
||||||
|
| DefKind::Generator
|
||||||
|
| DefKind::TyAlias => true,
|
||||||
|
DefKind::Variant
|
||||||
|
| DefKind::TraitAlias
|
||||||
|
| DefKind::ForeignTy
|
||||||
|
| DefKind::Field
|
||||||
|
| DefKind::TyParam
|
||||||
|
| DefKind::Mod
|
||||||
|
| DefKind::ForeignMod
|
||||||
|
| DefKind::ConstParam
|
||||||
|
| DefKind::Macro(..)
|
||||||
|
| DefKind::Use
|
||||||
|
| DefKind::LifetimeParam
|
||||||
|
| DefKind::GlobalAsm
|
||||||
|
| DefKind::ExternCrate => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn should_encode_trait_impl_trait_tys<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
|
fn should_encode_trait_impl_trait_tys<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
|
||||||
if tcx.def_kind(def_id) != DefKind::AssocFn {
|
if tcx.def_kind(def_id) != DefKind::AssocFn {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1165,6 +1202,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
record!(self.tables.trait_impl_trait_tys[def_id] <- table);
|
record!(self.tables.trait_impl_trait_tys[def_id] <- table);
|
||||||
}
|
}
|
||||||
|
if should_encode_constness(def_kind) {
|
||||||
|
self.tables.constness.set(def_id.index, tcx.constness(def_id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let inherent_impls = tcx.crate_inherent_impls(());
|
let inherent_impls = tcx.crate_inherent_impls(());
|
||||||
for (def_id, implementations) in inherent_impls.inherent_impls.iter() {
|
for (def_id, implementations) in inherent_impls.inherent_impls.iter() {
|
||||||
|
@ -1192,7 +1232,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
record!(self.tables.variant_data[def_id] <- data);
|
record!(self.tables.variant_data[def_id] <- data);
|
||||||
self.tables.constness.set(def_id.index, hir::Constness::Const);
|
|
||||||
record_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
|
record_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
|
||||||
assert!(f.did.is_local());
|
assert!(f.did.is_local());
|
||||||
f.did.index
|
f.did.index
|
||||||
|
@ -1220,7 +1259,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
record!(self.tables.variant_data[def_id] <- data);
|
record!(self.tables.variant_data[def_id] <- data);
|
||||||
self.tables.constness.set(def_id.index, hir::Constness::Const);
|
|
||||||
if variant.ctor_kind == CtorKind::Fn {
|
if variant.ctor_kind == CtorKind::Fn {
|
||||||
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
|
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
|
||||||
}
|
}
|
||||||
|
@ -1284,7 +1322,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
|
|
||||||
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
||||||
record!(self.tables.variant_data[def_id] <- data);
|
record!(self.tables.variant_data[def_id] <- data);
|
||||||
self.tables.constness.set(def_id.index, hir::Constness::Const);
|
|
||||||
if variant.ctor_kind == CtorKind::Fn {
|
if variant.ctor_kind == CtorKind::Fn {
|
||||||
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
|
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
|
||||||
}
|
}
|
||||||
|
@ -1320,7 +1357,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.tables.asyncness.set(def_id.index, m_sig.header.asyncness);
|
self.tables.asyncness.set(def_id.index, m_sig.header.asyncness);
|
||||||
self.tables.constness.set(def_id.index, hir::Constness::NotConst);
|
|
||||||
}
|
}
|
||||||
ty::AssocKind::Type => {
|
ty::AssocKind::Type => {
|
||||||
self.encode_explicit_item_bounds(def_id);
|
self.encode_explicit_item_bounds(def_id);
|
||||||
|
@ -1345,13 +1381,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
|
let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
|
||||||
self.tables.asyncness.set(def_id.index, sig.header.asyncness);
|
self.tables.asyncness.set(def_id.index, sig.header.asyncness);
|
||||||
record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
|
record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
|
||||||
// Can be inside `impl const Trait`, so using sig.header.constness is not reliable
|
|
||||||
let constness = if self.tcx.is_const_fn_raw(def_id) {
|
|
||||||
hir::Constness::Const
|
|
||||||
} else {
|
|
||||||
hir::Constness::NotConst
|
|
||||||
};
|
|
||||||
self.tables.constness.set(def_id.index, constness);
|
|
||||||
}
|
}
|
||||||
ty::AssocKind::Const | ty::AssocKind::Type => {}
|
ty::AssocKind::Const | ty::AssocKind::Type => {}
|
||||||
}
|
}
|
||||||
|
@ -1474,7 +1503,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
hir::ItemKind::Fn(ref sig, .., body) => {
|
hir::ItemKind::Fn(ref sig, .., body) => {
|
||||||
self.tables.asyncness.set(def_id.index, sig.header.asyncness);
|
self.tables.asyncness.set(def_id.index, sig.header.asyncness);
|
||||||
record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
|
record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
|
||||||
self.tables.constness.set(def_id.index, sig.header.constness);
|
|
||||||
}
|
}
|
||||||
hir::ItemKind::Macro(ref macro_def, _) => {
|
hir::ItemKind::Macro(ref macro_def, _) => {
|
||||||
if macro_def.macro_rules {
|
if macro_def.macro_rules {
|
||||||
|
@ -1495,7 +1523,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
hir::ItemKind::Struct(ref struct_def, _) => {
|
hir::ItemKind::Struct(ref struct_def, _) => {
|
||||||
let adt_def = self.tcx.adt_def(def_id);
|
let adt_def = self.tcx.adt_def(def_id);
|
||||||
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
||||||
self.tables.constness.set(def_id.index, hir::Constness::Const);
|
|
||||||
|
|
||||||
// Encode def_ids for each field and method
|
// Encode def_ids for each field and method
|
||||||
// for methods, write all the stuff get_trait_method
|
// for methods, write all the stuff get_trait_method
|
||||||
|
@ -1524,9 +1551,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
|
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
|
hir::ItemKind::Impl(hir::Impl { defaultness, .. }) => {
|
||||||
self.tables.impl_defaultness.set(def_id.index, *defaultness);
|
self.tables.impl_defaultness.set(def_id.index, *defaultness);
|
||||||
self.tables.constness.set(def_id.index, *constness);
|
|
||||||
|
|
||||||
let trait_ref = self.tcx.impl_trait_ref(def_id);
|
let trait_ref = self.tcx.impl_trait_ref(def_id);
|
||||||
if let Some(trait_ref) = trait_ref {
|
if let Some(trait_ref) = trait_ref {
|
||||||
|
|
|
@ -137,77 +137,10 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
let local_did = def_id.as_local();
|
let local_did = def_id.as_local();
|
||||||
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
|
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
|
||||||
|
|
||||||
let constness = match hir_id {
|
|
||||||
Some(hir_id) => match tcx.hir().get(hir_id) {
|
|
||||||
hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. })
|
|
||||||
if tcx.is_const_default_method(def_id) =>
|
|
||||||
{
|
|
||||||
hir::Constness::Const
|
|
||||||
}
|
|
||||||
|
|
||||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. })
|
|
||||||
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. })
|
|
||||||
| hir::Node::TraitItem(hir::TraitItem {
|
|
||||||
kind: hir::TraitItemKind::Const(..), ..
|
|
||||||
})
|
|
||||||
| hir::Node::AnonConst(_)
|
|
||||||
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
|
|
||||||
| hir::Node::ImplItem(hir::ImplItem {
|
|
||||||
kind:
|
|
||||||
hir::ImplItemKind::Fn(
|
|
||||||
hir::FnSig {
|
|
||||||
header: hir::FnHeader { constness: hir::Constness::Const, .. },
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..,
|
|
||||||
),
|
|
||||||
..
|
|
||||||
}) => hir::Constness::Const,
|
|
||||||
|
|
||||||
hir::Node::ImplItem(hir::ImplItem {
|
|
||||||
kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..),
|
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
let parent_hir_id = tcx.hir().get_parent_node(hir_id);
|
|
||||||
match tcx.hir().get(parent_hir_id) {
|
|
||||||
hir::Node::Item(hir::Item {
|
|
||||||
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
|
|
||||||
..
|
|
||||||
}) => *constness,
|
|
||||||
_ => span_bug!(
|
|
||||||
tcx.def_span(parent_hir_id.owner),
|
|
||||||
"impl item's parent node is not an impl",
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hir::Node::Item(hir::Item {
|
|
||||||
kind:
|
|
||||||
hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
|
|
||||||
..
|
|
||||||
})
|
|
||||||
| hir::Node::TraitItem(hir::TraitItem {
|
|
||||||
kind:
|
|
||||||
hir::TraitItemKind::Fn(
|
|
||||||
hir::FnSig { header: hir::FnHeader { constness, .. }, .. },
|
|
||||||
..,
|
|
||||||
),
|
|
||||||
..
|
|
||||||
})
|
|
||||||
| hir::Node::Item(hir::Item {
|
|
||||||
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
|
|
||||||
..
|
|
||||||
}) => *constness,
|
|
||||||
|
|
||||||
_ => hir::Constness::NotConst,
|
|
||||||
},
|
|
||||||
None => hir::Constness::NotConst,
|
|
||||||
};
|
|
||||||
|
|
||||||
let unnormalized_env = ty::ParamEnv::new(
|
let unnormalized_env = ty::ParamEnv::new(
|
||||||
tcx.intern_predicates(&predicates),
|
tcx.intern_predicates(&predicates),
|
||||||
traits::Reveal::UserFacing,
|
traits::Reveal::UserFacing,
|
||||||
constness,
|
tcx.constness(def_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
let body_id =
|
let body_id =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue