Fix ICE in normalization during closure capture analysis

This commit is contained in:
delta17920 2025-12-09 09:36:58 +00:00
parent 0ac9e59d8f
commit ac448c987d
3 changed files with 101 additions and 2 deletions

View file

@ -1394,8 +1394,10 @@ impl<'tcx> Ty<'tcx> {
// This doesn't depend on regions, so try to minimize distinct
// query keys used.
let erased = tcx.normalize_erasing_regions(typing_env, query_ty);
tcx.has_significant_drop_raw(typing_env.as_query_input(erased))
// FIX: Use try_normalize to avoid crashing. If it fails, return true.
tcx.try_normalize_erasing_regions(typing_env, query_ty)
.map(|erased| tcx.has_significant_drop_raw(typing_env.as_query_input(erased)))
.unwrap_or(true)
}
}
}

View file

@ -0,0 +1,17 @@
//@ edition: 2015..2021
#![warn(rust_2021_incompatible_closure_captures)]
trait Owner { type Ty<T: FnMut()>; }
impl Owner for () { type Ty<T: FnMut()> = T; }
pub struct Warns<T> {
_significant_drop: <() as Owner>::Ty<T>,
//~^ ERROR expected a `FnMut()` closure, found `T`
field: String,
}
pub fn test<T>(w: Warns<T>) {
//~^ ERROR expected a `FnMut()` closure, found `T`
_ = || w.field
//~^ ERROR expected a `FnMut()` closure, found `T`
//~| ERROR expected a `FnMut()` closure, found `T`
//~| WARN: changes to closure capture in Rust 2021 will affect drop order
}
fn main() {}

View file

@ -0,0 +1,80 @@
error[E0277]: expected a `FnMut()` closure, found `T`
--> $DIR/normalization-ice-issue-149746.rs:6:24
|
LL | _significant_drop: <() as Owner>::Ty<T>,
| ^^^^^^^^^^^^^^^^^^^^ expected an `FnMut()` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Owner::Ty`
--> $DIR/normalization-ice-issue-149746.rs:3:26
|
LL | trait Owner { type Ty<T: FnMut()>; }
| ^^^^^^^ required by this bound in `Owner::Ty`
help: consider restricting type parameter `T` with trait `FnMut`
|
LL | pub struct Warns<T: FnMut()> {
| +++++++++
warning: changes to closure capture in Rust 2021 will affect drop order
--> $DIR/normalization-ice-issue-149746.rs:12:9
|
LL | _ = || w.field
| ^^ -------
| | |
| | in Rust 2018, `w` is dropped here, but in Rust 2021, only `w.field` will be dropped here as part of the closure
| in Rust 2018, this closure captures all of `w`, but in Rust 2021, it will only capture `w.field`
|
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/normalization-ice-issue-149746.rs:2:9
|
LL | #![warn(rust_2021_incompatible_closure_captures)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: add a dummy let to cause `w` to be fully captured
|
LL | _ = || { let _ = &w; w.field }
| +++++++++++++ +
error[E0277]: expected a `FnMut()` closure, found `T`
--> $DIR/normalization-ice-issue-149746.rs:12:9
|
LL | _ = || w.field
| ^^^^^^^^^^ expected an `FnMut()` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Owner::Ty`
--> $DIR/normalization-ice-issue-149746.rs:3:26
|
LL | trait Owner { type Ty<T: FnMut()>; }
| ^^^^^^^ required by this bound in `Owner::Ty`
error[E0277]: expected a `FnMut()` closure, found `T`
--> $DIR/normalization-ice-issue-149746.rs:10:16
|
LL | pub fn test<T>(w: Warns<T>) {
| ^ expected an `FnMut()` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Owner::Ty`
--> $DIR/normalization-ice-issue-149746.rs:3:26
|
LL | trait Owner { type Ty<T: FnMut()>; }
| ^^^^^^^ required by this bound in `Owner::Ty`
error[E0277]: expected a `FnMut()` closure, found `T`
--> $DIR/normalization-ice-issue-149746.rs:12:9
|
LL | _ = || w.field
| ^^^^^^^^^^ expected an `FnMut()` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Owner::Ty`
--> $DIR/normalization-ice-issue-149746.rs:3:26
|
LL | trait Owner { type Ty<T: FnMut()>; }
| ^^^^^^^ required by this bound in `Owner::Ty`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 4 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0277`.