-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Fix accidental type inference in array coercion #140283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
rustbot has assigned @petrochenkov. Use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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;
};
// I can't come up with an example of function return type for now.
} |
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 |
Fixes #136420.
If the expectation is a type variable, we should avoid resolving it to the first element's type.
We can create a free type variable instead which is only used in this
CoerceMany
.check_expr_match
whereCoerceMany
is also used does the same.