-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Confusing/incorrect error message with incoherent implementations and async blocks #67651
Comments
@Centril said they'd look into minimizing this further. |
Also assigning @nikomatsakis to look into this along with #66312. |
Reduced: trait From {
fn from();
}
impl From for () {
fn from() {}
}
impl From for () {
fn from() {}
}
fn af() -> impl core::future::Future<Output = ()> {
async move { From::from() }
}
/*
fn f() -> () {
From::from()
}
*/ |
I've been investigating this. I'm not sure I understand yet what is going on, but I'm going to leave a few breadcrumbs as I go. To start, I think part of the problem lies on this line: rust/src/librustc_typeck/collect.rs Line 1395 in ed6468d
Specifically what is happening here is that we are executing the rust/src/librustc_typeck/collect.rs Lines 1393 to 1400 in ed6468d
Here, on lines 1398-1399, you can see that for a closure we create a type with "identity substitutions", which means a closure type like (I see that opaque types also behave differently; it seems like (I'm going to look a bit more at why generators behave this way now, not obvious to me that they must -- @Zoxc may have some details here?) UPDATE: Based on some exploration of git history, this line goes way back to the original gen branch at least. |
OK, I can confirm that the "naive fix" causes downstream errors, I haven't investigated those much yet: @@ -1392,12 +1392,12 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
Node::Field(field) => icx.to_ty(&field.ty),
Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(.., gen), .. }) => {
- if gen.is_some() {
- return tcx.typeck_tables_of(def_id).node_type(hir_id);
- }
-
let substs = InternalSubsts::identity_for_item(tcx, def_id);
- tcx.mk_closure(def_id, substs)
+ if let Some(movability) = gen {
+ tcx.mk_generator(def_id, substs, movability)
+ } else {
+ tcx.mk_closure(def_id, substs)
+ }
}
Node::AnonConst(_) => { I suspect they can be fixed though |
@nikomatsakis Generator types contain the types of the values inside which are live across a yield statement, that is why |
@Zoxc I don't think that's sufficient reason by itself. Closure types also contain details that result from inference (e.g., the types that their upvars use), but |
We hit an instance of this in Fuchsia. Minimal example: (playground) mod queue {
pub trait TryMerge {}
impl TryMerge for () {}
pub fn work_queue<W, C, WF>(work_fn: W)
where
W: Fn(C) -> WF,
C: TryMerge,
{}
}
impl queue::TryMerge for () {}
fn main() {
queue::work_queue(move |_: ()| {
async {}
})
} Gives
instead of the expected error, which is what you get if you remove the async block:
cc @JakeEhrlich |
Make the `type_of` return a generic type for generators Fixes rust-lang#67651. r? @nikomatsakis
Make the `type_of` return a generic type for generators Fixes rust-lang#67651. r? @nikomatsakis
Make the `type_of` return a generic type for generators Fixes rust-lang#67651. r? @nikomatsakis
Make the `type_of` return a generic type for generators Fixes rust-lang#67651. r? @nikomatsakis
This fails with
type annotations required: cannot resolve Error: std::convert::From<Error>
(E0283) instead of the expectedconflicting implementations of trait std::convert::From<Error> for type Error
(E0119). Changingfail
toi.e. eliminating the async block leads to the expected error message being produced.
playground demonstration
The text was updated successfully, but these errors were encountered: