Skip to content

Commit 9ce7630

Browse files
committed
Generalize 'impl'/'dyn' trait
* Trait objects and impl traits are now accepted anywhere in types. * Added some tests for foreign types and impl/dyn trait
1 parent 836427d commit 9ce7630

File tree

4 files changed

+14
-25
lines changed

4 files changed

+14
-25
lines changed

sample-sources/items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ mod bar {
5353
}
5454

5555
trait Foo = Bar + Baz;
56+
trait Foo<'a,N> = Bar<'a,N> + Baz + 'a;
5657

5758
fn foo<T: ?Sized>(x: &T) { }
5859
struct Foo<T: Send + ?Sized + Sync> { field: Box<T> }

sample-sources/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fn main() {
1717
let x: T;
1818
let x: <Vec<T> as SomeTrait>::SomeType;
1919
let x: Bound1 + Bound2 + 'static;
20+
let x: impl Bound1 + Bound2 + 'static;
2021
let x: dyn Bound1 + Bound2 + 'static;
2122
let x: (i32);
2223
let x: typeof(1i32);

src/Language/Rust/Parser/Internal.y

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ import qualified Data.List.NonEmpty as N
7272
-- in order to document the parsers, we have to alias them
7373
%name parseLit lit
7474
%name parseAttr export_attribute
75-
%name parseTy export_ty
75+
%name parseTy ty
7676
%name parsePat pat
7777
%name parseStmt stmt
7878
%name parseExpr expr
@@ -208,8 +208,6 @@ import qualified Data.List.NonEmpty as N
208208
where { Spanned (IdentTok "where") _ }
209209
while { Spanned (IdentTok "while") _ }
210210
do { Spanned (IdentTok "do") _ }
211-
yield { Spanned (IdentTok "yield") _ }
212-
dyn { Spanned (IdentTok "dyn") _ }
213211

214212
-- Keywords reserved for future use
215213
abstract { Spanned (IdentTok "abstract") _ }
@@ -232,6 +230,8 @@ import qualified Data.List.NonEmpty as N
232230
union { Spanned (IdentTok "union") _ }
233231
catch { Spanned (IdentTok "catch") _ }
234232
auto { Spanned (IdentTok "auto") _ }
233+
yield { Spanned (IdentTok "yield") _ }
234+
dyn { Spanned (IdentTok "dyn") _ }
235235

236236
-- Comments
237237
outerDoc { Spanned (Doc _ Outer _) _ }
@@ -278,7 +278,7 @@ import qualified Data.List.NonEmpty as N
278278
%nonassoc mut DEF EQ '::'
279279

280280
-- These are all identifiers of sorts ('union' and 'default' are "weak" keywords)
281-
%nonassoc IDENT ntIdent default union catch self auto
281+
%nonassoc IDENT ntIdent default union catch self auto dyn
282282

283283
-- These are all very low precedence unary operators
284284
%nonassoc box return yield break continue IMPLTRAIT LAMBDA
@@ -630,6 +630,8 @@ no_for_ty_prim :: { Ty Span }
630630
| '[' ty ';' expr ']' { Array $2 $4 ($1 # $>) }
631631
| '?' trait_ref { TraitObject [TraitTyParamBound (PolyTraitRef [] $2 (spanOf $2)) Maybe ($1 # $2)] ($1 # $2) }
632632
| '?' for_lts trait_ref { TraitObject [TraitTyParamBound (PolyTraitRef (unspan $2) $3 ($2 # $3)) Maybe ($1 # $3)] ($1 # $3) }
633+
| impl sep_by1(ty_param_bound_mod,'+') %prec IMPLTRAIT { ImplTrait (toNonEmpty $2) ($1 # $2) }
634+
| dyn sep_by1(ty_param_bound_mod,'+') %prec IMPLTRAIT { TraitObject (toNonEmpty $2) ($1 # $2) }
633635

634636
-- All (non-sum) types starting with a 'for'
635637
for_ty_no_plus :: { Ty Span }
@@ -642,10 +644,6 @@ for_ty_no_plus :: { Ty Span }
642644
TraitObject [TraitTyParamBound poly None ($1 # $2)] ($1 # $2)
643645
}
644646

645-
impl_ty :: { Ty Span }
646-
: impl sep_by1(ty_param_bound_mod,'+') %prec IMPLTRAIT { ImplTrait (toNonEmpty $2) ($1 # $2) }
647-
-- | dyn sep_by1(ty_param_bound_mod,'+') %prec IMPLTRAIT { TraitObject (toNonEmpty $2) ($1 # $2) }
648-
649647
-- An optional lifetime followed by an optional mutability
650648
lifetime_mut :: { (Maybe (Lifetime Span), Mutability) }
651649
: lifetime mut { (Just $1, Mutable) }
@@ -697,11 +695,8 @@ abi :: { Abi }
697695
| {- empty -} { C }
698696

699697
-- parse_ret_ty
700-
-- Note that impl traits are still at RFC stage - they may eventually become accepted in more places
701-
-- than just return types.
702698
ret_ty :: { Maybe (Ty Span) }
703699
: '->' ty_no_plus { Just $2 }
704-
| '->' impl_ty { Just $2 }
705700
| {- empty -} { Nothing }
706701

707702
-- parse_poly_trait_ref()
@@ -1617,7 +1612,6 @@ token :: { Spanned Token }
16171612
| pub { $1 }
16181613
| ref { $1 }
16191614
| return { $1 }
1620-
| yield { $1 }
16211615
| Self { $1 }
16221616
| self { $1 }
16231617
| static { $1 }
@@ -1651,6 +1645,8 @@ token :: { Spanned Token }
16511645
| union { $1 }
16521646
| catch { $1 }
16531647
| auto { $1 }
1648+
| yield { $1 }
1649+
| dyn { $1 }
16541650
-- Comments
16551651
| outerDoc { $1 }
16561652
| innerDoc { $1 }
@@ -1678,12 +1674,6 @@ export_block :: { Block Span }
16781674
| safety '{' '}' { Block [] (unspan $1) ($1 # $2 # $>) }
16791675
| safety '{' stmts_possibly_no_semi '}' { Block [ s | Just s <- $3 ] (unspan $1) ($1 # $2 # $>) }
16801676

1681-
-- Any type, including trait types with plus and impl trait types
1682-
export_ty :: { Ty Span }
1683-
: ty { $1 }
1684-
| impl_ty { $1 }
1685-
1686-
16871677
{
16881678
-- | Parser for literals.
16891679
parseLit :: P (Lit Span)

src/Language/Rust/Pretty/Resolve.hs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -375,15 +375,13 @@ data TyType
375375
| NoSumType -- ^ Any type except for 'TraitObject' with a '+'
376376
| PrimParenType -- ^ Types not starting with '<' or '(', or paren types with no sum types inside
377377
| NoForType -- ^ Non-sum types not starting with a 'for'
378-
| ReturnType -- ^ Type in a return type position
379378

380379
-- | Resolve a given type, and a constraint on it (see the parser 'Internal.y' for more details on
381380
-- these cases).
382381
resolveTy :: (Typeable a, Monoid a) => TyType -> Ty a -> ResolveM (Ty a)
383382
-- TraitObject
384383
resolveTy NoSumType o@(TraitObject b _) | length b > 1 = scope o (correct "added parens around trait object type" *> resolveTy NoSumType (ParenTy o mempty))
385384
resolveTy NoForType o@TraitObject{} = scope o (correct "added parens around trait object type" *> resolveTy NoForType (ParenTy o mempty))
386-
resolveTy ReturnType o@TraitObject{} = scope o (correct "added parens around trait object type" *> resolveTy ReturnType (ParenTy o mempty))
387385
resolveTy _ o@(TraitObject bds@(TraitTyParamBound{} :| _) x)
388386
= scope o (TraitObject <$> traverse (resolveTyParamBound ModBound) bds <*> pure x)
389387
resolveTy _ o@TraitObject{} = scope o (err o "first bound in trait object should be a trait bound")
@@ -394,8 +392,7 @@ resolveTy _ p@(ParenTy ty' x) = scope p (ParenTy <$> resolveTy AnyTy
394392
resolveTy PrimParenType t@TupTy{} = scope t (correct "added parens around tuple type" *> resolveTy PrimParenType (ParenTy t mempty))
395393
resolveTy _ t@(TupTy tys x) = scope t (TupTy <$> traverse (resolveTy AnyType) tys <*> pure x)
396394
-- ImplTrait
397-
resolveTy ReturnType i@(ImplTrait bds x) = scope i (ImplTrait <$> traverse (resolveTyParamBound ModBound) bds <*> pure x)
398-
resolveTy _ i@ImplTrait{} = scope i $ err i "impl trait types are only allowed as return types"
395+
resolveTy _ i@(ImplTrait bds x) = scope i (ImplTrait <$> traverse (resolveTyParamBound ModBound) bds <*> pure x)
399396
-- PathTy
400397
resolveTy PrimParenType p@(PathTy (Just _) _ _) = scope p (correct "added parents around path type" *> resolveTy PrimParenType (ParenTy p mempty))
401398
resolveTy _ p@(PathTy q p'@(Path _ s _) x) = scope p $
@@ -435,7 +432,7 @@ resolveFnDecl :: (Typeable a, Monoid a) => FnDeclType -> ArgType -> FnDecl a ->
435432
resolveFnDecl fn _ f@(FnDecl (s : _) _ _ _) | isSelfArg s && fn /= AllowSelf = scope f (err f "self argument is not allowed in this function declaration")
436433
resolveFnDecl _ _ f@(FnDecl (_ : as) _ _ _) | any isSelfArg as = scope f (err f "self arguments must always be the first arguments")
437434
resolveFnDecl fn _ f@(FnDecl _ _ True _) | fn /= VarNoSelf = scope f (err f "this function declaration cannot be variadic")
438-
resolveFnDecl _ at f@(FnDecl as o v x) = scope f (FnDecl <$> traverse (resolveArg at) as <*> traverse (resolveTy ReturnType) o <*> pure v <*> pure x)
435+
resolveFnDecl _ at f@(FnDecl as o v x) = scope f (FnDecl <$> traverse (resolveArg at) as <*> traverse (resolveTy AnyType) o <*> pure v <*> pure x)
439436

440437
-- | Check whether an argument is one of the "self" forms
441438
isSelfArg :: Arg a -> Bool
@@ -1006,7 +1003,7 @@ isBlockLike BlockExpr{} = True
10061003
isBlockLike _ = False
10071004

10081005
resolveLbl :: Typeable a => Label a -> ResolveM (Label a)
1009-
resolveLbl l@(Label n x) = scope l (resolveIdent (mkIdent n) *> pure l)
1006+
resolveLbl l@(Label n _) = scope l (resolveIdent (mkIdent n) *> pure l)
10101007

10111008
-- | Wrap an expression in parens if the condition given holds
10121009
parenE :: (Typeable a, Monoid a) => Bool -> ResolveM (Expr a) -> ResolveM (Expr a)
@@ -1244,7 +1241,7 @@ resolveForeignItem _ f@(ForeignStatic as v i t m x) = scope f $ do
12441241
i' <- resolveIdent i
12451242
t' <- resolveTy AnyType t
12461243
pure (ForeignStatic as' v' i' t' m x)
1247-
resolveForeignItem _ f@(ForeignTy as v i _) = scope f $ do
1244+
resolveForeignItem _ f@(ForeignTy as v i x) = scope f $ do
12481245
as' <- traverse (resolveAttr OuterAttr) as
12491246
v' <- resolveVisibility v
12501247
i' <- resolveIdent i

0 commit comments

Comments
 (0)