@@ -2886,18 +2886,33 @@ MissingContextualConformanceFailure::getDiagnosticFor(
2886
2886
return None;
2887
2887
}
2888
2888
2889
- SourceLoc MissingGenericArgumentsFailure::getLoc () const {
2890
- return BaseType ? BaseType->getLoc () : getAnchor ()->getLoc ();
2891
- }
2892
-
2893
2889
bool MissingGenericArgumentsFailure::hasLoc (GenericTypeParamType *GP) const {
2894
2890
return GP->getDecl ()->getStartLoc ().isValid ();
2895
2891
}
2896
2892
2897
2893
bool MissingGenericArgumentsFailure::diagnoseAsError () {
2894
+ llvm::SmallDenseMap<TypeRepr *, SmallVector<GenericTypeParamType *, 4 >>
2895
+ scopedParameters;
2896
+
2897
+ auto isScoped =
2898
+ findArgumentLocations ([&](TypeRepr *base, GenericTypeParamType *GP) {
2899
+ scopedParameters[base].push_back (GP);
2900
+ });
2901
+
2902
+ if (!isScoped)
2903
+ return diagnoseForAnchor (getAnchor (), Parameters);
2904
+
2898
2905
bool diagnosed = false ;
2899
- for (auto *GP : Parameters)
2900
- diagnosed |= diagnoseParameter (GP);
2906
+ for (const auto &scope : scopedParameters)
2907
+ diagnosed |= diagnoseForAnchor (scope.first , scope.second );
2908
+ return diagnosed;
2909
+ }
2910
+
2911
+ bool MissingGenericArgumentsFailure::diagnoseForAnchor (
2912
+ Anchor anchor, ArrayRef<GenericTypeParamType *> params) const {
2913
+ bool diagnosed = false ;
2914
+ for (auto *GP : params)
2915
+ diagnosed |= diagnoseParameter (anchor, GP);
2901
2916
2902
2917
if (!diagnosed)
2903
2918
return false ;
@@ -2915,14 +2930,17 @@ bool MissingGenericArgumentsFailure::diagnoseAsError() {
2915
2930
return true ;
2916
2931
}
2917
2932
2918
- emitGenericSignatureNote ();
2933
+ emitGenericSignatureNote (anchor );
2919
2934
return true ;
2920
2935
}
2921
2936
2922
2937
bool MissingGenericArgumentsFailure::diagnoseParameter (
2923
- GenericTypeParamType *GP) const {
2938
+ Anchor anchor, GenericTypeParamType *GP) const {
2924
2939
auto &cs = getConstraintSystem ();
2925
2940
2941
+ auto loc = anchor.is <Expr *>() ? anchor.get <Expr *>()->getLoc ()
2942
+ : anchor.get <TypeRepr *>()->getLoc ();
2943
+
2926
2944
auto *locator = getLocator ();
2927
2945
// Type variables associated with missing generic parameters are
2928
2946
// going to be completely cut off from the rest of constraint system,
@@ -2938,41 +2956,43 @@ bool MissingGenericArgumentsFailure::diagnoseParameter(
2938
2956
if (auto *CE = dyn_cast<ExplicitCastExpr>(getRawAnchor ())) {
2939
2957
auto castTo = getType (CE->getCastTypeLoc ());
2940
2958
auto *NTD = castTo->getAnyNominal ();
2941
- emitDiagnostic (getLoc () , diag::unbound_generic_parameter_cast, GP,
2959
+ emitDiagnostic (loc , diag::unbound_generic_parameter_cast, GP,
2942
2960
NTD ? NTD->getDeclaredType () : castTo);
2943
2961
} else {
2944
- emitDiagnostic (getLoc () , diag::unbound_generic_parameter, GP);
2962
+ emitDiagnostic (loc , diag::unbound_generic_parameter, GP);
2945
2963
}
2946
2964
2947
2965
if (!hasLoc (GP))
2948
2966
return true ;
2949
2967
2950
- Type baseType ;
2968
+ Type baseTyForNote ;
2951
2969
auto *DC = getDeclContext ();
2952
2970
2953
2971
if (auto *NTD =
2954
2972
dyn_cast_or_null<NominalTypeDecl>(DC->getSelfNominalTypeDecl ())) {
2955
- baseType = NTD->getDeclaredType ();
2973
+ baseTyForNote = NTD->getDeclaredType ();
2956
2974
} else if (auto *TAD = dyn_cast<TypeAliasDecl>(DC)) {
2957
- baseType = TAD->getUnboundGenericType ();
2975
+ baseTyForNote = TAD->getUnboundGenericType ();
2958
2976
} else {
2959
- baseType = DC->getDeclaredInterfaceType ();
2977
+ baseTyForNote = DC->getDeclaredInterfaceType ();
2960
2978
}
2961
2979
2962
- if (!baseType )
2980
+ if (!baseTyForNote )
2963
2981
return true ;
2964
2982
2965
- emitDiagnostic (GP->getDecl (), diag::archetype_declared_in_type, GP, baseType);
2983
+ emitDiagnostic (GP->getDecl (), diag::archetype_declared_in_type, GP,
2984
+ baseTyForNote);
2966
2985
return true ;
2967
2986
}
2968
2987
2969
- void MissingGenericArgumentsFailure::emitGenericSignatureNote () const {
2988
+ void MissingGenericArgumentsFailure::emitGenericSignatureNote (
2989
+ Anchor anchor) const {
2970
2990
auto &cs = getConstraintSystem ();
2971
2991
auto &TC = getTypeChecker ();
2972
2992
auto *paramDC = getDeclContext ();
2973
2993
2974
2994
auto *GTD = dyn_cast<GenericTypeDecl>(paramDC);
2975
- if (!GTD || !BaseType )
2995
+ if (!GTD || anchor. is <Expr *>() )
2976
2996
return ;
2977
2997
2978
2998
auto getParamDecl =
@@ -3006,18 +3026,90 @@ void MissingGenericArgumentsFailure::emitGenericSignatureNote() const {
3006
3026
};
3007
3027
3008
3028
SmallString<64 > paramsAsString;
3029
+ auto baseType = anchor.get <TypeRepr *>();
3009
3030
if (TC.getDefaultGenericArgumentsString (paramsAsString, GTD,
3010
3031
getPreferredType)) {
3011
- auto diagnostic =
3012
- emitDiagnostic ( getLoc (), diag::unbound_generic_parameter_explicit_fix);
3032
+ auto diagnostic = emitDiagnostic (
3033
+ baseType-> getLoc (), diag::unbound_generic_parameter_explicit_fix);
3013
3034
3014
- if (auto *genericTy = dyn_cast<GenericIdentTypeRepr>(BaseType )) {
3035
+ if (auto *genericTy = dyn_cast<GenericIdentTypeRepr>(baseType )) {
3015
3036
// If some of the eneric arguments have been specified, we need to
3016
3037
// replace existing signature with a new one.
3017
3038
diagnostic.fixItReplace (genericTy->getAngleBrackets (), paramsAsString);
3018
3039
} else {
3019
3040
// Otherwise we can simply insert new generic signature.
3020
- diagnostic.fixItInsertAfter (BaseType ->getEndLoc (), paramsAsString);
3041
+ diagnostic.fixItInsertAfter (baseType ->getEndLoc (), paramsAsString);
3021
3042
}
3022
3043
}
3023
3044
}
3045
+
3046
+ bool MissingGenericArgumentsFailure::findArgumentLocations (
3047
+ llvm::function_ref<void (TypeRepr *, GenericTypeParamType *)> callback) {
3048
+ using Callback = llvm::function_ref<void (TypeRepr *, GenericTypeParamType *)>;
3049
+
3050
+ auto *anchor = getRawAnchor ();
3051
+
3052
+ TypeLoc typeLoc;
3053
+ if (auto *TE = dyn_cast<TypeExpr>(anchor))
3054
+ typeLoc = TE->getTypeLoc ();
3055
+ else if (auto *ECE = dyn_cast<ExplicitCastExpr>(anchor))
3056
+ typeLoc = ECE->getCastTypeLoc ();
3057
+
3058
+ if (!typeLoc.hasLocation ())
3059
+ return false ;
3060
+
3061
+ struct AssociateMissingParams : public ASTWalker {
3062
+ llvm::SmallVector<GenericTypeParamType *, 4 > Params;
3063
+ Callback Fn;
3064
+
3065
+ AssociateMissingParams (ArrayRef<GenericTypeParamType *> params,
3066
+ Callback callback)
3067
+ : Params(params.begin(), params.end()), Fn(callback) {}
3068
+
3069
+ bool walkToTypeReprPre (TypeRepr *T) override {
3070
+ if (Params.empty ())
3071
+ return false ;
3072
+
3073
+ auto *ident = dyn_cast<ComponentIdentTypeRepr>(T);
3074
+ if (!ident)
3075
+ return true ;
3076
+
3077
+ auto *decl = dyn_cast_or_null<GenericTypeDecl>(ident->getBoundDecl ());
3078
+ if (!decl)
3079
+ return true ;
3080
+
3081
+ auto *paramList = decl->getGenericParams ();
3082
+ if (!paramList)
3083
+ return true ;
3084
+
3085
+ // There could a situation like `S<S>()`, so we need to be
3086
+ // careful not to point at first `S` because it has all of
3087
+ // its generic parameters specified.
3088
+ if (auto *generic = dyn_cast<GenericIdentTypeRepr>(ident)) {
3089
+ if (paramList->size () == generic->getNumGenericArgs ())
3090
+ return true ;
3091
+ }
3092
+
3093
+ for (auto *candidate : paramList->getParams ()) {
3094
+ auto result =
3095
+ llvm::find_if (Params, [&](const GenericTypeParamType *param) {
3096
+ return candidate == param->getDecl ();
3097
+ });
3098
+
3099
+ if (result != Params.end ()) {
3100
+ Fn (ident, *result);
3101
+ Params.erase (result);
3102
+ }
3103
+ }
3104
+
3105
+ // Keep walking.
3106
+ return true ;
3107
+ }
3108
+
3109
+ bool allParamsAssigned () const { return Params.empty (); }
3110
+
3111
+ } associator (Parameters, callback);
3112
+
3113
+ typeLoc.getTypeRepr ()->walk (associator);
3114
+ return associator.allParamsAssigned ();
3115
+ }
0 commit comments