traits: Allow escaping self types in ExistentialTraitRef::with_self_ty#157280
traits: Allow escaping self types in ExistentialTraitRef::with_self_ty#157280Dnreikronos wants to merge 3 commits into
Conversation
|
changes to the core type system cc @lcnr |
|
r? @mejrs rustbot has assigned @mejrs. Use Why was this reviewer chosen?The reviewer was selected based on:
|
WF-checking walks through higher-ranked binders without instantiating them, so a `dyn Trait` nested inside a `for<'a>` bound reaches the `ty::Dynamic` arm of `WfPredicates::visit_ty` while still carrying escaping bound vars. Feeding that type into `ExistentialTraitRef::with_self_ty` violated its no-escaping-self precondition and tripped the assertion that guards it. The trait ref built there is only used to read off `ConstArgHasType` clauses, which constrain the trait's own const arguments and never mention the `Self` type. Substitute a fresh placeholder self type when the real one escapes: the assertion holds and the const-argument check is still performed. Re-enable the `with_self_ty` debug assertion now that its precondition is upheld.
One test covers the original ICE (a `dyn Trait` nested in a `for<'a>` bound, distilled from itertools). The other locks in that a const argument on such a nested `dyn` is still type-checked, so the placeholder-self-type fix cannot silently regress into dropping the `ConstArgHasType` check.
87f6783 to
0676d4a
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
I'm not confident reviewing this. r? @fmease perhaps? |
|
Oh it's not about what and how you implemented this, I'm very unfamiliar with this part of the compiler so I'm ill-suited to review PRs touching it. |
WF-checking can reach ExistentialTraitRef::with_self_ty with a dyn principal that still carries escaping bound vars, e.g. a dyn nested in a for<'a> bound, which tripped the debug assertion forbidding escaping self types and ICEd when compiling itertools. Building such a trait ref is fine: escaping bound vars are caught where it is actually used. Remove the assertion rather than working around it, which lets the WF visitor pass the type through unchanged and drops the placeholder-self-type detour.
This comment was marked as outdated.
This comment was marked as outdated.
|
@bors delegate+ r=me after updating the PR name |
|
✌️ @Dnreikronos, you can now approve this pull request! If @lcnr told you to " |
|
just reenamed the PR. @bors r=lcnr |
…escaping_bound_vars_assert, r=lcnr traits: Allow escaping self types in ExistentialTraitRef::with_self_ty Fixes rust-lang#157122 WF-checking recurses through higher-ranked binders without instantiating them, so a `dyn Trait` nested inside a `for<'a>` binder reaches the `ty::Dynamic` arm of `WfPredicates::visit_ty` while still carrying escaping bound vars. Building the principal trait ref there via `ExistentialTraitRef::with_self_ty` hands that escaping self type to a `debug_assert!(!self_ty.has_escaping_bound_vars())`, which ICEs once the assertion is enabled. The assert was accidentally disabled in 2018 refactor rust-lang#53816, and the `// FIXME(rust-lang#157122)` left in its place asks whether to remove it or fix the fallout. An escaping bound var is expected for trait objects, and we already catch trait refs with escaping bound vars at the places that actually use them — so creating one here is fine. Rather than work around the assert in WF, this removes the assert and its stale FIXME from `with_self_ty`. Two regression tests pin the behavior: - `wf-dyn-in-hrtb-bound-issue-157122.rs` reproduces the original ICE (`dyn` nested in an HRTB bound). - `wf-dyn-in-hrtb-bound-const-mismatch.rs` checks that the `ConstArgHasType` obligation this arm reads off still fires, so an ill-typed const argument on such a `dyn` keeps erroring instead of compiling clean.
…uwer Rollup of 14 pull requests Successful merges: - #157280 (traits: Allow escaping self types in ExistentialTraitRef::with_self_ty) - #157282 (Fix post-monomorphization error note race in the parallel frontend) - #157352 (Make the retained dep graph deterministic under the parallel frontend) - #157601 (Emit error for unused target expression in glob and list delegations) - #157626 (Autogenerate unstable compiler flag stubs for unstable-book) - #157647 (Start using comptime for reflection intrinsics and their wrapper functions) - #157013 (Ensure inferred let pattern types are well-formed) - #157288 (platform support: add SNaN erratum to MIPS targets) - #157355 (Add `or_try_*` variants for `HashMap` and `BTreeMap` Entry APIs) - #157577 (Fix parser error recovery treating 'dyn' as a strict keyword in Rust …) - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N)) - #157691 (Move symbol hiding code to a new file) - #157700 (Rename `errors.rs` file to `diagnostics.rs` (5/N)) - #157703 (Fix doc link to Instant sub in saturating caveat) Failed merges: - #157699 (Arg splat experiment - hir FnDecl impl)
…uwer Rollup of 14 pull requests Successful merges: - #157280 (traits: Allow escaping self types in ExistentialTraitRef::with_self_ty) - #157282 (Fix post-monomorphization error note race in the parallel frontend) - #157352 (Make the retained dep graph deterministic under the parallel frontend) - #157601 (Emit error for unused target expression in glob and list delegations) - #157626 (Autogenerate unstable compiler flag stubs for unstable-book) - #157647 (Start using comptime for reflection intrinsics and their wrapper functions) - #157013 (Ensure inferred let pattern types are well-formed) - #157288 (platform support: add SNaN erratum to MIPS targets) - #157355 (Add `or_try_*` variants for `HashMap` and `BTreeMap` Entry APIs) - #157577 (Fix parser error recovery treating 'dyn' as a strict keyword in Rust …) - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N)) - #157691 (Move symbol hiding code to a new file) - #157700 (Rename `errors.rs` file to `diagnostics.rs` (5/N)) - #157703 (Fix doc link to Instant sub in saturating caveat) Failed merges: - #157699 (Arg splat experiment - hir FnDecl impl)
…escaping_bound_vars_assert, r=lcnr traits: Allow escaping self types in ExistentialTraitRef::with_self_ty Fixes rust-lang#157122 WF-checking recurses through higher-ranked binders without instantiating them, so a `dyn Trait` nested inside a `for<'a>` binder reaches the `ty::Dynamic` arm of `WfPredicates::visit_ty` while still carrying escaping bound vars. Building the principal trait ref there via `ExistentialTraitRef::with_self_ty` hands that escaping self type to a `debug_assert!(!self_ty.has_escaping_bound_vars())`, which ICEs once the assertion is enabled. The assert was accidentally disabled in 2018 refactor rust-lang#53816, and the `// FIXME(rust-lang#157122)` left in its place asks whether to remove it or fix the fallout. An escaping bound var is expected for trait objects, and we already catch trait refs with escaping bound vars at the places that actually use them — so creating one here is fine. Rather than work around the assert in WF, this removes the assert and its stale FIXME from `with_self_ty`. Two regression tests pin the behavior: - `wf-dyn-in-hrtb-bound-issue-157122.rs` reproduces the original ICE (`dyn` nested in an HRTB bound). - `wf-dyn-in-hrtb-bound-const-mismatch.rs` checks that the `ConstArgHasType` obligation this arm reads off still fires, so an ill-typed const argument on such a `dyn` keeps erroring instead of compiling clean.
…escaping_bound_vars_assert, r=lcnr traits: Allow escaping self types in ExistentialTraitRef::with_self_ty Fixes rust-lang#157122 WF-checking recurses through higher-ranked binders without instantiating them, so a `dyn Trait` nested inside a `for<'a>` binder reaches the `ty::Dynamic` arm of `WfPredicates::visit_ty` while still carrying escaping bound vars. Building the principal trait ref there via `ExistentialTraitRef::with_self_ty` hands that escaping self type to a `debug_assert!(!self_ty.has_escaping_bound_vars())`, which ICEs once the assertion is enabled. The assert was accidentally disabled in 2018 refactor rust-lang#53816, and the `// FIXME(rust-lang#157122)` left in its place asks whether to remove it or fix the fallout. An escaping bound var is expected for trait objects, and we already catch trait refs with escaping bound vars at the places that actually use them — so creating one here is fine. Rather than work around the assert in WF, this removes the assert and its stale FIXME from `with_self_ty`. Two regression tests pin the behavior: - `wf-dyn-in-hrtb-bound-issue-157122.rs` reproduces the original ICE (`dyn` nested in an HRTB bound). - `wf-dyn-in-hrtb-bound-const-mismatch.rs` checks that the `ConstArgHasType` obligation this arm reads off still fires, so an ill-typed const argument on such a `dyn` keeps erroring instead of compiling clean.
Rollup of 23 pull requests Successful merges: - #157280 (traits: Allow escaping self types in ExistentialTraitRef::with_self_ty) - #157282 (Fix post-monomorphization error note race in the parallel frontend) - #157352 (Make the retained dep graph deterministic under the parallel frontend) - #157601 (Emit error for unused target expression in glob and list delegations) - #157611 (Update `browser-ui-test` version to `0.24.0`) - #157620 (Add a strategy FnMut to inject behavior into the flush cycle) - #157645 (Windows TLS - Only register the `atexit` hook when `cleanup` can be unloaded) - #157647 (Start using comptime for reflection intrinsics and their wrapper functions) - #157719 (resolve: Partially revert "Remove a special case for dummy imports") - #156497 (fix-155516: Don't suggest wrong unwrap expect) - #156583 (Support defaults for static EIIs) - #157013 (Ensure inferred let pattern types are well-formed) - #157230 (borrowck: avoid ICE describing fields on generic params) - #157288 (platform support: add SNaN erratum to MIPS targets) - #157350 (compiletest: ignore SVG `y` offset in by-lines comparison) - #157355 (Add `or_try_*` variants for `HashMap` and `BTreeMap` Entry APIs) - #157384 (Add `#[rustc_dump_generics]` attribute) - #157577 (Fix parser error recovery treating 'dyn' as a strict keyword in Rust 2015 when used in `dyn + dyn`) - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N)) - #157691 (Move symbol hiding code to a new file) - #157697 (Add more tests that exercise the well-formedness checking of lazy type aliases) - #157700 (Rename `errors.rs` file to `diagnostics.rs` (5/N)) - #157703 (Fix doc link to Instant sub in saturating caveat) Failed merges: - #157699 (Arg splat experiment - hir FnDecl impl)
Fixes #157122
WF-checking recurses through higher-ranked binders without instantiating them, so a
dyn Traitnested inside afor<'a>binder reaches thety::Dynamicarm ofWfPredicates::visit_tywhile still carrying escaping bound vars. Building the principal trait ref there viaExistentialTraitRef::with_self_tyhands that escaping self type to adebug_assert!(!self_ty.has_escaping_bound_vars()), which ICEs once the assertion is enabled. The assert was accidentally disabled in 2018 refactor #53816, and the// FIXME(#157122)left in its place asks whether to remove it or fix the fallout.An escaping bound var is expected for trait objects, and we already catch trait refs with escaping bound vars at the places that actually use them — so creating one here is fine. Rather than work around the assert in WF, this removes the assert and its stale FIXME from
with_self_ty.Two regression tests pin the behavior:
wf-dyn-in-hrtb-bound-issue-157122.rsreproduces the original ICE (dynnested in an HRTB bound).wf-dyn-in-hrtb-bound-const-mismatch.rschecks that theConstArgHasTypeobligation this arm reads off still fires, so an ill-typed const argument on such adynkeeps erroring instead of compiling clean.