Fix accidental type inference in array coercion#140283
Fix accidental type inference in array coercion#140283rust-bors[bot] merged 1 commit intorust-lang:mainfrom
Conversation
|
rustbot has assigned @petrochenkov. Use |
There was a problem hiding this comment.
Please add a test to demonstrate the effect of this change. Especially since with this change, we would be accepting more code than on master (this is the snippet in the original issue):
fn foo() {}
fn bar() {}
fn main() {
let _a = if true { foo } else { bar };
let _b = vec![foo, bar];
let _c = [foo, bar];
d(if true { foo } else { bar });
e(vec![foo, bar]);
f([foo, bar]); // <- this PR now accepts this
}
fn d<T>(_: T) {}
fn e<T>(_: Vec<T>) {}
fn f<T>(_: [T; 2]) {}whereas on master this snippet does not compile w/
error[E0308]: mismatched types
--> src/main.rs:10:7
|
10 | f([foo, bar]);
| - ^^^^^^^^^^ expected `[fn() {foo}; 2]`, found `[fn(); 2]`
| |
| arguments to this function are incorrect
|
= note: expected array `[fn() {foo}; 2]`
found array `[fn(); 2]`
note: function defined here
--> src/main.rs:15:4
|
15 | fn f<T>(_: [T; 2]) {}
| ^ ---------
For more information about this error, try `rustc --explain E0308`.
I'm surprised there are no ui test diffs.
|
r? types |
|
There're some similar errors, but I'm unsure whether it's okay to allow these code. The Rust Reference. fn foo() {}
fn bar() {}
fn main() {
let block_var = 'a: { // Easy to fix, but not specified by the Rust Reference.
if false {
break 'a foo;
}
break 'a bar;
};
let loop_var = loop { // Easy to fix, but not specified by the Rust Reference.
if false {
break foo;
}
break bar;
};
let closure_var = || { // More complicated. But this should work according to the Rust Reference.
if false {
return foo;
}
return bar;
};
} |
Yea I think these all should work, too. Please fix the easy ones and add tests for all of them if we don't already have any |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
fdbaf03 to
b31fa29
Compare
|
Turns out the ‘easy’ cases aren’t so easy after all. I can't fix the inference regressions for now, but I might revisit them later once I understand type inference better. |
|
@rustbot ready |
|
I am not going to get to this in the next 10 days. I'll need to review the general state of inference here and write a T-types FCP text |
|
☔ The latest upstream changes (presumably #141716) made this pull request unmergeable. Please resolve the merge conflicts. |
|
Array expressions normally lub their element expressions' types to ensure that things like This PR changes that to instead fall back to "not knowing" that the argument type is array of infer var, but just having an infer var for the entire argument. Thus we typeck the array expression normally, lubbing the element expressions, and then in the end comparing the array expression's type with the array of infer var type. Things like fn foo() {}
fn bar() {}
fn f<T>(_: [T; 2]) {}
f([foo, bar]);and struct Foo;
struct Bar;
trait Trait {}
impl Trait for Foo {}
impl Trait for Bar {}
fn f<T>(_: [T; 2]) {}
f([&Foo, &Bar as &dyn Trait]);@rfcbot merge |
|
Team member @oli-obk has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
ec874ee to
9ccce41
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. |
This comment has been minimized.
This comment has been minimized.
9ccce41 to
b235cc2
Compare
|
I see the date that this was opened and am terribly sorry that you've waited this long @adwinwhite. That being said, I appreciate you opening this and seeing it through :) Overall here, even though I am doing other experimentation in this area, these changes here align with the principles that I am trying to achieve (that the LUB inference is "somewhat" independent from the "expected type" - and also doesn't directly result in any additional order-dependent behavior). @bors r+ rollup=never |
This comment has been minimized.
This comment has been minimized.
What is this?This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.Comparing 842bd5b (parent) -> 35a31ba (this PR) Test differencesShow 14 test diffsStage 1
Stage 2
Additionally, 10 doctest diffs were found. These are ignored, as they are noisy. Job group index
Test dashboardRun cargo run --manifest-path src/ci/citool/Cargo.toml -- \
test-dashboard 35a31ba763976907cd38ba88743a3aefbaf8ffff --output-dir test-dashboardAnd then open Job duration changes
How to interpret the job duration changes?Job durations can vary a lot, based on the actual runner instance |
|
Finished benchmarking commit (35a31ba): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)This benchmark run did not return any relevant results for this metric. CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 473.781s -> 476.214s (0.51%) |
Fix accidental type inference in array coercion Fixes rust-lang/rust#136420. If the expectation of array element is a type variable, we should avoid resolving it to the first element's type and wait until LUB coercion is completed. We create a free type variable instead which is only used in this `CoerceMany`. [`check_expr_match`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/_match.rs#L72) and [`check_expr_if`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expr.rs#L1329) where `CoerceMany` is also used do the [same](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expectation.rs#L50). ### [FCP Proposal](rust-lang/rust#140283 (comment)): > Array expressions normally lub their element expressions' types to ensure that things like `[5, 5_u8]` work and don't result in type mismatches. When invoking a generic function `fn foo<T>(_: [T; N])` with an array expression, we end up with an infer var for the element type of the array in the signature. So when typecking the first array element we compare its type with the infer var and thus subsequently require all other elements to be the same type. > > This PR changes that to instead fall back to "not knowing" that the argument type is array of infer var, but just having an infer var for the entire argument. Thus we typeck the array expression normally, lubbing the element expressions, and then in the end comparing the array expression's type with the array of infer var type. > > Things like > > ```rust > fn foo() {} > fn bar() {} > fn f<T>(_: [T; 2]) {} > > f([foo, bar]); > ``` > > and > > ```rust > struct Foo; > struct Bar; > trait Trait {} > impl Trait for Foo {} > impl Trait for Bar {} > fn f<T>(_: [T; 2]) {} > > f([&Foo, &Bar as &dyn Trait]); > ``` ### Remaining inconsistency with `if` and `match`(rust-lang/rust#145048): The typeck of array always uses the element coercion target type as the expectation of element exprs while `if` and `match` use `NoExpectation` if the expected type is an infer var. This causes that array doesn't support nested coercion. ```rust fn foo() {} fn bar() {} fn main() { let _ = [foo, if false { bar } else { foo }]; // type mismatch when trying to coerce `bar` into `foo` in if-then branch coercion. } ``` But we can't simply change this behavior to be the same as `if` and `match` since [many code](rust-lang/rust#140283 (comment)) depends on using the first element's type as expectation.
Fix accidental type inference in array coercion Fixes rust-lang/rust#136420. If the expectation of array element is a type variable, we should avoid resolving it to the first element's type and wait until LUB coercion is completed. We create a free type variable instead which is only used in this `CoerceMany`. [`check_expr_match`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/_match.rs#L72) and [`check_expr_if`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expr.rs#L1329) where `CoerceMany` is also used do the [same](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expectation.rs#L50). ### [FCP Proposal](rust-lang/rust#140283 (comment)): > Array expressions normally lub their element expressions' types to ensure that things like `[5, 5_u8]` work and don't result in type mismatches. When invoking a generic function `fn foo<T>(_: [T; N])` with an array expression, we end up with an infer var for the element type of the array in the signature. So when typecking the first array element we compare its type with the infer var and thus subsequently require all other elements to be the same type. > > This PR changes that to instead fall back to "not knowing" that the argument type is array of infer var, but just having an infer var for the entire argument. Thus we typeck the array expression normally, lubbing the element expressions, and then in the end comparing the array expression's type with the array of infer var type. > > Things like > > ```rust > fn foo() {} > fn bar() {} > fn f<T>(_: [T; 2]) {} > > f([foo, bar]); > ``` > > and > > ```rust > struct Foo; > struct Bar; > trait Trait {} > impl Trait for Foo {} > impl Trait for Bar {} > fn f<T>(_: [T; 2]) {} > > f([&Foo, &Bar as &dyn Trait]); > ``` ### Remaining inconsistency with `if` and `match`(rust-lang/rust#145048): The typeck of array always uses the element coercion target type as the expectation of element exprs while `if` and `match` use `NoExpectation` if the expected type is an infer var. This causes that array doesn't support nested coercion. ```rust fn foo() {} fn bar() {} fn main() { let _ = [foo, if false { bar } else { foo }]; // type mismatch when trying to coerce `bar` into `foo` in if-then branch coercion. } ``` But we can't simply change this behavior to be the same as `if` and `match` since [many code](rust-lang/rust#140283 (comment)) depends on using the first element's type as expectation.
Fix accidental type inference in array coercion Fixes rust-lang/rust#136420. If the expectation of array element is a type variable, we should avoid resolving it to the first element's type and wait until LUB coercion is completed. We create a free type variable instead which is only used in this `CoerceMany`. [`check_expr_match`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/_match.rs#L72) and [`check_expr_if`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expr.rs#L1329) where `CoerceMany` is also used do the [same](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expectation.rs#L50). ### [FCP Proposal](rust-lang/rust#140283 (comment)): > Array expressions normally lub their element expressions' types to ensure that things like `[5, 5_u8]` work and don't result in type mismatches. When invoking a generic function `fn foo<T>(_: [T; N])` with an array expression, we end up with an infer var for the element type of the array in the signature. So when typecking the first array element we compare its type with the infer var and thus subsequently require all other elements to be the same type. > > This PR changes that to instead fall back to "not knowing" that the argument type is array of infer var, but just having an infer var for the entire argument. Thus we typeck the array expression normally, lubbing the element expressions, and then in the end comparing the array expression's type with the array of infer var type. > > Things like > > ```rust > fn foo() {} > fn bar() {} > fn f<T>(_: [T; 2]) {} > > f([foo, bar]); > ``` > > and > > ```rust > struct Foo; > struct Bar; > trait Trait {} > impl Trait for Foo {} > impl Trait for Bar {} > fn f<T>(_: [T; 2]) {} > > f([&Foo, &Bar as &dyn Trait]); > ``` ### Remaining inconsistency with `if` and `match`(rust-lang/rust#145048): The typeck of array always uses the element coercion target type as the expectation of element exprs while `if` and `match` use `NoExpectation` if the expected type is an infer var. This causes that array doesn't support nested coercion. ```rust fn foo() {} fn bar() {} fn main() { let _ = [foo, if false { bar } else { foo }]; // type mismatch when trying to coerce `bar` into `foo` in if-then branch coercion. } ``` But we can't simply change this behavior to be the same as `if` and `match` since [many code](rust-lang/rust#140283 (comment)) depends on using the first element's type as expectation.
Fix accidental type inference in array coercion Fixes rust-lang/rust#136420. If the expectation of array element is a type variable, we should avoid resolving it to the first element's type and wait until LUB coercion is completed. We create a free type variable instead which is only used in this `CoerceMany`. [`check_expr_match`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/_match.rs#L72) and [`check_expr_if`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expr.rs#L1329) where `CoerceMany` is also used do the [same](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expectation.rs#L50). ### [FCP Proposal](rust-lang/rust#140283 (comment)): > Array expressions normally lub their element expressions' types to ensure that things like `[5, 5_u8]` work and don't result in type mismatches. When invoking a generic function `fn foo<T>(_: [T; N])` with an array expression, we end up with an infer var for the element type of the array in the signature. So when typecking the first array element we compare its type with the infer var and thus subsequently require all other elements to be the same type. > > This PR changes that to instead fall back to "not knowing" that the argument type is array of infer var, but just having an infer var for the entire argument. Thus we typeck the array expression normally, lubbing the element expressions, and then in the end comparing the array expression's type with the array of infer var type. > > Things like > > ```rust > fn foo() {} > fn bar() {} > fn f<T>(_: [T; 2]) {} > > f([foo, bar]); > ``` > > and > > ```rust > struct Foo; > struct Bar; > trait Trait {} > impl Trait for Foo {} > impl Trait for Bar {} > fn f<T>(_: [T; 2]) {} > > f([&Foo, &Bar as &dyn Trait]); > ``` ### Remaining inconsistency with `if` and `match`(rust-lang/rust#145048): The typeck of array always uses the element coercion target type as the expectation of element exprs while `if` and `match` use `NoExpectation` if the expected type is an infer var. This causes that array doesn't support nested coercion. ```rust fn foo() {} fn bar() {} fn main() { let _ = [foo, if false { bar } else { foo }]; // type mismatch when trying to coerce `bar` into `foo` in if-then branch coercion. } ``` But we can't simply change this behavior to be the same as `if` and `match` since [many code](rust-lang/rust#140283 (comment)) depends on using the first element's type as expectation.
Fix accidental type inference in array coercion Fixes rust-lang/rust#136420. If the expectation of array element is a type variable, we should avoid resolving it to the first element's type and wait until LUB coercion is completed. We create a free type variable instead which is only used in this `CoerceMany`. [`check_expr_match`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/_match.rs#L72) and [`check_expr_if`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expr.rs#L1329) where `CoerceMany` is also used do the [same](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expectation.rs#L50). ### [FCP Proposal](rust-lang/rust#140283 (comment)): > Array expressions normally lub their element expressions' types to ensure that things like `[5, 5_u8]` work and don't result in type mismatches. When invoking a generic function `fn foo<T>(_: [T; N])` with an array expression, we end up with an infer var for the element type of the array in the signature. So when typecking the first array element we compare its type with the infer var and thus subsequently require all other elements to be the same type. > > This PR changes that to instead fall back to "not knowing" that the argument type is array of infer var, but just having an infer var for the entire argument. Thus we typeck the array expression normally, lubbing the element expressions, and then in the end comparing the array expression's type with the array of infer var type. > > Things like > > ```rust > fn foo() {} > fn bar() {} > fn f<T>(_: [T; 2]) {} > > f([foo, bar]); > ``` > > and > > ```rust > struct Foo; > struct Bar; > trait Trait {} > impl Trait for Foo {} > impl Trait for Bar {} > fn f<T>(_: [T; 2]) {} > > f([&Foo, &Bar as &dyn Trait]); > ``` ### Remaining inconsistency with `if` and `match`(rust-lang/rust#145048): The typeck of array always uses the element coercion target type as the expectation of element exprs while `if` and `match` use `NoExpectation` if the expected type is an infer var. This causes that array doesn't support nested coercion. ```rust fn foo() {} fn bar() {} fn main() { let _ = [foo, if false { bar } else { foo }]; // type mismatch when trying to coerce `bar` into `foo` in if-then branch coercion. } ``` But we can't simply change this behavior to be the same as `if` and `match` since [many code](rust-lang/rust#140283 (comment)) depends on using the first element's type as expectation.
Fix accidental type inference in array coercion Fixes rust-lang/rust#136420. If the expectation of array element is a type variable, we should avoid resolving it to the first element's type and wait until LUB coercion is completed. We create a free type variable instead which is only used in this `CoerceMany`. [`check_expr_match`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/_match.rs#L72) and [`check_expr_if`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expr.rs#L1329) where `CoerceMany` is also used do the [same](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expectation.rs#L50). ### [FCP Proposal](rust-lang/rust#140283 (comment)): > Array expressions normally lub their element expressions' types to ensure that things like `[5, 5_u8]` work and don't result in type mismatches. When invoking a generic function `fn foo<T>(_: [T; N])` with an array expression, we end up with an infer var for the element type of the array in the signature. So when typecking the first array element we compare its type with the infer var and thus subsequently require all other elements to be the same type. > > This PR changes that to instead fall back to "not knowing" that the argument type is array of infer var, but just having an infer var for the entire argument. Thus we typeck the array expression normally, lubbing the element expressions, and then in the end comparing the array expression's type with the array of infer var type. > > Things like > > ```rust > fn foo() {} > fn bar() {} > fn f<T>(_: [T; 2]) {} > > f([foo, bar]); > ``` > > and > > ```rust > struct Foo; > struct Bar; > trait Trait {} > impl Trait for Foo {} > impl Trait for Bar {} > fn f<T>(_: [T; 2]) {} > > f([&Foo, &Bar as &dyn Trait]); > ``` ### Remaining inconsistency with `if` and `match`(rust-lang/rust#145048): The typeck of array always uses the element coercion target type as the expectation of element exprs while `if` and `match` use `NoExpectation` if the expected type is an infer var. This causes that array doesn't support nested coercion. ```rust fn foo() {} fn bar() {} fn main() { let _ = [foo, if false { bar } else { foo }]; // type mismatch when trying to coerce `bar` into `foo` in if-then branch coercion. } ``` But we can't simply change this behavior to be the same as `if` and `match` since [many code](rust-lang/rust#140283 (comment)) depends on using the first element's type as expectation.
Fix accidental type inference in array coercion Fixes rust-lang/rust#136420. If the expectation of array element is a type variable, we should avoid resolving it to the first element's type and wait until LUB coercion is completed. We create a free type variable instead which is only used in this `CoerceMany`. [`check_expr_match`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/_match.rs#L72) and [`check_expr_if`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expr.rs#L1329) where `CoerceMany` is also used do the [same](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expectation.rs#L50). ### [FCP Proposal](rust-lang/rust#140283 (comment)): > Array expressions normally lub their element expressions' types to ensure that things like `[5, 5_u8]` work and don't result in type mismatches. When invoking a generic function `fn foo<T>(_: [T; N])` with an array expression, we end up with an infer var for the element type of the array in the signature. So when typecking the first array element we compare its type with the infer var and thus subsequently require all other elements to be the same type. > > This PR changes that to instead fall back to "not knowing" that the argument type is array of infer var, but just having an infer var for the entire argument. Thus we typeck the array expression normally, lubbing the element expressions, and then in the end comparing the array expression's type with the array of infer var type. > > Things like > > ```rust > fn foo() {} > fn bar() {} > fn f<T>(_: [T; 2]) {} > > f([foo, bar]); > ``` > > and > > ```rust > struct Foo; > struct Bar; > trait Trait {} > impl Trait for Foo {} > impl Trait for Bar {} > fn f<T>(_: [T; 2]) {} > > f([&Foo, &Bar as &dyn Trait]); > ``` ### Remaining inconsistency with `if` and `match`(rust-lang/rust#145048): The typeck of array always uses the element coercion target type as the expectation of element exprs while `if` and `match` use `NoExpectation` if the expected type is an infer var. This causes that array doesn't support nested coercion. ```rust fn foo() {} fn bar() {} fn main() { let _ = [foo, if false { bar } else { foo }]; // type mismatch when trying to coerce `bar` into `foo` in if-then branch coercion. } ``` But we can't simply change this behavior to be the same as `if` and `match` since [many code](rust-lang/rust#140283 (comment)) depends on using the first element's type as expectation.
Fix accidental type inference in array coercion Fixes rust-lang/rust#136420. If the expectation of array element is a type variable, we should avoid resolving it to the first element's type and wait until LUB coercion is completed. We create a free type variable instead which is only used in this `CoerceMany`. [`check_expr_match`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/_match.rs#L72) and [`check_expr_if`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expr.rs#L1329) where `CoerceMany` is also used do the [same](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expectation.rs#L50). ### [FCP Proposal](rust-lang/rust#140283 (comment)): > Array expressions normally lub their element expressions' types to ensure that things like `[5, 5_u8]` work and don't result in type mismatches. When invoking a generic function `fn foo<T>(_: [T; N])` with an array expression, we end up with an infer var for the element type of the array in the signature. So when typecking the first array element we compare its type with the infer var and thus subsequently require all other elements to be the same type. > > This PR changes that to instead fall back to "not knowing" that the argument type is array of infer var, but just having an infer var for the entire argument. Thus we typeck the array expression normally, lubbing the element expressions, and then in the end comparing the array expression's type with the array of infer var type. > > Things like > > ```rust > fn foo() {} > fn bar() {} > fn f<T>(_: [T; 2]) {} > > f([foo, bar]); > ``` > > and > > ```rust > struct Foo; > struct Bar; > trait Trait {} > impl Trait for Foo {} > impl Trait for Bar {} > fn f<T>(_: [T; 2]) {} > > f([&Foo, &Bar as &dyn Trait]); > ``` ### Remaining inconsistency with `if` and `match`(rust-lang/rust#145048): The typeck of array always uses the element coercion target type as the expectation of element exprs while `if` and `match` use `NoExpectation` if the expected type is an infer var. This causes that array doesn't support nested coercion. ```rust fn foo() {} fn bar() {} fn main() { let _ = [foo, if false { bar } else { foo }]; // type mismatch when trying to coerce `bar` into `foo` in if-then branch coercion. } ``` But we can't simply change this behavior to be the same as `if` and `match` since [many code](rust-lang/rust#140283 (comment)) depends on using the first element's type as expectation.
Fix accidental type inference in array coercion Fixes rust-lang/rust#136420. If the expectation of array element is a type variable, we should avoid resolving it to the first element's type and wait until LUB coercion is completed. We create a free type variable instead which is only used in this `CoerceMany`. [`check_expr_match`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/_match.rs#L72) and [`check_expr_if`](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expr.rs#L1329) where `CoerceMany` is also used do the [same](https://github.com/rust-lang/rust/blob/847e3ee6b0e614937eee4e6d8f61094411eadcc0/compiler/rustc_hir_typeck/src/expectation.rs#L50). ### [FCP Proposal](rust-lang/rust#140283 (comment)): > Array expressions normally lub their element expressions' types to ensure that things like `[5, 5_u8]` work and don't result in type mismatches. When invoking a generic function `fn foo<T>(_: [T; N])` with an array expression, we end up with an infer var for the element type of the array in the signature. So when typecking the first array element we compare its type with the infer var and thus subsequently require all other elements to be the same type. > > This PR changes that to instead fall back to "not knowing" that the argument type is array of infer var, but just having an infer var for the entire argument. Thus we typeck the array expression normally, lubbing the element expressions, and then in the end comparing the array expression's type with the array of infer var type. > > Things like > > ```rust > fn foo() {} > fn bar() {} > fn f<T>(_: [T; 2]) {} > > f([foo, bar]); > ``` > > and > > ```rust > struct Foo; > struct Bar; > trait Trait {} > impl Trait for Foo {} > impl Trait for Bar {} > fn f<T>(_: [T; 2]) {} > > f([&Foo, &Bar as &dyn Trait]); > ``` ### Remaining inconsistency with `if` and `match`(rust-lang/rust#145048): The typeck of array always uses the element coercion target type as the expectation of element exprs while `if` and `match` use `NoExpectation` if the expected type is an infer var. This causes that array doesn't support nested coercion. ```rust fn foo() {} fn bar() {} fn main() { let _ = [foo, if false { bar } else { foo }]; // type mismatch when trying to coerce `bar` into `foo` in if-then branch coercion. } ``` But we can't simply change this behavior to be the same as `if` and `match` since [many code](rust-lang/rust#140283 (comment)) depends on using the first element's type as expectation.
Pkgsrc changes: * Update version & checksums, and adapt to new libc crate included. Upstream changes relative to 1.94.1: Version 1.95 (2026-04-16) ========================== Language -------- - [Stabilize `if let` guards on match arms] (rust-lang/rust#141295) - [`irrefutable_let_patterns` lint no longer lints on let chains] (rust-lang/rust#146832) - [Support importing path-segment keywords with renaming] (rust-lang/rust#146972) - [Stabilize inline assembly for PowerPC and PowerPC64] (rust-lang/rust#147996) - [const-eval: be more consistent in the behavior of padding during typed copies] (rust-lang/rust#148967) - [Const blocks are no longer evaluated to determine if expressions involving fallible operations can implicitly be constant-promoted.] (rust-lang/rust#150557). Expressions whose ability to implicitly be promoted would depend on the result of a const block are no longer implicitly promoted. - [Make operational semantics of pattern matching independent of crate and module] (rust-lang/rust#150681) Compiler -------- - [Stabilize `--remap-path-scope` for controlling the scoping of how paths get remapped in the resulting binary] (rust-lang/rust#147611) Platform Support ---------------- - [Promote `powerpc64-unknown-linux-musl` to Tier 2 with host tools] (rust-lang/rust#149962) - [Promote `aarch64-apple-tvos` to Tier 2] (rust-lang/rust#152021) - [Promote `aarch64-apple-tvos-sim` to Tier 2] (rust-lang/rust#152021) - [Promote `aarch64-apple-watchos` to Tier 2] (rust-lang/rust#152021) - [Promote `aarch64-apple-watchos-sim` to Tier 2] (rust-lang/rust#152021) - [Promote `aarch64-apple-visionos` to Tier 2] (rust-lang/rust#152021) - [Promote `aarch64-apple-visionos-sim` to Tier 2] (rust-lang/rust#152021) Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. https://doc.rust-lang.org/rustc/platform-support.html Libraries --------- - [`thread::scope`: document how join interacts with TLS destructors] (rust-lang/rust#149482) - [Speed up `str::contains` on aarch64 targets with `neon` target feature enabled by default] (rust-lang/rust#152176) Stabilized APIs --------------- - [`MaybeUninit<[T; N]>: From<[MaybeUninit<T>; N]>`] (https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-From%3CMaybeUninit%3C%5BT;+N%5D%3E%3E-for-%5BMaybeUninit%3CT%3E;+N%5D) - [`MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>; N]>`] (https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-AsRef%3C%5BMaybeUninit%3CT%3E;+N%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E) - [`MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>]>`] (https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-AsRef%3C%5BMaybeUninit%3CT%3E%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E) - [`MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>; N]>`] (https://doc.rust-lang.org/beta/std/mem/union.MaybeUninit.html#impl-AsMut%3C%5BMaybeUninit%3CT%3E;+N%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E) - [`MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>]>`] (https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-AsMut%3C%5BMaybeUninit%3CT%3E%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E) - [`[MaybeUninit<T>; N]: From<MaybeUninit<[T; N]>>`] (https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-From%3C%5BMaybeUninit%3CT%3E;+N%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E) - [`Cell<[T; N]>: AsRef<[Cell<T>; N]>`] (https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#impl-AsRef%3C%5BCell%3CT%3E;+N%5D%3E-for-Cell%3C%5BT;+N%5D%3E) - [`Cell<[T; N]>: AsRef<[Cell<T>]>`] (https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#impl-AsRef%3C%5BCell%3CT%3E%5D%3E-for-Cell%3C%5BT;+N%5D%3E) - [`Cell<[T]>: AsRef<[Cell<T>]>`] (https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#impl-AsRef%3C%5BCell%3CT%3E%5D%3E-for-Cell%3C%5BT%5D%3E) - [`bool: TryFrom<{integer}>`] (https://doc.rust-lang.org/stable/std/primitive.bool.html#impl-TryFrom%3Cu128%3E-for-bool) - [`AtomicPtr::update`] (https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.update) - [`AtomicPtr::try_update`] (https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.try_update) - [`AtomicBool::update`] (https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicBool.html#method.update) - [`AtomicBool::try_update`] (https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicBool.html#method.try_update) - [`AtomicIn::update`] (https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicIsize.html#method.update) - [`AtomicIn::try_update`] (https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicIsize.html#method.try_update) - [`AtomicUn::update`] (https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicUsize.html#method.update) - [`AtomicUn::try_update`] (https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicUsize.html#method.try_update) - [`cfg_select!`] (https://doc.rust-lang.org/stable/std/macro.cfg_select.html) - [`mod core::range`] (https://doc.rust-lang.org/stable/core/range/index.html) - [`core::range::RangeInclusive`] (https://doc.rust-lang.org/stable/core/range/struct.RangeInclusive.html) - [`core::range::RangeInclusiveIter`] (https://doc.rust-lang.org/stable/core/range/struct.RangeInclusiveIter.html) - [`core::hint::cold_path`] (https://doc.rust-lang.org/stable/core/hint/fn.cold_path.html) - [`<*const T>::as_ref_unchecked`] (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_ref_unchecked) - [`<*mut T>::as_ref_unchecked`] (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_ref_unchecked-1) - [`<*mut T>::as_mut_unchecked`] (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_mut_unchecked) These previously stable APIs are now stable in const contexts: - [`fmt::from_fn`] (https://doc.rust-lang.org/stable/std/fmt/fn.from_fn.html) - [`ControlFlow::is_break`] (https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.is_break) - [`ControlFlow::is_continue`] (https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.is_continue) Cargo ----- - [docs(report): enhance man pages for `cargo report *`] (rust-lang/cargo#16430) Rustdoc ----- - [In search results, rank unstable items lower] (rust-lang/rust#149460) - [Add new "hide deprecated items" setting in rustdoc] (rust-lang/rust#151091) Compatibility Notes ------------------- - [Array coercions may now result in less inference constraints than before] (rust-lang/rust#140283) - Importing `$crate` without renaming, i.e. `use $crate::{self};`, is now no longer permitted due to stricter error checking for `self` imports. - [const-eval: be more consistent in the behavior of padding during typed copies.] (rust-lang/rust#148967) In very rare cases, this may cause compilation errors due to bytes from parts of a pointer ending up in the padding bytes of a `const` or `static`. - [A future-incompatibility warning lint `ambiguous_glob_imported_traits` is now reported when using an ambiguously glob imported trait] (rust-lang/rust#149058) - [Check lifetime bounds of types mentioning only type parameters] (rust-lang/rust#149389) - [Report more visibility-related ambiguous import errors] (rust-lang/rust#149596) - [Deprecate `Eq::assert_receiver_is_total_eq` and emit future compatibility warnings on manual impls] (rust-lang/rust#149978) - [powerpc64: Use the ELF ABI version set in target spec instead of guessing] (rust-lang/rust#150468) (fixes the ELF ABI used by the OpenBSD target) - Matching on a `#[non_exhaustive]` enum [now reads the discriminant, even if the enum has only one variant] (rust-lang/rust#150681). This can cause closures to capture values that they previously wouldn't. - `mut ref` and `mut ref mut` patterns, part of the unstable [Match Ergonomics 2024 RFC] (rust-lang/rust#123076), were accidentally allowed on stable within struct pattern field shorthand. These patterns are now correctly feature-gated as unstable in this position. - [Add future-compatibility warning for derive helper attributes which conflict with built-in attributes] (rust-lang/rust#151152) - [JSON target specs] (https://doc.rust-lang.org/rustc/targets/custom.html) have been destabilized and now require `-Z unstable-options` to use. Previously, they could not be used without the standard library, which has no stable build mechanism. In preparation for the `build-std` project adding that support, JSON target specs are being proactively gated to ensure they remain unstable even if `build-std` is stabilized. Cargo now includes the `-Z json-target-spec` CLI flag to automatically pass `-Z unstable-options` to the compiler when needed. See [#150151] (rust-lang/rust#150151), [#151534] (rust-lang/rust#150151), and [rust-lang/cargo#16557] (rust-lang/cargo#16557). - [The arguments of `#[feature]` attributes on invalid targets are now checked] (rust-lang/rust#153764) Internal Changes ---------------- These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. - [Update to LLVM 22](rust-lang/rust#150722)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [rust](https://github.com/rust-lang/rust) | | minor | `1.94.0` → `1.95.0` | | rust | stage | minor | `1.94-bookworm` → `1.95-bookworm` | --- ### Release Notes <details> <summary>rust-lang/rust (rust)</summary> ### [`v1.95.0`](https://github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1950-2026-04-16) [Compare Source](rust-lang/rust@1.94.1...1.95.0) \=========================== <a id="1.95-Language"></a> ## Language - [Stabilize `if let` guards on match arms](rust-lang/rust#141295) - [`irrefutable_let_patterns` lint no longer lints on let chains](rust-lang/rust#146832) - [Support importing path-segment keywords with renaming](rust-lang/rust#146972) - [Stabilize inline assembly for PowerPC and PowerPC64](rust-lang/rust#147996) - [const-eval: be more consistent in the behavior of padding during typed copies](rust-lang/rust#148967) - [Const blocks are no longer evaluated to determine if expressions involving fallible operations can implicitly be constant-promoted.](rust-lang/rust#150557). Expressions whose ability to implicitly be promoted would depend on the result of a const block are no longer implicitly promoted. - [Make operational semantics of pattern matching independent of crate and module](rust-lang/rust#150681) <a id="1.95-Compiler"></a> ## Compiler - [Stabilize `--remap-path-scope` for controlling the scoping of how paths get remapped in the resulting binary](rust-lang/rust#147611) - [Apply patches for CVE-2026-6042 and CVE-2026-40200 to vendored musl](rust-lang/rust#155171) <a id="1.95-Platform-Support"></a> ## Platform Support - [Promote `powerpc64-unknown-linux-musl` to Tier 2 with host tools](rust-lang/rust#149962) - [Promote `aarch64-apple-tvos` to Tier 2](rust-lang/rust#152021) - [Promote `aarch64-apple-tvos-sim` to Tier 2](rust-lang/rust#152021) - [Promote `aarch64-apple-watchos` to Tier 2](rust-lang/rust#152021) - [Promote `aarch64-apple-watchos-sim` to Tier 2](rust-lang/rust#152021) - [Promote `aarch64-apple-visionos` to Tier 2](rust-lang/rust#152021) - [Promote `aarch64-apple-visionos-sim` to Tier 2](rust-lang/rust#152021) Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. [platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html <a id="1.95-Libraries"></a> ## Libraries - [`thread::scope`: document how join interacts with TLS destructors](rust-lang/rust#149482) - [Speed up `str::contains` on aarch64 targets with `neon` target feature enabled by default](rust-lang/rust#152176) <a id="1.95-Stabilized-APIs"></a> ## Stabilized APIs - [`MaybeUninit<[T; N]>: From<[MaybeUninit<T>; N]>`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-From%3CMaybeUninit%3C%5BT;+N%5D%3E%3E-for-%5BMaybeUninit%3CT%3E;+N%5D) - [`MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>; N]>`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-AsRef%3C%5BMaybeUninit%3CT%3E;+N%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E) - [`MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>]>`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-AsRef%3C%5BMaybeUninit%3CT%3E%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E) - [`MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>; N]>`](https://doc.rust-lang.org/beta/std/mem/union.MaybeUninit.html#impl-AsMut%3C%5BMaybeUninit%3CT%3E;+N%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E) - [`MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>]>`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-AsMut%3C%5BMaybeUninit%3CT%3E%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E) - [`[MaybeUninit<T>; N]: From<MaybeUninit<[T; N]>>`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#impl-From%3C%5BMaybeUninit%3CT%3E;+N%5D%3E-for-MaybeUninit%3C%5BT;+N%5D%3E) - [`Cell<[T; N]>: AsRef<[Cell<T>; N]>`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#impl-AsRef%3C%5BCell%3CT%3E;+N%5D%3E-for-Cell%3C%5BT;+N%5D%3E) - [`Cell<[T; N]>: AsRef<[Cell<T>]>`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#impl-AsRef%3C%5BCell%3CT%3E%5D%3E-for-Cell%3C%5BT;+N%5D%3E) - [`Cell<[T]>: AsRef<[Cell<T>]>`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#impl-AsRef%3C%5BCell%3CT%3E%5D%3E-for-Cell%3C%5BT%5D%3E) - [`bool: TryFrom<{integer}>`](https://doc.rust-lang.org/stable/std/primitive.bool.html#impl-TryFrom%3Cu128%3E-for-bool) - [`AtomicPtr::update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.update) - [`AtomicPtr::try_update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.try_update) - [`AtomicBool::update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicBool.html#method.update) - [`AtomicBool::try_update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicBool.html#method.try_update) - [`AtomicIn::update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicIsize.html#method.update) - [`AtomicIn::try_update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicIsize.html#method.try_update) - [`AtomicUn::update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicUsize.html#method.update) - [`AtomicUn::try_update`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicUsize.html#method.try_update) - [`cfg_select!`](https://doc.rust-lang.org/stable/std/macro.cfg_select.html) - [`mod core::range`](https://doc.rust-lang.org/stable/core/range/index.html) - [`core::range::RangeInclusive`](https://doc.rust-lang.org/stable/core/range/struct.RangeInclusive.html) - [`core::range::RangeInclusiveIter`](https://doc.rust-lang.org/stable/core/range/struct.RangeInclusiveIter.html) - [`core::hint::cold_path`](https://doc.rust-lang.org/stable/core/hint/fn.cold_path.html) - [`<*const T>::as_ref_unchecked`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_ref_unchecked) - [`<*mut T>::as_ref_unchecked`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_ref_unchecked-1) - [`<*mut T>::as_mut_unchecked`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_mut_unchecked) - [`Vec::push_mut`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.push_mut) - [`Vec::insert_mut`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.insert_mut) - [`VecDeque::push_front_mut`](https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.push_front_mut) - [`VecDeque::push_back_mut`](https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.push_back_mut) - [`VecDeque::insert_mut`](https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.insert_mut) - [`LinkedList::push_front_mut`](https://doc.rust-lang.org/stable/std/collections/struct.LinkedList.html#method.push_front_mut) - [`LinkedList::push_back_mut`](https://doc.rust-lang.org/stable/std/collections/struct.LinkedList.html#method.push_back_mut) - [`Layout::dangling_ptr`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.dangling_ptr) - [`Layout::repeat`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.repeat) - [`Layout::repeat_packed`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.repeat_packed) - [`Layout::extend_packed`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.extend_packed) These previously stable APIs are now stable in const contexts: - [`fmt::from_fn`](https://doc.rust-lang.org/stable/std/fmt/fn.from_fn.html) - [`ControlFlow::is_break`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.is_break) - [`ControlFlow::is_continue`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.is_continue) <a id="1.95-Rustdoc"></a> ## Rustdoc - [In search results, rank unstable items lower](rust-lang/rust#149460) - [Add new "hide deprecated items" setting in rustdoc](rust-lang/rust#151091) <a id="1.95-Compatibility-Notes"></a> ## Compatibility Notes - [Array coercions may now result in less inference constraints than before](rust-lang/rust#140283) - Importing `$crate` without renaming, i.e. `use $crate::{self};`, is now no longer permitted due to stricter error checking for `self` imports. - [const-eval: be more consistent in the behavior of padding during typed copies.](rust-lang/rust#148967) In very rare cases, this may cause compilation errors due to bytes from parts of a pointer ending up in the padding bytes of a `const` or `static`. - [A future-incompatibility warning lint `ambiguous_glob_imported_traits` is now reported when using an ambiguously glob imported trait](rust-lang/rust#149058) - [Check lifetime bounds of types mentioning only type parameters](rust-lang/rust#149389) - [Report more visibility-related ambiguous import errors](rust-lang/rust#149596) - [Deprecate `Eq::assert_receiver_is_total_eq` and emit future compatibility warnings on manual impls](rust-lang/rust#149978) - [powerpc64: Use the ELF ABI version set in target spec instead of guessing](rust-lang/rust#150468) (fixes the ELF ABI used by the OpenBSD target) - Matching on a `#[non_exhaustive]` enum [now reads the discriminant, even if the enum has only one variant](rust-lang/rust#150681). This can cause closures to capture values that they previously wouldn't. - `mut ref` and `mut ref mut` patterns, part of the unstable [Match Ergonomics 2024 RFC](rust-lang/rust#123076), were accidentally allowed on stable within struct pattern field shorthand. These patterns are now correctly feature-gated as unstable in this position. - [Add future-compatibility warning for derive helper attributes which conflict with built-in attributes](rust-lang/rust#151152) - [JSON target specs](https://doc.rust-lang.org/rustc/targets/custom.html) have been destabilized and now require `-Z unstable-options` to use. Previously, they could not be used without the standard library, which has no stable build mechanism. In preparation for the `build-std` project adding that support, JSON target specs are being proactively gated to ensure they remain unstable even if `build-std` is stabilized. Cargo now includes the `-Z json-target-spec` CLI flag to automatically pass `-Z unstable-options` to the compiler when needed. See [#​150151](rust-lang/rust#150151), [#​151534](rust-lang/rust#150151), and [rust-lang/cargo#16557](rust-lang/cargo#16557). - [The arguments of `#[feature]` attributes on invalid targets are now checked](rust-lang/rust#153764) <a id="1.95-Internal-Changes"></a> ## Internal Changes These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. - [Update to LLVM 22](rust-lang/rust#150722) ### [`v1.94.1`](https://github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1941-2026-03-26) [Compare Source](rust-lang/rust@1.94.0...1.94.1) \=========================== <a id="1.94.1"></a> - [Fix `std::thread::spawn` on wasm32-wasip1-threads](rust-lang/rust#153634) - [Remove new methods added to `std::os::windows::fs::OpenOptionsExt`](rust-lang/rust#153491) The new methods were unstable, but the trait itself is not sealed and so cannot be extended with non-default methods. - [Clippy: fix ICE in `match_same_arms`](rust-lang/rust-clippy#16685) - [Cargo: update tar to 0.4.45](rust-lang/cargo#16769) This resolves CVE-2026-33055 and CVE-2026-33056. Users of crates.io are not affected. See [blog](https://blog.rust-lang.org/2026/03/21/cve-2026-33056/) for more details. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/towonel/pulls/4
Fixes #136420.
If the expectation of array element is a type variable, we should avoid resolving it to the first element's type and wait until LUB coercion is completed.
We create a free type variable instead which is only used in this
CoerceMany.check_expr_matchandcheck_expr_ifwhereCoerceManyis also used do the same.FCP Proposal:
Remaining inconsistency with
ifandmatch(#145048):The typeck of array always uses the element coercion target type as the expectation of element exprs while
ifandmatchuseNoExpectationif the expected type is an infer var.This causes that array doesn't support nested coercion.
But we can't simply change this behavior to be the same as
ifandmatchsince many code depends on using the first element's type as expectation.