Skip to content

Commit 44536fe

Browse files
committed
[Diagnostics] Improve missing generic argument diagnostic notes
Emit separate notes for generic parameters found in operator, initializer and function declarations. As well as clarify types of `declared in type` note.
1 parent 3737358 commit 44536fe

File tree

2 files changed

+49
-13
lines changed

2 files changed

+49
-13
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,21 +2895,46 @@ bool MissingGenericArgumentsFailure::hasLoc(GenericTypeParamType *GP) const {
28952895
}
28962896

28972897
bool MissingGenericArgumentsFailure::diagnoseAsError() {
2898+
bool diagnosed = false;
28982899
for (auto *GP : Parameters)
2899-
diagnoseParameter(GP);
2900+
diagnosed |= diagnoseParameter(GP);
2901+
2902+
if (!diagnosed)
2903+
return false;
29002904

29012905
auto *DC = getDeclContext();
29022906
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) {
2903-
emitDiagnostic(AFD, diag::note_call_to_func, AFD->getFullName());
2907+
if (isa<ConstructorDecl>(AFD)) {
2908+
emitDiagnostic(AFD, diag::note_call_to_initializer);
2909+
} else {
2910+
emitDiagnostic(AFD,
2911+
AFD->isOperator() ? diag::note_call_to_operator
2912+
: diag::note_call_to_func,
2913+
AFD->getFullName());
2914+
}
29042915
return true;
29052916
}
29062917

29072918
emitGenericSignatureNote();
29082919
return true;
29092920
}
29102921

2911-
void MissingGenericArgumentsFailure::diagnoseParameter(
2922+
bool MissingGenericArgumentsFailure::diagnoseParameter(
29122923
GenericTypeParamType *GP) const {
2924+
auto &cs = getConstraintSystem();
2925+
2926+
auto *locator = getLocator();
2927+
// Type variables associated with missing generic parameters are
2928+
// going to be completely cut off from the rest of constraint system,
2929+
// that's why we'd get two fixes in this case which is not ideal.
2930+
if (locator->isForContextualType() &&
2931+
llvm::count_if(cs.DefaultedConstraints,
2932+
[&GP](const ConstraintLocator *locator) {
2933+
return locator->getGenericParameter() == GP;
2934+
}) > 1) {
2935+
return false;
2936+
}
2937+
29132938
if (auto *CE = dyn_cast<ExplicitCastExpr>(getRawAnchor())) {
29142939
auto castTo = getType(CE->getCastTypeLoc());
29152940
auto *NTD = castTo->getAnyNominal();
@@ -2919,21 +2944,33 @@ void MissingGenericArgumentsFailure::diagnoseParameter(
29192944
emitDiagnostic(getLoc(), diag::unbound_generic_parameter, GP);
29202945
}
29212946

2947+
if (!hasLoc(GP))
2948+
return true;
2949+
2950+
Type baseType;
29222951
auto *DC = getDeclContext();
2923-
if (DC->isTypeContext() && hasLoc(GP)) {
2924-
auto *base = DC->getSelfNominalTypeDecl();
2925-
emitDiagnostic(GP->getDecl(), diag::archetype_declared_in_type, GP,
2926-
base->getDeclaredType());
2952+
2953+
if (auto *NTD =
2954+
dyn_cast_or_null<NominalTypeDecl>(DC->getSelfNominalTypeDecl())) {
2955+
baseType = NTD->getDeclaredType();
2956+
} else if (auto *TAD = dyn_cast<TypeAliasDecl>(DC)) {
2957+
baseType = TAD->getUnboundGenericType();
2958+
} else {
2959+
baseType = DC->getDeclaredInterfaceType();
29272960
}
2961+
2962+
if (!baseType)
2963+
return true;
2964+
2965+
emitDiagnostic(GP->getDecl(), diag::archetype_declared_in_type, GP, baseType);
2966+
return true;
29282967
}
29292968

29302969
void MissingGenericArgumentsFailure::emitGenericSignatureNote() const {
29312970
auto &cs = getConstraintSystem();
29322971
auto &TC = getTypeChecker();
29332972
auto *paramDC = getDeclContext();
29342973

2935-
assert(paramDC->isTypeContext());
2936-
29372974
auto *GTD = dyn_cast<GenericTypeDecl>(paramDC);
29382975
if (!GTD || !BaseType)
29392976
return;
@@ -2947,9 +2984,8 @@ void MissingGenericArgumentsFailure::emitGenericSignatureNote() const {
29472984

29482985
llvm::SmallDenseMap<GenericTypeParamDecl *, Type> params;
29492986
for (auto *typeVar : cs.getTypeVariables()) {
2950-
if (auto *locator = typeVar->getImpl().getLocator()) {
2951-
if (auto *GPD = getParamDecl(locator))
2952-
params[GPD] = resolveType(typeVar);
2987+
if (auto *GP = typeVar->getImpl().getGenericParameter()) {
2988+
params[GP->getDecl()] = resolveType(typeVar);
29532989
}
29542990
}
29552991

lib/Sema/CSDiagnostics.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ class MissingGenericArgumentsFailure final : public FailureDiagnostic {
12651265

12661266
bool diagnoseAsError() override;
12671267

1268-
void diagnoseParameter(GenericTypeParamType *GP) const;
1268+
bool diagnoseParameter(GenericTypeParamType *GP) const;
12691269

12701270
private:
12711271
void emitGenericSignatureNote() const;

0 commit comments

Comments
 (0)