Skip to content
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

Fix generic type substitution in impl trait with assoc type #11107

Merged
merged 2 commits into from
Jan 8, 2022

Conversation

pnevyk
Copy link
Contributor

@pnevyk pnevyk commented Dec 23, 2021

Fixes #11045

The path transform now detects if a type parameter that is being substituted has an associated type. In that case it is necessary (or safe in general case) to fully qualify the substitution with a trait which the associated type belongs to.

This PR also fixes the previous wrong behavior of the substitution that could create an invalid tree PATH_TYPE -> PATH_TYPE -> ....

crates/ide_db/src/path_transform.rs Show resolved Hide resolved
subst.clone_subtree().clone_for_update().syntax(),
);
} else {
ted::replace(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even without this else branch, all tests pass. I am wondering in which scenarios is this code executed and if that's what is desired.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only case where I can see this happening is in Patterns using the path I believe, so PathPat, or the path in TupleStructPat etc, might be good to check that.

Copy link
Contributor Author

@pnevyk pnevyk Jan 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't come up with a code snippet that would exercise this branch. It would need to:

  • use a generic type parameter, because this part of code deals with hir::PathResolution::TypeParam(tp) substitution
  • must not use associated type/constant, because this case is handled by if let Some(parent) = ast::Path::cast(parent.clone()) above
  • must be in a pattern or path expression

Therefore, as far as I can tell, the path here will always be a type (having PathType as parent) or will have an associated type/constant (having Path as parent). And so this else branch seems unreachable to me and can be removed.

Nevertheless, thanks to playing with path patterns and expressions, I discovered that handling associated constants was missing in my fix. It works now (a710b87).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't hurt leaving the branch either so I think keeping it is fine, either way works.

PR lgtm then, thanks!
bors d+

Comment on lines +198 to +206
if let hir::ModuleDef::Trait(_) = def {
if matches!(path.segment()?.kind()?, ast::PathSegmentKind::Type { .. }) {
// `speculative_resolve` resolves segments like `<T as
// Trait>` into `Trait`, but just the trait name should
// not be used as the replacement of the original
// segment.
return None;
}
}
Copy link
Contributor Author

@pnevyk pnevyk Dec 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels hacky. But without this exception, the following thing happens:

pub trait Behavior<T: Types> {
    fn reproduce(&self, foo: <T as Types>::Foo);
}

pub struct Impl;

impl Behavior<u32> for Impl { $0 }

// -->

impl Behavior<u32> for Impl {
    fn reproduce(&self, foo: Types::Foo) {
        ${0:todo!()}
    }
}

crates/syntax/src/ast/make.rs Show resolved Hide resolved
@Veykril Veykril self-assigned this Jan 3, 2022
@bors
Copy link
Contributor

bors bot commented Jan 7, 2022

✌️ pnevyk can now approve this pull request. To approve and merge a pull request, simply reply with bors r+. More detailed instructions are available here.

@pnevyk
Copy link
Contributor Author

pnevyk commented Jan 8, 2022

bors r+

@bors
Copy link
Contributor

bors bot commented Jan 8, 2022

@bors bors bot merged commit c17db9f into rust-lang:master Jan 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

"Implement missing members" generates trait name instead of associated types if these have the same name
2 participants