Skip to content

incorrect resolutions for type dependent paths in struct expression #98711

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

Open
lcnr opened this issue Jun 30, 2022 · 1 comment
Open

incorrect resolutions for type dependent paths in struct expression #98711

lcnr opened this issue Jun 30, 2022 · 1 comment
Labels
A-associated-items Area: Associated items (types, constants & functions) C-cleanup Category: PRs that clean code up or issues documenting cleanup. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@lcnr
Copy link
Contributor

lcnr commented Jun 30, 2022

trait Foo: Sized {
    type Output;

    fn func() -> Self;
}

struct Type<T> { value: T }

impl<T: Default> Foo for Type<T> {
    type Output = Self;

    fn func() -> Self {
        Self::Output { value: Default::default() }
    }
}

stores the following resolution for Self::Output via fn write_resolution:

Ok((AssocTy, DefId(0:4 ~ test1[f74d]::Foo::Output)))

the node_substs for Self::Output are however empty. This makes the stored resolution completely useless as there isn't really a way to go from Foo::Output to Type<T>::Output which is what we actually need.

We should probably store <Foo as Type<T>>::Output instead. This happens here

QPath::TypeRelative(ref qself, ref segment) => {
let ty = self.to_ty(qself);
let result = <dyn AstConv<'_>>::associated_path_to_ty(
self, hir_id, path_span, ty, qself, segment, true,
);
let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
let result = result.map(|(_, kind, def_id)| (kind, def_id));
// Write back the new resolution.
self.write_resolution(hir_id, result);
(result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty)
}

@lcnr lcnr added C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 30, 2022
@lcnr lcnr added the A-associated-items Area: Associated items (types, constants & functions) label Jun 30, 2022
@lcnr
Copy link
Contributor Author

lcnr commented Jul 1, 2022

this is needed to resolve the following fixme

// FIXME(#98711): Ideally we would also deal with type relative
// paths here, even if that is quite rare.
//
// See the `need_type_info/expr-struct-type-relative-gat.rs` test
// for an example where that would be needed.
//
// However, the `type_dependent_def_id` for `Self::Output` in an
// impl is currently the `DefId` of `Output` in the trait definition
// which makes this somewhat difficult and prevents us from just
// using `self.path_inferred_subst_iter` here.
hir::ExprKind::Struct(&hir::QPath::Resolved(_self_ty, path), _, _) => {
if let Some(ty) = self.opt_node_type(expr.hir_id) {
if let ty::Adt(_, substs) = ty.kind() {
return Box::new(self.resolved_path_inferred_subst_iter(path, substs));
}
}
}

@lcnr lcnr added the C-cleanup Category: PRs that clean code up or issues documenting cleanup. label Nov 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) C-cleanup Category: PRs that clean code up or issues documenting cleanup. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

1 participant