You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Rust beta: "cannot infer type" when compiling bottom crate #96074
Not sure who is correct here, or if this is expected: I just compiled the bottom crate version 0.6.8. This worked with the stable compiler, but failed with the current beta. The error message is the following:
error[E0283]: type annotations needed
--> src/canvas/dialogs/dd_dialog.rs:385:22
|
380 | / if app_state.dd_err.is_some() {
381 | | vec![Constraint::Percentage(100)]
382 | | } else {
383 | | vec![Constraint::Min(3), Constraint::Length(btn_height)]
384 | | }
385 | | .as_ref(),
| |______________________^^^^^^_- this method call resolves to `&T`
| |
| cannot infer type for type parameter `T` declared on the trait `AsRef`
|
= note: multiple `impl`s satisfying `Vec<Constraint>: AsRef<_>` found in the `alloc` crate:
- impl<T, A> AsRef<Vec<T, A>> for Vec<T, A>
where A: Allocator;
- impl<T, A> AsRef<[T]> for Vec<T, A>
where A: Allocator;
error[E0283]: type annotations needed
--> src/canvas.rs:630:59
|
630 | .constraints(self.row_constraints.as_ref())
| ---------------------^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: multiple `impl`s satisfying `Vec<Constraint>: AsRef<_>` found in the `alloc` crate:
- impl<T, A> AsRef<Vec<T, A>> for Vec<T, A>
where A: Allocator;
- impl<T, A> AsRef<[T]> for Vec<T, A>
where A: Allocator;
For more information about this error, try `rustc --explain E0283`.
error: could not compile `bottom` due to 2 previous errors
For T-libs-api: I don't expect that we would choose to revert this. @rust-lang/libs-api
However it's not clear to me what type inference limitation makes the type unable to be inferred. Using the minimal repro from @ehuss, we have:
constraints(vec.as_ref());
Rustc can see that .as_ref() refers to core::convert::AsRef<T>::as_ref because there is no as_ref inherent method on Vec or any of the types it transitively derefs to, and AsRef is the only trait in scope with an as_ref method. The signature of AsRef::as_ref is fn as_ref(&self) -> &T and therefore the type of vec.as_ref() is &T for some T, as long as Vec<Constraint>: AsRef<T>.
The possibilities for Vec<Constraint>: AsRef<T> are T = [Constraint] and T = Vec<Constraint>.
Then it sees calling constraints::<&T> requires &T: Into<Vec<Constraint>> due to the where-clause. Previously this was satisfiable only by T = [Constraint] whereas after #95098 it's also satisfiable by T = [Constraint; N].
Is it computationally hard to deduce from this that T = [Constraint]? As someone who doesn't know the type inference implementation in detail, my impression is this seems in line with inference that rustc is able to do successfully in other situations.
However it's not clear to me what type inference limitation makes the type unable to be inferred. Using the minimal repro from @ehuss, we have:
I recall some special cases in candidate assembly for allowing inference to continue when there is only one unambiguous impl, if I had to guess I'd say this is the same issue as #90904.
I'm trying to find the special case, I think this might be it but I'm not sure:
Sadly I don't understand this well enough either to really understand whats going on. I think there's some rule in the compiler (maybe the bit above) that lets the ambiguous type parameter for AsRef to be inferred off of the type of the single candidate for From when there's only one, but as soon as you have two, even if only one of them is actually applicable, it ends up erroring out earlier and never uses the From impls to attempt to select an AsRef impl.
I think making inference even 'smarter' is just going to lead to more code that implicitly relies on certain impls not existing, which will ultimately prohibit more impls from being added because some ambiguities just cannot be resolved cleanly.
I would much rather see existing code that relies on there's-only-one-impl-for cleverness start raising future-incompat errors. Maybe we could even have impl Add<char> for String and friends at some point then.
Reacted by lcnr, Jane Losare-Lusby, Esteban Kuber, scottmcm and Ali MJ Al-Nasrawy
Activity
ehuss commentedon Apr 15, 2022
This is almost certainly caused by #95098. cc @shepmaster
A smaller repro:
dtolnay commentedon Apr 16, 2022
This bisects to 93313d1, so indeed #95098.
apiraino commentedon Apr 20, 2022
Assigning priority as discussed in the Zulip thread of the Prioritization Working Group.
@rustbot label -I-prioritize +P-high
pnkfelix commentedon Apr 21, 2022
based on the injection point being #95098, isn't this a T-libs-api issue, not a T-compiler issue?
Switching tags under that assumption.
@rustbot label: -T-compiler +T-libs-api
dtolnay commentedon Apr 21, 2022
For T-libs-api: I don't expect that we would choose to revert this. @rust-lang/libs-api
However it's not clear to me what type inference limitation makes the type unable to be inferred. Using the minimal repro from @ehuss, we have:
Rustc can see that
.as_ref()refers tocore::convert::AsRef<T>::as_refbecause there is noas_refinherent method onVecor any of the types it transitively derefs to, andAsRefis the only trait in scope with anas_refmethod. The signature ofAsRef::as_refisfn as_ref(&self) -> &Tand therefore the type ofvec.as_ref()is&Tfor someT, as long asVec<Constraint>: AsRef<T>.The possibilities for
Vec<Constraint>: AsRef<T>areT = [Constraint]andT = Vec<Constraint>.Then it sees calling
constraints::<&T>requires&T: Into<Vec<Constraint>>due to thewhere-clause. Previously this was satisfiable only byT = [Constraint]whereas after #95098 it's also satisfiable byT = [Constraint; N].Is it computationally hard to deduce from this that
T = [Constraint]? As someone who doesn't know the type inference implementation in detail, my impression is this seems in line with inference that rustc is able to do successfully in other situations.yaahc commentedon Apr 21, 2022
I recall some special cases in candidate assembly for allowing inference to continue when there is only one unambiguous impl, if I had to guess I'd say this is the same issue as #90904.
I'm trying to find the special case, I think this might be it but I'm not sure:
rust/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
Lines 140 to 156 in b04c532
Sadly I don't understand this well enough either to really understand whats going on. I think there's some rule in the compiler (maybe the bit above) that lets the ambiguous type parameter for
AsRefto be inferred off of the type of the single candidate forFromwhen there's only one, but as soon as you have two, even if only one of them is actually applicable, it ends up erroring out earlier and never uses theFromimpls to attempt to select anAsRefimpl.20 remaining items
bug: change as_ref calls so rust beta 1.61 builds
bug: change as_ref calls so rust beta 1.61 builds
bug: change as_ref calls so rust beta 1.61 builds
bug: change as_ref() to build in Rust beta 1.61.0 (#711)
jplatte commentedon Apr 28, 2022
I think making inference even 'smarter' is just going to lead to more code that implicitly relies on certain impls not existing, which will ultimately prohibit more impls from being added because some ambiguities just cannot be resolved cleanly.
I would much rather see existing code that relies on there's-only-one-impl-for cleverness start raising future-incompat errors. Maybe we could even have
impl Add<char> for Stringand friends at some point then.pnkfelix commentedon May 5, 2022
Visiting this issue during T-compiler triage meeting.
We believe the beta backport of PR #96489 addresses the issue this was nominated for.
@rustbot label: -I-nominated-compiler
apiraino commentedon May 5, 2022
:)
@rustbot label -I-compiler-nominated
Mark-Simulacrum commentedon May 15, 2022
Clearing milestone as we have landed #96489 on master (1.62+) and backported it to 1.61, so this is no longer a regression.
Enselic commentedon Mar 16, 2024
Triage: The revert is done and consensus seems to be to not change inference. Closing.