Uh oh!
There was an error while loading. Please reload this page.
Fix ICE involving calling Instance.ty during const evaluation - #67800
Conversation
rust-highfive
commented
Jan 2, 2020
r? @varkor (rust_highfive has picked a reviewer for you, use r? to override) |
Instance.ty durign const evaluationInstance.ty during const evaluation51b9fa5 to
1e08f9eCompare
This comment has been minimized.
This comment has been minimized.
1e08f9e to
7e86561Compare
This comment has been minimized.
This comment has been minimized.
Uh oh!
There was an error while loading. Please reload this page.
rust-highfive
commented
Jan 3, 2020
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
Uh oh!
There was an error while loading. Please reload this page.
wesleywiser
commented
Jan 3, 2020
@bors try @rust-timer queue |
rust-timer
commented
Jan 3, 2020
Awaiting bors try build completion |
bors
commented
Jan 3, 2020
⌛ Trying commit b9dcd9814b4f8b37cfe0b0136cc10ed7797d30eb with merge c8783d8cf524e2ceaad6d300e62e58e68a6d22cf... |
bors
commented
Jan 3, 2020
☀️ Try build successful - checks-azure |
rust-timer
commented
Jan 3, 2020
Queued c8783d8cf524e2ceaad6d300e62e58e68a6d22cf with parent 4877e16, future comparison URL. |
Aaron1011
commented
Jan 3, 2020
For some reason, the bot didn't comment saying that benchmarking completed. It looks like this change had no perf impact above the noise floor, as I had hoped. |
wesleywiser
left a comment
There was a problem hiding this comment.
Code and perf look good to me and the change seems reasonable enough but I don't think I know enough about the resolver to sign off on this myself. Perhaps @oli-obk or someone else could take a look as well?
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Fixesrust-lang#67639 `Instance.ty` assumes that we are in a fully monomorphic context (e.g. codegen), and can therefore use an empty `ParamEnv` when performing normalization. Howver, the MIR constant evaluator code ends up calling `Instance.ty` as a result of us attemptign to 'speculatively' const-evaluate generic functions during const propagation. As a result, we may end up with projections involving type parameters (e.g. <T as MyTrait>::Bar>) in the type we are trying to normalize. Normalization expects us to have proper predicates in the `ParamEnv` for such projections, and will ICE if we don't. This commit adds a new method `Instance.ty_env`, which takes a `ParamEnv` for use during normalization. The MIR const-evaluator code is changed to use this method, passing in the proper `ParamEnv` for the context at hand.
Co-Authored-By: Wesley Wiser <wwiser@gmail.com>
b9dcd98 to
33caf0bCompareAaron1011
commented
Jan 5, 2020
@oli-obk: Updated |
Uh oh!
There was an error while loading. Please reload this page.
| // adjustments `FnAbi::of_instance` might be performing. | ||
| fn fn_sig_for_fn_abi(&self, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> { | ||
| let ty = self.ty(tcx); | ||
| let ty = self.monomorphic_ty(tcx); |
There was a problem hiding this comment.
It's not obvious to me that this is correct. Ca you go up the call chain and see if there are any noncodegen uses?
There was a problem hiding this comment.
The only caller is FnAbi:of_instance, which is only called from codegen.
There was a problem hiding this comment.
We need to stop assuming that codegen = monomorphic.
oli-obk
commented
Jan 5, 2020
bors
commented
Jan 5, 2020
📌 Commit 336b902 has been approved by |
… r=oli-obk Fix ICE involving calling `Instance.ty` during const evaluation Fixesrust-lang#67639 `Instance.ty` assumes that we are in a fully monomorphic context (e.g. codegen), and can therefore use an empty `ParamEnv` when performing normalization. Howver, the MIR constant evaluator code ends up calling `Instance.ty` as a result of us attemptign to 'speculatively' const-evaluate generic functions during const propagation. As a result, we may end up with projections involving type parameters (e.g. <T as MyTrait>::Bar>) in the type we are trying to normalize. Normalization expects us to have proper predicates in the `ParamEnv` for such projections, and will ICE if we don't. This commit adds a new method `Instance.ty_env`, which takes a `ParamEnv` for use during normalization. The MIR const-evaluator code is changed to use this method, passing in the proper `ParamEnv` for the context at hand.
Rollup of 6 pull requests Successful merges: - #67800 (Fix ICE involving calling `Instance.ty` during const evaluation) - #67873 (change remove to have a PartialEq bound) - #67897 (Use `as_deref()` to replace `as_ref().map(...)`) - #67906 (Silence `TooGeneric` error) - #67912 (macros: typo fix) - #67915 (Use Self instead of $type) Failed merges: r? @ghost
| pub fn ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { | ||
| /// Returns the `Ty` corresponding to this `Instance`, | ||
| /// with generic substitutions applied and lifetimes erased. | ||
| /// | ||
| /// This method can only be called when the 'substs' for this Instance | ||
| /// are fully monomorphic (no `ty::Param`'s are present). | ||
| /// This is usually the case (e.g. during codegen). | ||
| /// However, during constant evaluation, we may want | ||
| /// to try to resolve a `Instance` using generic parameters | ||
| /// (e.g. when we are attempting to to do const-propagation). | ||
| /// In this case, `Instance.ty_env` should be used to provide | ||
| /// the `ParamEnv` for our generic context. | ||
| pub fn monomorphic_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { | ||
| let ty = tcx.type_of(self.def.def_id()); | ||
| // There shouldn't be any params - if there are, then | ||
| // Instance.ty_env should have been used to provide the proper | ||
| // ParamEnv | ||
| if self.substs.has_param_types() { | ||
| bug!("Instance.ty called for type {:?} with params in substs: {:?}", ty, self.substs); | ||
| } | ||
| tcx.subst_and_normalize_erasing_regions(self.substs, ty::ParamEnv::reveal_all(), &ty) | ||
| } | ||
| /// Like `Instance.ty`, but allows a `ParamEnv` to be specified for use during | ||
| /// normalization. This method is only really useful during constant evaluation, | ||
| /// where we are dealing with potentially generic types. | ||
| pub fn ty_env(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> { | ||
| let ty = tcx.type_of(self.def.def_id()); | ||
| tcx.subst_and_normalize_erasing_regions(self.substs, param_env, &ty) | ||
| } |
There was a problem hiding this comment.
I would keep a single ty method and force callers to pass in ty::ParamEnv::reveal_all() (eventually all of codegen should have to keep track of a ParamEnv anyway, because of @davidtwco's work on partial monomorphization).
Fixes#67639
Instance.tyassumes that we are in a fully monomorphic context (e.g.codegen), and can therefore use an empty
ParamEnvwhen performingnormalization. Howver, the MIR constant evaluator code ends up calling
Instance.tyas a result of us attemptign to 'speculatively'const-evaluate generic functions during const propagation.
As a result,
we may end up with projections involving type parameters
(e.g. ::Bar>) in the type we are trying to normalize.
Normalization expects us to have proper predicates in the
ParamEnvforsuch projections, and will ICE if we don't.
This commit adds a new method
Instance.ty_env, which takes aParamEnvfor use during normalization. The MIR const-evaluator code ischanged to use this method, passing in the proper
ParamEnvfor thecontext at hand.