-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use only ty::Unevaluated<'tcx, ()> in type system #98588
Conversation
let val = | ||
self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal)?; | ||
debug!(?val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer if we wouldn't sprinkle debug
all over the codebase. That makes it super hard to debug the things I want to look into because all information drowns in noise.
At least this should be made trace
-- we only want to see this when we are at maximal verbosity level.
@@ -632,7 +635,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |||
} | |||
ty::ConstKind::Unevaluated(uv) => { | |||
let instance = self.resolve(uv.def, uv.substs)?; | |||
Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) | |||
Ok(self.eval_to_allocation(GlobalId { instance, promoted: None })?.into()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this make sense? It might be a promoted after all...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also can't this call uneval_to_op
now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function should be replaced with a function fn ty_const_to_value
instead of going to an Operand
in one go. I think we should require the caller to normalize unevaluated type system constants and we just always return TooGeneric
for ty::Unevaluated
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why we would want to do that? It's doesn't make sense to me why we should first create a ConstValue
when we only only want an Operand
(we would call eval_to_allocation
for creating the ConstValue
anyway).
@@ -645,6 +648,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |||
} | |||
} | |||
|
|||
/// Tries to evaluate an unevaluated constant from the MIR (and not the type-system). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this comment. The type of the argument is ty::Unevaluated
, that sounds like a type system thing to me?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we use ty::Unevaluated
for both type system constants, in which case promoted is ()
and unevaluated mir constants, in which case promoted is Option<Promoted>
.
It is true that this means that ty
isn't really the right module for this but idk where else to put it 😆
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we want to instead represent ConstantKind::Unevaluated
completely without ty::Unevaluated
but instead inline the fields 🤔
any shared eval code should then again take def_id, substs, promoted
separately. This also avoids the use of ty::X
for stuff only used in the mir. not 100% sure what's the best design here.
ConstantKind::Ty(ct) => match ct.kind() { | ||
ty::ConstKind::Unevaluated(uv) => Some(uv), | ||
ty::ConstKind::Unevaluated(uv) => Some(uv.expand()), | ||
_ => None, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can never be an inline const, can just return None
there.
please change this match to be exhaustive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing this causes the test in src/test/ui/inline-const/const-expr-lifetime-err.rs
to compile successfully
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm we should lower inline consts to mir constants, not ty constants 🤔 that's a bug during inline const lowering then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still relevant
mir::ConstantKind::Ty(ct) => ct, | ||
let uv = match ct { | ||
mir::ConstantKind::Ty(ct) => match ct.kind() { | ||
ty::ConstKind::Unevaluated(uv) => uv.expand(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again only ConstKind::Value
should be possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we can still have ConstKind::Unevaluated
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that seems wrong? the constant should be evaluated in monomorphize
🤔
maybe we should return an Err
here if this fails to evaluate
rust/compiler/rustc_trait_selection/src/traits/query/normalize.rs
Lines 327 to 328 in 4045ce6
let constant = constant.try_super_fold_with(self)?; | |
Ok(constant.eval(self.infcx.tcx, self.param_env)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also not clear to me why we would want to error here if we can't evaluate yet, this is called all the time during typecheck, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, the normalize query isn't used during typeck, it's only used afterwards.
i guess it's fine to keep this for now 🤷 will be easier to fix this once your pr has landed
@@ -632,7 +635,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |||
} | |||
ty::ConstKind::Unevaluated(uv) => { | |||
let instance = self.resolve(uv.def, uv.substs)?; | |||
Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) | |||
Ok(self.eval_to_allocation(GlobalId { instance, promoted: None })?.into()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function should be replaced with a function fn ty_const_to_value
instead of going to an Operand
in one go. I think we should require the caller to normalize unevaluated type system constants and we just always return TooGeneric
for ty::Unevaluated
here.
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) | ||
if matches!( | ||
self.tcx.def_kind(def.did), | ||
DefKind::AnonConst | DefKind::InlineConst |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it can be InlineConst
? that shouldn't be the case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still relevant
mir::ConstantKind::Val(_, _) => constant.try_super_fold_with(self)?, | ||
mir::ConstantKind::Val(_, _) | mir::ConstantKind::Unevaluated(..) => { | ||
constant.try_super_fold_with(self)? | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this try_fold_mir_const
can now stop with the weird ConstantKind::Ty
. The default impl of that method should now be good enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't understand what you mean here, we def do need try_fold_mir_const
here afaict, since this is where we convert valtrees to constvals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should do that conversion lazily. keep the mir constant as ConstantKind::Ty(ConstKind::Value(..))
until we actually need it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still relevant
☔ The latest upstream changes (presumably #98669) made this pull request unmergeable. Please resolve the merge conflicts. |
2fb9d38
to
46d1e13
Compare
Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt Some changes occurred in const_evaluatable.rs cc @lcnr |
Still getting errors in the tests when implementing some of your suggestions, @lcnr. Trying to find which changes are responsible for the failure, but since running the test set is slow on my machine, I'll use CI. |
This comment has been minimized.
This comment has been minimized.
46d1e13
to
8cf507b
Compare
This comment has been minimized.
This comment has been minimized.
What is wrong in the commit that removes |
bb2451e
to
68369fd
Compare
This comment has been minimized.
This comment has been minimized.
6e40c69
to
1e04998
Compare
This comment has been minimized.
This comment has been minimized.
not at all imo 😁 what visitor would want to only look at |
I mean that's true, but what should the default impl for I don't like it at all that these super methods in the mir visitor aren't required in the impl, you can super easily shoot yourself in the foot as I'm doing right now. So if we don't have |
Queued 1a5b8c954e6c7b563df9c4b135bab9d8ffda9003 with parent 22f6aec, future comparison URL. |
Finished benchmarking commit (1a5b8c954e6c7b563df9c4b135bab9d8ffda9003): comparison URL. Overall result: ❌✅ regressions and improvements - no action neededBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Footnotes |
looking good 👍 @bors r+ rollup=never p=10 somewhat bitrotty |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
☀️ Test successful - checks-actions |
Finished benchmarking commit (c524c7d): comparison URL. Overall result: ❌✅ regressions and improvements - no action needed@rustbot label: -perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Footnotes |
Use only ty::Unevaluated<'tcx, ()> in type system r? `@lcnr`
// NOTE: We evaluate to a `ValTree` here as a check to ensure | ||
// we're working with valid constants, even though we never need it. | ||
let instance = self.resolve(uv.def, uv.substs)?; | ||
Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) | ||
let cid = GlobalId { instance, promoted: None }; | ||
let _valtree = self | ||
.tcx | ||
.eval_to_valtree(self.param_env.and(cid))? | ||
.unwrap_or_else(|| bug!("unable to create ValTree for {:?}", uv)); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a strange check. Why would CTFE care whether the constant is a valid valtree? What if uv
has a type that does not even allow valtree construction, like a raw pointer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this is specifically for mir::ConstantKind::Ty
, which I guess must always be valtree-constructible.
But then IMO it would make most sense to have a function that evaluates a ty::Const
to a Valtree
, and always go through that. Doesn't that exist as a query or so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But then IMO it would make most sense to have a function that evaluates a ty::Const to a Valtree, and always go through that.
I will do that in #104317
r? @lcnr