Skip to content

Commit

Permalink
fix: handle GAT types in impls with self bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
calebcartwright committed Aug 7, 2021
1 parent 8cbee56 commit fefb542
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 87 deletions.
82 changes: 26 additions & 56 deletions src/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1497,7 +1497,7 @@ fn format_tuple_struct(
Some(result)
}

fn rewrite_type<R: Rewrite>(
pub(crate) fn rewrite_type<R: Rewrite>(
context: &RewriteContext<'_>,
indent: Indent,
ident: symbol::Ident,
Expand Down Expand Up @@ -1841,29 +1841,6 @@ fn rewrite_static(
Some(format!("{}{};", prefix, ty_str))
}
}

pub(crate) fn rewrite_type_alias(
ident: symbol::Ident,
ty_opt: Option<&ptr::P<ast::Ty>>,
generics: &ast::Generics,
generic_bounds_opt: Option<&ast::GenericBounds>,
context: &RewriteContext<'_>,
indent: Indent,
vis: &ast::Visibility,
span: Span,
) -> Option<String> {
rewrite_type(
context,
indent,
ident,
vis,
generics,
generic_bounds_opt,
ty_opt,
span,
)
}

struct OpaqueType<'a> {
bounds: &'a ast::GenericBounds,
}
Expand All @@ -1877,32 +1854,7 @@ impl<'a> Rewrite for OpaqueType<'a> {
}
}

pub(crate) fn rewrite_opaque_impl_type(
context: &RewriteContext<'_>,
ident: symbol::Ident,
generics: &ast::Generics,
generic_bounds: &ast::GenericBounds,
indent: Indent,
) -> Option<String> {
let ident_str = rewrite_ident(context, ident);
// 5 = "type "
let generics_shape = Shape::indented(indent, context.config).offset_left(5)?;
let generics_str = rewrite_generics(context, ident_str, generics, generics_shape)?;
let prefix = format!("type {} =", generics_str);
let rhs = OpaqueType {
bounds: generic_bounds,
};

rewrite_assign_rhs(
context,
&prefix,
&rhs,
Shape::indented(indent, context.config).sub_width(1)?,
)
.map(|s| s + ";")
}

pub(crate) fn rewrite_associated_impl_type(
pub(crate) fn rewrite_impl_type(
ident: symbol::Ident,
vis: &ast::Visibility,
defaultness: ast::Defaultness,
Expand All @@ -1912,7 +1864,25 @@ pub(crate) fn rewrite_associated_impl_type(
indent: Indent,
span: Span,
) -> Option<String> {
let result = rewrite_type_alias(ident, ty_opt, generics, None, context, indent, vis, span)?;
// Opaque type
let result = if let Some(rustc_ast::ast::Ty {
kind: ast::TyKind::ImplTrait(_, ref bounds),
..
}) = ty_opt.map(|t| &**t)
{
rewrite_type(
context,
indent,
ident,
&DEFAULT_VISIBILITY,
generics,
None,
Some(&OpaqueType { bounds }),
span,
)
} else {
rewrite_type(context, indent, ident, vis, generics, None, ty_opt, span)
}?;

match defaultness {
ast::Defaultness::Default(..) => Some(format!("default {}", result)),
Expand Down Expand Up @@ -3164,14 +3134,14 @@ impl Rewrite for ast::ForeignItem {
ast::ForeignItemKind::TyAlias(ref ty_alias_kind) => {
let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) =
**ty_alias_kind;
rewrite_type_alias(
self.ident,
type_default.as_ref(),
generics,
Some(generic_bounds),
rewrite_type(
&context,
shape.indent,
self.ident,
&self.vis,
generics,
Some(generic_bounds),
type_default.as_ref(),
self.span,
)
}
Expand Down
49 changes: 18 additions & 31 deletions src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ use crate::config::Version;
use crate::config::{BraceStyle, Config};
use crate::coverage::transform_missing_snippet;
use crate::items::{
format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item,
rewrite_associated_impl_type, rewrite_extern_crate, rewrite_opaque_impl_type,
rewrite_opaque_type, rewrite_type_alias, FnBraceStyle, FnSig, StaticParts, StructParts,
format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate,
rewrite_impl_type, rewrite_opaque_type, rewrite_type, FnBraceStyle, FnSig, StaticParts,
StructParts,
};
use crate::macros::{macro_style, rewrite_macro, rewrite_macro_def, MacroPosition};
use crate::modules::Module;
Expand Down Expand Up @@ -579,14 +579,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
**alias_kind;
match ty {
Some(ty) => {
let rewrite = rewrite_type_alias(
item.ident,
Some(&*ty),
generics,
Some(generic_bounds),
let rewrite = rewrite_type(
&self.get_context(),
self.block_indent,
item.ident,
&item.vis,
generics,
Some(generic_bounds),
Some(&*ty),
item.span,
);
self.push_rewrite(item.span, rewrite);
Expand Down Expand Up @@ -665,14 +665,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
ast::AssocItemKind::TyAlias(ref ty_alias_kind) => {
let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) =
**ty_alias_kind;
let rewrite = rewrite_type_alias(
ti.ident,
type_default.as_ref(),
generics,
Some(generic_bounds),
let rewrite = rewrite_type(
&self.get_context(),
self.block_indent,
ti.ident,
&ti.vis,
generics,
Some(generic_bounds),
type_default.as_ref(),
ti.span,
);
self.push_rewrite(ti.span, rewrite);
Expand Down Expand Up @@ -715,8 +715,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_impl_item(ii)),
ast::AssocItemKind::TyAlias(ref ty_alias_kind) => {
let ast::TyAliasKind(defaultness, ref generics, _, ref ty) = **ty_alias_kind;
let rewrite_associated = || {
rewrite_associated_impl_type(
self.push_rewrite(
ii.span,
rewrite_impl_type(
ii.ident,
&ii.vis,
defaultness,
Expand All @@ -725,22 +726,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
&self.get_context(),
self.block_indent,
ii.span,
)
};
let rewrite = match ty {
None => rewrite_associated(),
Some(ty) => match ty.kind {
ast::TyKind::ImplTrait(_, ref bounds) => rewrite_opaque_impl_type(
&self.get_context(),
ii.ident,
generics,
bounds,
self.block_indent,
),
_ => rewrite_associated(),
},
};
self.push_rewrite(ii.span, rewrite);
),
);
}
ast::AssocItemKind::MacCall(ref mac) => {
self.visit_mac(mac, Some(ii.ident), MacroPosition::Item);
Expand Down
6 changes: 6 additions & 0 deletions tests/source/issue_4911.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![feature(generic_associated_types)]
#![feature(min_type_alias_impl_trait)]

impl SomeTrait for SomeType {
type SomeGAT<'a> where Self: 'a = impl SomeOtherTrait;
}
9 changes: 9 additions & 0 deletions tests/target/issue_4911.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![feature(generic_associated_types)]
#![feature(min_type_alias_impl_trait)]

impl SomeTrait for SomeType {
type SomeGAT<'a>
where
Self: 'a,
= impl SomeOtherTrait;
}

0 comments on commit fefb542

Please sign in to comment.