11107: Fix generic type substitution in impl trait with assoc type r=pnevyk a=pnevyk

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 -> ...`.

Co-authored-by: Petr Nevyhoštěný <petr.nevyhosteny@gmail.com>
This commit is contained in:
bors[bot] 2022-01-08 09:05:09 +00:00 committed by GitHub
commit c17db9fa53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 468 additions and 11 deletions

View file

@ -188,6 +188,14 @@ pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment {
ast_from_text(&format!("use {};", name_ref))
}
pub fn path_segment_ty(type_ref: ast::Type, trait_ref: Option<ast::PathType>) -> ast::PathSegment {
let text = match trait_ref {
Some(trait_ref) => format!("fn f(x: <{} as {}>) {{}}", type_ref, trait_ref),
None => format!("fn f(x: <{}>) {{}}", type_ref),
};
ast_from_text(&text)
}
pub fn path_segment_self() -> ast::PathSegment {
ast_from_text("use self;")
}
@ -218,9 +226,9 @@ pub fn path_from_segments(
) -> ast::Path {
let segments = segments.into_iter().map(|it| it.syntax().clone()).join("::");
ast_from_text(&if is_abs {
format!("use ::{};", segments)
format!("fn f(x: ::{}) {{}}", segments)
} else {
format!("use {};", segments)
format!("fn f(x: {}) {{}}", segments)
})
}