Skip to content

Remove the empty variant of VerifyBound#152438

Open
amandasystems wants to merge 4 commits intorust-lang:mainfrom
amandasystems:remove-is-empty-verify-bound
Open

Remove the empty variant of VerifyBound#152438
amandasystems wants to merge 4 commits intorust-lang:mainfrom
amandasystems:remove-is-empty-verify-bound

Conversation

@amandasystems
Copy link
Copy Markdown
Contributor

This variant is not encountered in region inference at all. Where it is used, it is replaced with an empty any (or) bound, which is checked for as a special case with the equivalent logic where necessary. Such a bound will always fail in region inference, so this should not introduce any soundness issues.

This variant is not encountered in region inference at all. Where it is used,
it is replaced with an empty any (or) bound, which is checked for as a special
case with the equivalent logic where necessary. Such a bound will always fail
in region inference, so this should not introduce any soundness issues.
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 10, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Feb 10, 2026

r? @JonathanBrouwer

rustbot has assigned @JonathanBrouwer.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 66 candidates
  • Random selection from 14 candidates

@amandasystems
Copy link
Copy Markdown
Contributor Author

r? @BoxyUwU @lcnr

who already has this in cache.

@rustbot rustbot assigned BoxyUwU and unassigned JonathanBrouwer Feb 10, 2026
Comment thread compiler/rustc_borrowck/src/region_infer/mod.rs
Comment on lines +955 to 963
// An empty bound holds for an empty variable.
VerifyBound::AnyBound(bs) if bs.is_empty() => match min.kind() {
ty::ReVar(rid) => match var_values.values[rid] {
VarValue::ErrorValue => false,
VarValue::Empty(_) => true,
VarValue::Value(_) => false,
},
_ => false,
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems undesirable as it means we still have VerifyBound::IsEmpty, just represented differently. Why is this necessary?

Comment thread compiler/rustc_infer/src/infer/region_constraints/mod.rs Outdated
@rust-log-analyzer
Copy link
Copy Markdown
Collaborator

The job pr-check-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)

=> Removing the following docker images:
WARNING: This output is designed for human readability. For machine-readable output, please use --format.
IMAGE                                               ID             DISK USAGE   CONTENT SIZE   EXTRA
ghcr.io/dependabot/dependabot-updater-core:latest   9a6a20114926       1.18GB          310MB        
=> Removing docker images...
Deleted Images:
untagged: ghcr.io/dependabot/dependabot-updater-core:latest
deleted: sha256:9a6a20114926442eeadab0732ddd7264ecafc907389c47974b1825d779571319

Total reclaimed space: 309.7MB

********************************************************************************
---
   Compiling anyhow v1.0.100
error[E0311]: the parameter type `F` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/ascii/mod.rs:1469:5
     |
1469 | /     trace("escaped", move |input: &mut I| {
1470 | |         if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() {
1471 | |             streaming_escaped_internal(input, &mut normal, control_char, &mut escapable)
1472 | |         } else {
...    |
1475 | |     })
     | |      ^
     | |      |
     | |______the parameter type `F` must be valid for lifetime `'_`...
     |        ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/ascii/mod.rs:1469:22: 1469:42}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
     |
  45 |     parser: impl Parser<I, O, E>,
     |                  ^^^^^^^^^^^^^^^
     = help: consider adding an explicit lifetime bound `F: anon`...

error[E0311]: the parameter type `G` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/ascii/mod.rs:1469:5
     |
1469 | /     trace("escaped", move |input: &mut I| {
1470 | |         if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() {
1471 | |             streaming_escaped_internal(input, &mut normal, control_char, &mut escapable)
1472 | |         } else {
...    |
1475 | |     })
     | |      ^
     | |      |
     | |______the parameter type `G` must be valid for lifetime `'_`...
     |        ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/ascii/mod.rs:1469:22: 1469:42}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
     |
  45 |     parser: impl Parser<I, O, E>,
     |                  ^^^^^^^^^^^^^^^
     = help: consider adding an explicit lifetime bound `G: anon`...

error[E0311]: the parameter type `F` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/ascii/mod.rs:1637:5
     |
1637 | /     trace("escaped_transform", move |input: &mut I| {
1638 | |         if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() {
1639 | |             streaming_escaped_transform_internal(input, &mut normal, control_char, &mut transform)
1640 | |         } else {
...    |
1643 | |     })
     | |      ^
     | |      |
     | |______the parameter type `F` must be valid for lifetime `'_`...
     |        ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/ascii/mod.rs:1637:32: 1637:52}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
     |
  45 |     parser: impl Parser<I, O, E>,
     |                  ^^^^^^^^^^^^^^^
     = help: consider adding an explicit lifetime bound `F: anon`...

error[E0311]: the parameter type `G` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/ascii/mod.rs:1637:5
     |
1637 | /     trace("escaped_transform", move |input: &mut I| {
1638 | |         if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() {
1639 | |             streaming_escaped_transform_internal(input, &mut normal, control_char, &mut transform)
1640 | |         } else {
...    |
1643 | |     })
     | |      ^
     | |      |
     | |______the parameter type `G` must be valid for lifetime `'_`...
     |        ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/ascii/mod.rs:1637:32: 1637:52}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
     |
  45 |     parser: impl Parser<I, O, E>,
     |                  ^^^^^^^^^^^^^^^
     = help: consider adding an explicit lifetime bound `G: anon`...

error[E0311]: the parameter type `P` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:56:5
     |
  56 | /     trace(
  57 | |         "bits",
  58 | |         unpeek(move |input: I| {
  59 | |             match parser.parse_peek((input, 0)) {
...    |
  74 | |         }),
  75 | |     )
     | |     ^
     | |     |
     | |_____the parameter type `P` must be valid for lifetime `'_`...
     |       ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:58:16: 58:31}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/parser.rs:1100:51
     |
1100 |     mut peek: impl FnMut(I) -> IResult<I, O, E> + 'a,
     |                                                   ^^
     = help: consider adding an explicit lifetime bound `P: anon`...

error[E0311]: the parameter type `I` may not live long enough
  --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:56:5
   |
56 | /     trace(
57 | |         "bits",
58 | |         unpeek(move |input: I| {
59 | |             match parser.parse_peek((input, 0)) {
...  |
74 | |         }),
75 | |     )
   | |     ^
   | |     |
   | |_____the parameter type `I` must be valid for lifetime `'_`...
   |       ...so that the type `impl for<'a> FnMut(&'a mut I) -> Result<O, ErrMode<E2>>` will meet its required lifetime bounds...
   |
note: ...that is required by this bound
  --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
   |
45 |     parser: impl Parser<I, O, E>,
   |                  ^^^^^^^^^^^^^^^
   = help: consider adding an explicit lifetime bound `I: anon`...

error[E0311]: the parameter type `O` may not live long enough
  --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:56:5
   |
56 | /     trace(
57 | |         "bits",
58 | |         unpeek(move |input: I| {
59 | |             match parser.parse_peek((input, 0)) {
...  |
74 | |         }),
75 | |     )
   | |     ^
   | |     |
   | |_____the parameter type `O` must be valid for lifetime `'_`...
   |       ...so that the type `impl for<'a> FnMut(&'a mut I) -> Result<O, ErrMode<E2>>` will meet its required lifetime bounds...
   |
note: ...that is required by this bound
  --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
   |
45 |     parser: impl Parser<I, O, E>,
   |                  ^^^^^^^^^^^^^^^
   = help: consider adding an explicit lifetime bound `O: anon`...

error[E0311]: the parameter type `E2` may not live long enough
  --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:56:5
   |
56 | /     trace(
57 | |         "bits",
58 | |         unpeek(move |input: I| {
59 | |             match parser.parse_peek((input, 0)) {
...  |
74 | |         }),
75 | |     )
   | |     ^
   | |     |
   | |_____the parameter type `E2` must be valid for lifetime `'_`...
   |       ...so that the type `impl for<'a> FnMut(&'a mut I) -> Result<O, ErrMode<E2>>` will meet its required lifetime bounds...
   |
note: ...that is required by this bound
  --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
   |
45 |     parser: impl Parser<I, O, E>,
   |                  ^^^^^^^^^^^^^^^
   = help: consider adding an explicit lifetime bound `E2: anon`...

error[E0311]: the parameter type `P` may not live long enough
  --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:56:5
   |
56 | /     trace(
57 | |         "bits",
58 | |         unpeek(move |input: I| {
59 | |             match parser.parse_peek((input, 0)) {
...  |
74 | |         }),
75 | |     )
   | |     ^
   | |     |
   | |_____the parameter type `P` must be valid for lifetime `'_`...
   |       ...so that the type `impl for<'a> FnMut(&'a mut I) -> Result<O, ErrMode<E2>>` will meet its required lifetime bounds...
   |
note: ...that is required by this bound
  --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
   |
45 |     parser: impl Parser<I, O, E>,
   |                  ^^^^^^^^^^^^^^^
   = help: consider adding an explicit lifetime bound `P: anon`...

error[E0311]: the parameter type `P` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:115:5
     |
 115 | /     trace(
 116 | |         "bytes",
 117 | |         unpeek(move |(input, offset): (I, usize)| {
 118 | |             let (inner, _) = if offset % BYTE != 0 {
...    |
 140 | |         }),
 141 | |     )
     | |     ^
     | |     |
     | |_____the parameter type `P` must be valid for lifetime `'_`...
     |       ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:117:16: 117:50}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/parser.rs:1100:51
     |
1100 |     mut peek: impl FnMut(I) -> IResult<I, O, E> + 'a,
     |                                                   ^^
     = help: consider adding an explicit lifetime bound `P: anon`...

error[E0311]: the parameter type `I` may not live long enough
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:115:5
    |
115 | /     trace(
116 | |         "bytes",
117 | |         unpeek(move |(input, offset): (I, usize)| {
118 | |             let (inner, _) = if offset % BYTE != 0 {
...   |
140 | |         }),
141 | |     )
    | |     ^
    | |     |
    | |_____the parameter type `I` must be valid for lifetime `'_`...
    |       ...so that the type `impl for<'a> FnMut(&'a mut (I, usize)) -> Result<O, ErrMode<E2>>` will meet its required lifetime bounds...
    |
note: ...that is required by this bound
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
    |
 45 |     parser: impl Parser<I, O, E>,
    |                  ^^^^^^^^^^^^^^^
    = help: consider adding an explicit lifetime bound `I: anon`...

error[E0311]: the parameter type `O` may not live long enough
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:115:5
    |
115 | /     trace(
116 | |         "bytes",
117 | |         unpeek(move |(input, offset): (I, usize)| {
118 | |             let (inner, _) = if offset % BYTE != 0 {
...   |
140 | |         }),
141 | |     )
    | |     ^
    | |     |
    | |_____the parameter type `O` must be valid for lifetime `'_`...
    |       ...so that the type `impl for<'a> FnMut(&'a mut (I, usize)) -> Result<O, ErrMode<E2>>` will meet its required lifetime bounds...
    |
note: ...that is required by this bound
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
    |
 45 |     parser: impl Parser<I, O, E>,
    |                  ^^^^^^^^^^^^^^^
    = help: consider adding an explicit lifetime bound `O: anon`...

error[E0311]: the parameter type `E2` may not live long enough
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:115:5
    |
115 | /     trace(
116 | |         "bytes",
117 | |         unpeek(move |(input, offset): (I, usize)| {
118 | |             let (inner, _) = if offset % BYTE != 0 {
...   |
140 | |         }),
141 | |     )
    | |     ^
    | |     |
    | |_____the parameter type `E2` must be valid for lifetime `'_`...
    |       ...so that the type `impl for<'a> FnMut(&'a mut (I, usize)) -> Result<O, ErrMode<E2>>` will meet its required lifetime bounds...
    |
note: ...that is required by this bound
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
    |
 45 |     parser: impl Parser<I, O, E>,
    |                  ^^^^^^^^^^^^^^^
    = help: consider adding an explicit lifetime bound `E2: anon`...

error[E0311]: the parameter type `P` may not live long enough
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:115:5
    |
115 | /     trace(
116 | |         "bytes",
117 | |         unpeek(move |(input, offset): (I, usize)| {
118 | |             let (inner, _) = if offset % BYTE != 0 {
...   |
140 | |         }),
141 | |     )
    | |     ^
    | |     |
    | |_____the parameter type `P` must be valid for lifetime `'_`...
    |       ...so that the type `impl for<'a> FnMut(&'a mut (I, usize)) -> Result<O, ErrMode<E2>>` will meet its required lifetime bounds...
    |
note: ...that is required by this bound
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
    |
 45 |     parser: impl Parser<I, O, E>,
    |                  ^^^^^^^^^^^^^^^
    = help: consider adding an explicit lifetime bound `P: anon`...

error[E0311]: the parameter type `I` may not live long enough
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:183:5
    |
183 | /     trace(
184 | |         "take",
185 | |         unpeek(move |input: (I, usize)| {
186 | |             if <I as StreamIsPartial>::is_partial_supported() {
...   |
191 | |         }),
192 | |     )
    | |     ^
    | |     |
    | |_____the parameter type `I` must be valid for lifetime `'_`...
    |       ...so that the type `impl for<'a> FnMut(&'a mut (I, usize)) -> Result<O, ErrMode<E>>` will meet its required lifetime bounds...
    |
note: ...that is required by this bound
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
    |
 45 |     parser: impl Parser<I, O, E>,
    |                  ^^^^^^^^^^^^^^^
    = help: consider adding an explicit lifetime bound `I: anon`...

error[E0311]: the parameter type `O` may not live long enough
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:183:5
    |
183 | /     trace(
184 | |         "take",
185 | |         unpeek(move |input: (I, usize)| {
186 | |             if <I as StreamIsPartial>::is_partial_supported() {
...   |
191 | |         }),
192 | |     )
    | |     ^
    | |     |
    | |_____the parameter type `O` must be valid for lifetime `'_`...
    |       ...so that the type `impl for<'a> FnMut(&'a mut (I, usize)) -> Result<O, ErrMode<E>>` will meet its required lifetime bounds...
    |
note: ...that is required by this bound
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
    |
 45 |     parser: impl Parser<I, O, E>,
    |                  ^^^^^^^^^^^^^^^
    = help: consider adding an explicit lifetime bound `O: anon`...

error[E0311]: the parameter type `E` may not live long enough
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:183:5
    |
183 | /     trace(
184 | |         "take",
185 | |         unpeek(move |input: (I, usize)| {
186 | |             if <I as StreamIsPartial>::is_partial_supported() {
...   |
191 | |         }),
192 | |     )
    | |     ^
    | |     |
    | |_____the parameter type `E` must be valid for lifetime `'_`...
    |       ...so that the type `impl for<'a> FnMut(&'a mut (I, usize)) -> Result<O, ErrMode<E>>` will meet its required lifetime bounds...
    |
note: ...that is required by this bound
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
    |
 45 |     parser: impl Parser<I, O, E>,
    |                  ^^^^^^^^^^^^^^^
    = help: consider adding an explicit lifetime bound `E: anon`...

error[E0311]: the parameter type `O` may not live long enough
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:316:5
    |
316 | /     trace("pattern", move |input: &mut (I, usize)| {
317 | |         let start = input.checkpoint();
318 | |
319 | |         take(count).parse_next(input).and_then(|o| {
...   |
329 | |         })
330 | |     })
    | |      ^
    | |      |
    | |______the parameter type `O` must be valid for lifetime `'_`...
    |        ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/bits/mod.rs:316:22: 316:51}` will meet its required lifetime bounds...
    |
note: ...that is required by this bound
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
    |
 45 |     parser: impl Parser<I, O, E>,
    |                  ^^^^^^^^^^^^^^^
    = help: consider adding an explicit lifetime bound `O: anon`...

[RUSTC-TIMING] simd_adler32 test:false 1.076
   Compiling miniz_oxide v0.8.9
error[E0311]: the parameter type `F` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/mod.rs:2434:5
     |
2434 | /     trace("length_take", move |i: &mut I| {
2435 | |         let length = f.parse_next(i)?;
2436 | |
2437 | |         crate::token::take(length).parse_next(i)
2438 | |     })
     | |      ^
     | |      |
     | |______the parameter type `F` must be valid for lifetime `'_`...
     |        ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/mod.rs:2434:26: 2434:42}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
     |
  45 |     parser: impl Parser<I, O, E>,
     |                  ^^^^^^^^^^^^^^^
     = help: consider adding an explicit lifetime bound `F: anon`...

error[E0311]: the parameter type `F` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/mod.rs:2503:5
     |
2503 | /     trace("length_and_then", move |i: &mut I| {
2504 | |         let data = length_take(f.by_ref()).parse_next(i)?;
2505 | |         let mut data = I::update_slice(i.clone(), data);
2506 | |         let _ = data.complete();
2507 | |         let o = g.by_ref().complete_err().parse_next(&mut data)?;
2508 | |         Ok(o)
2509 | |     })
     | |      ^
     | |      |
     | |______the parameter type `F` must be valid for lifetime `'_`...
     |        ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/mod.rs:2503:30: 2503:46}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
     |
  45 |     parser: impl Parser<I, O, E>,
     |                  ^^^^^^^^^^^^^^^
     = help: consider adding an explicit lifetime bound `F: anon`...

error[E0311]: the parameter type `G` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/mod.rs:2503:5
     |
2503 | /     trace("length_and_then", move |i: &mut I| {
2504 | |         let data = length_take(f.by_ref()).parse_next(i)?;
2505 | |         let mut data = I::update_slice(i.clone(), data);
2506 | |         let _ = data.complete();
2507 | |         let o = g.by_ref().complete_err().parse_next(&mut data)?;
2508 | |         Ok(o)
2509 | |     })
     | |      ^
     | |      |
     | |______the parameter type `G` must be valid for lifetime `'_`...
     |        ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/mod.rs:2503:30: 2503:46}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
     |
  45 |     parser: impl Parser<I, O, E>,
     |                  ^^^^^^^^^^^^^^^
     = help: consider adding an explicit lifetime bound `G: anon`...

error[E0311]: the parameter type `F` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/mod.rs:2572:5
     |
2572 | /     trace("length_repeat", move |i: &mut I| {
2573 | |         let n = f.parse_next(i)?;
2574 | |         let n = n.to_usize();
2575 | |         repeat(n, g.by_ref()).parse_next(i)
2576 | |     })
     | |      ^
     | |      |
     | |______the parameter type `F` must be valid for lifetime `'_`...
     |        ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/mod.rs:2572:28: 2572:44}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
     |
  45 |     parser: impl Parser<I, O, E>,
     |                  ^^^^^^^^^^^^^^^
     = help: consider adding an explicit lifetime bound `F: anon`...

error[E0311]: the parameter type `G` may not live long enough
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/mod.rs:2572:5
     |
2572 | /     trace("length_repeat", move |i: &mut I| {
2573 | |         let n = f.parse_next(i)?;
2574 | |         let n = n.to_usize();
2575 | |         repeat(n, g.by_ref()).parse_next(i)
2576 | |     })
     | |      ^
     | |      |
     | |______the parameter type `G` must be valid for lifetime `'_`...
     |        ...so that the type `{closure@/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/binary/mod.rs:2572:28: 2572:44}` will meet its required lifetime bounds...
     |
note: ...that is required by this bound
    --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/combinator/debug/mod.rs:45:18
     |
  45 |     parser: impl Parser<I, O, E>,
     |                  ^^^^^^^^^^^^^^^
     = help: consider adding an explicit lifetime bound `G: anon`...

error[E0311]: the parameter type `List` may not live long enough

@BoxyUwU
Copy link
Copy Markdown
Member

BoxyUwU commented Feb 14, 2026

r? lcnr

@rustbot rustbot assigned lcnr and unassigned BoxyUwU Feb 14, 2026
Copy link
Copy Markdown
Contributor

@lcnr lcnr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the errors you get are in a body, which is surprising. Can you minimize it?

View changes since this review

@amandasystems
Copy link
Copy Markdown
Contributor Author

the errors you get are in a body, which is surprising. Can you minimize it?

View changes since this review

I’m on it, but it seems interesting to me because as you and Boxy both said this shouldn’t happen so maybe I found something here. :)

@amandasystems
Copy link
Copy Markdown
Contributor Author

the errors you get are in a body, which is surprising. Can you minimize it?

View changes since this review

I think this is the same failure as the one I get for tests/ui/issues/issue-42467.rs:

error[E0311]: the parameter type `T` may not live long enough
  --> /home/amanda/rust/tests/ui/issues/issue-42467.rs:17:21
   |
LL |     type IntoIter = IntoIter<T>;
   |                     ^^^^^^^^^^^
   |                     |
   |                     the parameter type `T` must be valid for lifetime `'_`...
   |                     ...so that the type `T` will meet its required lifetime bounds...
   |
note: ...that is required by this bound
  --> /rustc/FAKE_PREFIX/library/core/src/iter/traits/collect.rs:291:28
   = help: consider adding an explicit lifetime bound `T: anon`...

I'm looking into where that is coming from.

@amandasystems
Copy link
Copy Markdown
Contributor Author

It's apparently coming from param_or_placeholder_bound, which used to generate an IsEmpty bound which would go on to check if T is a single ReVar whose VarValue is Empty during lexical region resolution but now generates an always-failing Any bound for the type T since it has no bounds in the environment etc.

I'm not sure if the information is available that would allow us to detect this case and simply not emit the bound in this case.

@lcnr
Copy link
Copy Markdown
Contributor

lcnr commented Feb 16, 2026

I expect tests/ui/issues/issue-42467.rs to fail. Does winnow also have an impl with an otherwise unconstrained region? How does that affect this crate?

@amandasystems
Copy link
Copy Markdown
Contributor Author

amandasystems commented Feb 16, 2026

I expect tests/ui/issues/issue-42467.rs to fail. Does winnow also have an impl with an otherwise unconstrained region? How does that affect this crate?

I think so, the failing code looks like this:

pub fn escaped<'a, I: 'a, Error, F, G, O1, O2>(
    mut normal: F,
    control_char: char,
    mut escapable: G,
) -> impl Parser<I, <I as Stream>::Slice, Error>
where
    I: StreamIsPartial,
    I: Stream,
    <I as Stream>::Token: AsChar + Clone,
    F: Parser<I, O1, Error>,
    G: Parser<I, O2, Error>,
    Error: ParserError<I>,
{
    trace("escaped", move |input: &mut I| {
        if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() {
            streaming_escaped_internal(input, &mut normal, control_char, &mut escapable)
        } else {
            complete_escaped_internal(input, &mut normal, control_char, &mut escapable)
        }
    })
}

I haven’t gotten around to minimising it yet but I suspect what trace does is just print something and in that case it shouldn’t be doing much interesting inside the closure where the failure is happening.

I’ll look into it some more once I’m better from my migraine, probably Wednesday.

@amandasystems
Copy link
Copy Markdown
Contributor Author

amandasystems commented Feb 19, 2026

I expect tests/ui/issues/issue-42467.rs to fail. Does winnow also have an impl with an otherwise unconstrained region? How does that affect this crate?

Here's a reduction!

pub fn escaped<'a, I: 'a, F, O1>(mut normal: F) -> impl Parser<I, <I as Stream>::Slice>
where
    I: Stream,
    F: Parser<I, O1>,
{
    trace(move |_input: &mut I| uses_normal(&mut normal))
}

fn uses_normal<I, F, O1>(_normal: &mut F) -> <I as Stream>::Slice
where
    I: Stream,
    F: Parser<I, O1>,
{
    todo!()
}

pub fn trace<I: Stream, O>(parser: impl Parser<I, O>) -> impl Parser<I, O> {
    parser
}

impl<'a, I, O, F> Parser<I, O> for F
where
    F: FnMut(&mut I) -> O + 'a,
    I: Stream,
{
}

pub trait Stream {
    type Slice;
}

pub trait Parser<I, O> {}

What happens here is that param_or_placeholder_bound is emitting an always-failing empty Any bound which fails somewhere in lexical region resolution. I think an or:ing somewhere in the middle removes the failing bound, because I tripped the path that would have encountered an IsEmpty, and that never fires.

Apparently, there are no default region bounds to apply in this case, I'm not familiar enough with this part of the compiler to know why.

@lcnr
Copy link
Copy Markdown
Contributor

lcnr commented Feb 27, 2026

does this error in MIR borrowck? -Ztreat-err-as-bug to look at the query stack when we emit an error 🤔

@amandasystems
Copy link
Copy Markdown
Contributor Author

amandasystems commented Mar 3, 2026

does this error in MIR borrowck? -Ztreat-err-as-bug to look at the query stack when we emit an error 🤔

Nope! It's emitted by trait selection as a generic bound failure. Here are the relevant parts:

15: <rustc_trait_selection::error_reporting::TypeErrCtxt>::report_generic_bound_failure
             at ./compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:694:14
  16: <rustc_trait_selection::error_reporting::TypeErrCtxt>::report_region_errors
             at ./compiler/rustc_trait_selection/src/error_reporting/infer/region.rs:82:26
  17: <rustc_trait_selection::traits::engine::ObligationCtxt<rustc_trait_selection::traits::FulfillmentError>>::resolve_regions_and_report_errors::<indexmap::set::IndexSet<rustc_middle::ty::Ty, rustc_hash::FxBuildHasher>>
             at ./compiler/rustc_trait_selection/src/traits/engine.rs:257:39
  18: rustc_hir_analysis::check::check::check_opaque_meets_bounds
             at ./compiler/rustc_hir_analysis/src/check/check.rs:392:9
  19: rustc_hir_analysis::check::check::check_opaque
             at ./compiler/rustc_hir_analysis/src/check/check.rs:242:13
  20: rustc_hir_analysis::check::check::check_item_type
             at ./compiler/rustc_hir_analysis/src/check/check.rs:888:17
  21: rustc_hir_analysis::check::wfcheck::check_well_formed
             at ./compiler/rustc_hir_analysis/src/check/wfcheck.rs:197:19
      [... omitted 20 frames ...]
  22: rustc_middle::query::inner::query_ensure_error_guaranteed::<rustc_data_structures::vec_cache::VecCache<rustc_span::def_id::LocalDefId, rustc_middle::query::erase::ErasedData<[u8; 1]>, rustc_middle::dep_graph::graph::DepNodeIndex>, ()>
             at ./compiler/rustc_middle/src/query/inner.rs:85:9
  23: <rustc_middle::query::plumbing::TyCtxtEnsureOk>::check_well_formed::<rustc_span::def_id::LocalDefId>
             at ./compiler/rustc_middle/src/query/plumbing.rs:275:9
  24: rustc_hir_analysis::check::wfcheck::check_type_wf::{closure#5}
             at ./compiler/rustc_hir_analysis/src/check/wfcheck.rs:2345:55
  25: <rustc_middle::hir::ModuleItems>::par_opaques::<rustc_hir_analysis::check::wfcheck::check_type_wf::{closure#5}>::{closure#0}
             at ./compiler/rustc_middle/src/hir/mod.rs:141:55

The failure seems to happen in rustc_infer::infer::lexical_region_resolve, where I have changed the handling of the empty bound from a pass to a fail. The debug statement I added to catch this case does fire, with the following:

0ms DEBUG rustc_infer::infer::lexical_region_resolve resolve_region('?1) = '?1
     0ms DEBUG rustc_infer::infer::lexical_region_resolve This bound was empty which should be true: [Empty(U0), Empty(U0), Value('!1_0.Named(DefId(0:32 ~ winnow_reduction[abcb]::{impl#0}::'_))), Value('!1_0.Named(DefId(0:32 ~ winnow_reduction[abcb]::{impl#0}::'_))), Value('!2_0.Named(DefId(0:32 ~ winnow_reduction[abcb]::{impl#0}::'_)))] '?1, F/#2
     0ms DEBUG rustc_infer::infer::lexical_region_resolve collect_errors: region error at RelateParamBound(winnow-reduction.rs:8:5: 8:58 (#0), Closure(DefId(0:10 ~ winnow_reduction[abcb]::escaped::{closure#0}), ['?0, I/#1, F/#2, O1/#3, i16, Binder { value: extern "RustCall" fn((&'^0.Named(DefId(0:30 ~ winnow_reduction[abcb]::escaped::'_)) mut I/#1,)) -> Alias(Projection, AliasTy { args: [I/#1], def_id: DefId(0:26 ~ winnow_reduction[abcb]::Stream::Slice), .. }), bound_vars: [Region(BrNamed(DefId(0:30 ~ winnow_reduction[abcb]::escaped::'_)))] }, (F/#2,)]), Some(winnow-reduction.rs:19:41: 19:53 (#0))): cannot verify that '?1 <= AnyBound([])

In other words, there is an empty AnyBound (previously represented by the deleted IsEmpty applied for a variable whose VarValue is Empty.

@lcnr
Copy link
Copy Markdown
Contributor

lcnr commented Mar 24, 2026

Happening when validating that the opaque types inferred in borrowck are well-formed

Unhappy about this 😅 this example should compile. I feel like the regression test could be made more minimal :3

I hate that we allow unconstrained lifetimes in impls in the first place :/ we should at least lint on them. Looking for the existing discussion here https://rust-lang.zulipchat.com/#narrow/channel/144729-t-types/topic/existing.20issue.20for.20unconstrained.20lifetimes.20in.20impls/with/581309540

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants