@@ -3347,8 +3347,32 @@ static FuncDecl *createAccessorFunc(SourceLoc DeclLoc, ParameterList *param,
3347
3347
}
3348
3348
3349
3349
if (Indices) {
3350
- Indices = Indices->clone (P->Context , ParameterList::Implicit);
3351
- ValueArgElements.append (Indices->begin (), Indices->end ());
3350
+ // Create parameter declarations corresponding to each of the
3351
+ // parameter declarations from the subscript declaration.
3352
+ for (ParamDecl *storageParam : *Indices) {
3353
+ // Clone the parameter. Do not clone the parameter type;
3354
+ // this will be filled in by the type-checker.
3355
+ auto accessorParam =
3356
+ new (P->Context ) ParamDecl (storageParam->getSpecifier (),
3357
+ storageParam->getSpecifierLoc (),
3358
+ storageParam->getArgumentNameLoc (),
3359
+ storageParam->getArgumentName (),
3360
+ storageParam->getNameLoc (),
3361
+ storageParam->getName (),
3362
+ Type (),
3363
+ P->CurDeclContext );
3364
+ accessorParam->setVariadic (storageParam->isVariadic ());
3365
+
3366
+ // The cloned parameter is implicit.
3367
+ accessorParam->setImplicit ();
3368
+
3369
+ // It has no default arguments; these will be always be taken
3370
+ // from the subscript declaration.
3371
+ accessorParam->setDefaultArgumentKind (DefaultArgumentKind::None);
3372
+
3373
+ ValueArgElements.push_back (accessorParam);
3374
+ }
3375
+
3352
3376
if (StartLoc.isInvalid ()) {
3353
3377
StartLoc = Indices->getStartLoc ();
3354
3378
EndLoc = Indices->getEndLoc ();
@@ -3370,82 +3394,9 @@ static FuncDecl *createAccessorFunc(SourceLoc DeclLoc, ParameterList *param,
3370
3394
// Add the "(value)" and subscript indices parameter clause.
3371
3395
Params.push_back (ValueArg);
3372
3396
3397
+ // The typechecker will always fill this in.
3373
3398
TypeLoc ReturnType;
3374
3399
3375
- // Getters return the value type.
3376
- if (Kind == AccessorKind::IsGetter) {
3377
- ReturnType = ElementTy.clone (P->Context );
3378
-
3379
- // Addressors return Unsafe{,Mutable}Pointer<T>, plus sometimes an
3380
- // owner or pinned owner.
3381
- } else if (Kind == AccessorKind::IsAddressor ||
3382
- Kind == AccessorKind::IsMutableAddressor) {
3383
-
3384
- // If we don't have a declared type, we will diagnose later,
3385
- // so skip this to avoid crashing.
3386
- if (ElementTy.getTypeRepr ()) {
3387
- // Construct "Unsafe{,Mutable}Pointer<T>".
3388
-
3389
- TypeRepr *args[] = { ElementTy.clone (P->Context ).getTypeRepr () };
3390
-
3391
- // FIXME: the fact that this could resolve in the local scope is dumb.
3392
- bool isMutable = (Kind == AccessorKind::IsMutableAddressor);
3393
- Identifier name = P->Context .getIdentifier (
3394
- isMutable ? " UnsafeMutablePointer" : " UnsafePointer" );
3395
-
3396
- TypeRepr *resultType =
3397
- new (P->Context ) GenericIdentTypeRepr (SourceLoc (), name,
3398
- P->Context .AllocateCopy (args),
3399
- SourceRange ());
3400
-
3401
- auto makeKnownType = [&](Type type) -> TypeRepr* {
3402
- return new (P->Context ) FixedTypeRepr (type, SourceLoc ());
3403
- };
3404
- auto makePairType = [&](TypeRepr *fst, TypeRepr *snd) -> TypeRepr* {
3405
- return TupleTypeRepr::create (P->Context , {fst, snd}, SourceRange ());
3406
- };
3407
-
3408
- switch (addressorKind) {
3409
- case AddressorKind::NotAddressor:
3410
- llvm_unreachable (" not an addressor!" );
3411
-
3412
- // For unsafe addressors, that's all we've got.
3413
- case AddressorKind::Unsafe:
3414
- break ;
3415
-
3416
- // For non-native owning addressors, the return type is actually
3417
- // (Unsafe{,Mutable}Pointer<T>, Builtin.UnknownObject)
3418
- case AddressorKind::Owning:
3419
- resultType = makePairType (resultType,
3420
- makeKnownType (P->Context .TheUnknownObjectType ));
3421
- break ;
3422
-
3423
- // For native owning addressors, the return type is actually
3424
- // (Unsafe{,Mutable}Pointer<T>, Builtin.NativeObject)
3425
- case AddressorKind::NativeOwning:
3426
- resultType = makePairType (resultType,
3427
- makeKnownType (P->Context .TheNativeObjectType ));
3428
- break ;
3429
-
3430
- // For native pinning addressors, the return type is actually
3431
- // (Unsafe{,Mutable}Pointer<T>, Builtin.NativeObject?)
3432
- case AddressorKind::NativePinning: {
3433
- auto optNativePtr = new (P->Context ) OptionalTypeRepr (
3434
- makeKnownType (P->Context .TheNativeObjectType ),
3435
- SourceLoc ());
3436
- resultType = makePairType (resultType, optNativePtr);
3437
- break ;
3438
- }
3439
- }
3440
-
3441
- ReturnType = resultType;
3442
- }
3443
-
3444
- // Everything else returns ().
3445
- } else {
3446
- ReturnType = TypeLoc::withoutLoc (TupleType::getEmpty (P->Context ));
3447
- }
3448
-
3449
3400
// Start the function.
3450
3401
auto *D = FuncDecl::create (P->Context , StaticLoc, StaticSpellingKind::None,
3451
3402
/* FIXME FuncLoc=*/ DeclLoc, Identifier (),
@@ -3489,8 +3440,7 @@ static FuncDecl *createAccessorFunc(SourceLoc DeclLoc, ParameterList *param,
3489
3440
3490
3441
static ParamDecl *
3491
3442
createSetterAccessorArgument (SourceLoc nameLoc, Identifier name,
3492
- TypeLoc elementTy, AccessorKind accessorKind,
3493
- Parser &P) {
3443
+ AccessorKind accessorKind, Parser &P) {
3494
3444
// Add the parameter. If no name was specified, the name defaults to
3495
3445
// 'value'.
3496
3446
bool isNameImplicit = name.empty ();
@@ -3507,8 +3457,6 @@ createSetterAccessorArgument(SourceLoc nameLoc, Identifier name,
3507
3457
if (isNameImplicit)
3508
3458
result->setImplicit ();
3509
3459
3510
- result->getTypeLoc () = elementTy.clone (P.Context );
3511
-
3512
3460
// AST Walker shouldn't go into the type recursively.
3513
3461
result->setIsTypeLocImplicit (true );
3514
3462
return result;
@@ -3518,7 +3466,7 @@ createSetterAccessorArgument(SourceLoc nameLoc, Identifier name,
3518
3466
// / parameter list to represent the spelled argument or return null if none is
3519
3467
// / present.
3520
3468
static ParameterList *
3521
- parseOptionalAccessorArgument (SourceLoc SpecifierLoc, TypeLoc ElementTy,
3469
+ parseOptionalAccessorArgument (SourceLoc SpecifierLoc,
3522
3470
Parser &P, AccessorKind Kind) {
3523
3471
// 'set' and 'willSet' have a (value) parameter, 'didSet' takes an (oldValue)
3524
3472
// parameter and 'get' and always takes a () parameter.
@@ -3556,7 +3504,7 @@ parseOptionalAccessorArgument(SourceLoc SpecifierLoc, TypeLoc ElementTy,
3556
3504
}
3557
3505
3558
3506
if (Name.empty ()) NameLoc = SpecifierLoc;
3559
- auto param = createSetterAccessorArgument (NameLoc, Name, ElementTy, Kind, P);
3507
+ auto param = createSetterAccessorArgument (NameLoc, Name, Kind, P);
3560
3508
return ParameterList::create (P.Context , StartLoc, param, EndLoc);
3561
3509
}
3562
3510
@@ -3779,7 +3727,7 @@ bool Parser::parseGetSetImpl(ParseDeclOptions Flags,
3779
3727
diagnose (Loc, diag::protocol_setter_name);
3780
3728
3781
3729
auto *ValueNameParams
3782
- = parseOptionalAccessorArgument (Loc, ElementTy, *this , Kind);
3730
+ = parseOptionalAccessorArgument (Loc, *this , Kind);
3783
3731
3784
3732
// Set up a function declaration.
3785
3733
TheDecl = createAccessorFunc (Loc, ValueNameParams,
@@ -3905,7 +3853,7 @@ bool Parser::parseGetSetImpl(ParseDeclOptions Flags,
3905
3853
//
3906
3854
// set-name ::= '(' identifier ')'
3907
3855
auto *ValueNamePattern =
3908
- parseOptionalAccessorArgument (Loc, ElementTy, *this , Kind);
3856
+ parseOptionalAccessorArgument (Loc, *this , Kind);
3909
3857
3910
3858
SourceLoc LBLoc = isImplicitGet ? VarLBLoc : Tok.getLoc ();
3911
3859
// FIXME: Use outer '{' loc if isImplicitGet.
@@ -4033,6 +3981,54 @@ void Parser::parseAccessorBodyDelayed(AbstractFunctionDecl *AFD) {
4033
3981
AFD->setBody (Body);
4034
3982
}
4035
3983
3984
+ static void fillInAccessorTypeErrors (Parser &P, FuncDecl *accessor,
3985
+ AccessorKind kind) {
3986
+ if (!accessor) return ;
3987
+
3988
+ // Fill in the parameter types.
3989
+ for (auto paramList : accessor->getParameterLists ()) {
3990
+ for (auto param : *paramList) {
3991
+ if (param->getTypeLoc ().isNull ()) {
3992
+ param->getTypeLoc ().setType (P.Context .TheErrorType , true );
3993
+ }
3994
+ }
3995
+ }
3996
+
3997
+ // Fill in the result type.
3998
+ switch (kind) {
3999
+ case AccessorKind::NotAccessor:
4000
+ case AccessorKind::IsMaterializeForSet:
4001
+ llvm_unreachable (" should never be seen here" );
4002
+
4003
+ // These have non-trivial returns, so fill in error.
4004
+ case AccessorKind::IsGetter:
4005
+ case AccessorKind::IsAddressor:
4006
+ case AccessorKind::IsMutableAddressor:
4007
+ accessor->getBodyResultTypeLoc ().setType (P.Context .TheErrorType , true );
4008
+ return ;
4009
+
4010
+ // These return void.
4011
+ case AccessorKind::IsSetter:
4012
+ case AccessorKind::IsWillSet:
4013
+ case AccessorKind::IsDidSet:
4014
+ return ;
4015
+ }
4016
+ llvm_unreachable (" bad kind" );
4017
+ }
4018
+
4019
+ // / We weren't able to tie the given accessors to a storage declaration.
4020
+ // / Fill in various slots with type errors.
4021
+ static void fillInAccessorTypeErrors (Parser &P,
4022
+ Parser::ParsedAccessors &accessors) {
4023
+ fillInAccessorTypeErrors (P, accessors.Get , AccessorKind::IsGetter);
4024
+ fillInAccessorTypeErrors (P, accessors.Set , AccessorKind::IsSetter);
4025
+ fillInAccessorTypeErrors (P, accessors.Addressor , AccessorKind::IsAddressor);
4026
+ fillInAccessorTypeErrors (P, accessors.MutableAddressor ,
4027
+ AccessorKind::IsMutableAddressor);
4028
+ fillInAccessorTypeErrors (P, accessors.WillSet , AccessorKind::IsWillSet);
4029
+ fillInAccessorTypeErrors (P, accessors.DidSet , AccessorKind::IsDidSet);
4030
+ }
4031
+
4036
4032
// / \brief Parse the brace-enclosed getter and setter for a variable.
4037
4033
VarDecl *Parser::parseDeclVarGetSet (Pattern *pattern,
4038
4034
ParseDeclOptions Flags,
@@ -4076,8 +4072,10 @@ VarDecl *Parser::parseDeclVarGetSet(Pattern *pattern,
4076
4072
Invalid = true ;
4077
4073
4078
4074
// If we have an invalid case, bail out now.
4079
- if (!PrimaryVar)
4075
+ if (!PrimaryVar) {
4076
+ fillInAccessorTypeErrors (*this , accessors);
4080
4077
return nullptr ;
4078
+ }
4081
4079
4082
4080
if (!TyLoc.hasLocation ()) {
4083
4081
if (accessors.Get || accessors.Set || accessors.Addressor ||
@@ -4258,7 +4256,7 @@ void Parser::ParsedAccessors::record(Parser &P, AbstractStorageDecl *storage,
4258
4256
auto argFunc = (WillSet ? WillSet : DidSet);
4259
4257
auto argLoc = argFunc->getParameterLists ().back ()->getStartLoc ();
4260
4258
4261
- auto argument = createSetterAccessorArgument (argLoc, Identifier (),elementTy,
4259
+ auto argument = createSetterAccessorArgument (argLoc, Identifier (),
4262
4260
AccessorKind::IsSetter, P);
4263
4261
auto argList = ParameterList::create (P.Context , argument);
4264
4262
Set = createImplicitAccessor (AccessorKind::IsSetter,
@@ -4281,7 +4279,7 @@ void Parser::ParsedAccessors::record(Parser &P, AbstractStorageDecl *storage,
4281
4279
assert (Get && !Set);
4282
4280
auto argument =
4283
4281
createSetterAccessorArgument (MutableAddressor->getLoc (), Identifier (),
4284
- elementTy, AccessorKind::IsSetter, P);
4282
+ AccessorKind::IsSetter, P);
4285
4283
auto argList = ParameterList::create (P.Context , argument);
4286
4284
Set = createImplicitAccessor (AccessorKind::IsSetter,
4287
4285
AddressorKind::NotAddressor, argList);
0 commit comments