Skip to content

Commit ea8fe29

Browse files
authored
feat: error if type parameters don't have sufficient context (#687)
### Summary of Changes Show an error if we already know at the declaration-site that we won't be able to infer type parameters in a call. A type parameter must occur in the parameter list of the containing callable. However, it does not suffice if they appear inside a union type or the parameter list of a callable type.
1 parent 09bfb38 commit ea8fe29

File tree

21 files changed

+147
-169
lines changed

21 files changed

+147
-169
lines changed

src/cli/generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ const getExternalReferenceNeededImport = function (
528528
if (isSdsQualifiedImport(value)) {
529529
const importedDeclarations = getImportedDeclarations(value);
530530
for (const importedDeclaration of importedDeclarations) {
531-
if (declaration === importedDeclaration.declaration.ref) {
531+
if (declaration === importedDeclaration.declaration?.ref) {
532532
if (importedDeclaration.alias !== undefined) {
533533
return {
534534
importPath: services.builtins.Annotations.getPythonModule(targetModule) || value.package,

src/language/grammar/safe-ds.langium

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ SdsImportedDeclarationList returns SdsImportedDeclarationList:
7777
;
7878

7979
interface SdsImportedDeclaration extends SdsObject {
80-
declaration: @SdsModuleMember;
80+
declaration?: @SdsModuleMember;
8181
alias?: SdsImportedDeclarationAlias;
8282
}
8383

@@ -384,7 +384,7 @@ SdsConstraint returns SdsConstraint:
384384
;
385385

386386
interface SdsTypeParameterConstraint extends SdsConstraint {
387-
leftOperand: @SdsTypeParameter
387+
leftOperand?: @SdsTypeParameter
388388
operator: string
389389
rightOperand: SdsType
390390
}
@@ -922,7 +922,7 @@ SdsLiteralList returns SdsLiteralList:
922922
;
923923

924924
interface SdsNamedType extends SdsType {
925-
declaration: @SdsNamedTypeDeclaration
925+
declaration?: @SdsNamedTypeDeclaration
926926
typeArgumentList?: SdsTypeArgumentList
927927
isNullable: boolean
928928
}

src/language/helpers/safe-ds-node-mapper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ export class SafeDsNodeMapper {
239239
}
240240

241241
// Find type parameter at the same position
242-
const namedTypeDeclaration = containingType.declaration.ref;
242+
const namedTypeDeclaration = containingType.declaration?.ref;
243243
const typeParameters = getTypeParameters(namedTypeDeclaration);
244244
return typeParameters[typeArgumentPosition];
245245
}

src/language/lsp/safe-ds-semantic-token-provider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export class SafeDsSemanticTokenProvider extends AbstractSemanticTokenProvider {
8787
type: SemanticTokenTypes.namespace,
8888
});
8989
} else if (isSdsImportedDeclaration(node)) {
90-
const info = this.computeSemanticTokenInfoForDeclaration(node.declaration.ref);
90+
const info = this.computeSemanticTokenInfoForDeclaration(node.declaration?.ref);
9191
if (info) {
9292
acceptor({
9393
node,
@@ -96,7 +96,7 @@ export class SafeDsSemanticTokenProvider extends AbstractSemanticTokenProvider {
9696
});
9797
}
9898
} else if (isSdsNamedType(node)) {
99-
const info = this.computeSemanticTokenInfoForDeclaration(node.declaration.ref);
99+
const info = this.computeSemanticTokenInfoForDeclaration(node.declaration?.ref);
100100
if (info) {
101101
acceptor({
102102
node,

src/language/scoping/safe-ds-scope-provider.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,16 @@ import { isContainedIn } from '../helpers/astUtils.js';
5252
import {
5353
getAbstractResults,
5454
getAssignees,
55-
getMatchingClassMembers,
5655
getEnumVariants,
5756
getImportedDeclarations,
5857
getImports,
59-
isStatic,
58+
getMatchingClassMembers,
6059
getPackageName,
6160
getParameters,
6261
getResults,
6362
getStatements,
6463
getTypeParameters,
64+
isStatic,
6565
} from '../helpers/nodeProperties.js';
6666
import { SafeDsServices } from '../safe-ds-module.js';
6767
import { SafeDsTypeComputer } from '../typing/safe-ds-type-computer.js';
@@ -165,7 +165,7 @@ export class SafeDsScopeProvider extends DefaultScopeProvider {
165165
*/
166166
private getUniqueReferencedDeclarationForType(node: SdsType): SdsNamedTypeDeclaration | undefined {
167167
if (isSdsNamedType(node)) {
168-
return node.declaration.ref;
168+
return node.declaration?.ref;
169169
} else if (isSdsMemberType(node)) {
170170
return node.member?.declaration?.ref;
171171
} else {
@@ -335,7 +335,7 @@ export class SafeDsScopeProvider extends DefaultScopeProvider {
335335
return EMPTY_SCOPE;
336336
}
337337

338-
const namedTypeDeclaration = containingNamedType.declaration.ref;
338+
const namedTypeDeclaration = containingNamedType.declaration?.ref;
339339
if (isSdsClass(namedTypeDeclaration)) {
340340
const typeParameters = getTypeParameters(namedTypeDeclaration.typeParameterList);
341341
return this.createScopeForNodes(typeParameters);
@@ -403,7 +403,7 @@ export class SafeDsScopeProvider extends DefaultScopeProvider {
403403
for (const imp of imports) {
404404
if (isSdsQualifiedImport(imp)) {
405405
for (const importedDeclaration of getImportedDeclarations(imp)) {
406-
const description = importedDeclaration.declaration.$nodeDescription;
406+
const description = importedDeclaration.declaration?.$nodeDescription;
407407
if (!description || !this.astReflection.isSubtype(description.type, referenceType)) {
408408
continue;
409409
}

src/language/typing/safe-ds-type-checker.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ export class SafeDsTypeChecker {
198198
}
199199

200200
private unionTypeIsAssignableTo(type: UnionType, other: Type): boolean {
201+
// return this.possibleTypes.all { it.isSubstitutableFor(other) }
201202
return type.equals(other);
202203
}
203204
}

src/language/typing/safe-ds-type-computer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ import {
7575
import { SafeDsNodeMapper } from '../helpers/safe-ds-node-mapper.js';
7676
import {
7777
getAssignees,
78-
streamBlockLambdaResults,
7978
getLiterals,
8079
getParameters,
8180
getResults,
8281
getTypeArguments,
82+
streamBlockLambdaResults,
8383
} from '../helpers/nodeProperties.js';
8484
import { SafeDsPartialEvaluator } from '../partialEvaluation/safe-ds-partial-evaluator.js';
8585
import { Constant, isConstant } from '../partialEvaluation/model.js';
@@ -453,7 +453,7 @@ export class SafeDsTypeComputer {
453453
} else if (isSdsMemberType(node)) {
454454
return this.computeType(node.member);
455455
} else if (isSdsNamedType(node)) {
456-
return this.computeType(node.declaration.ref).copyWithNullability(node.isNullable);
456+
return this.computeType(node.declaration?.ref).copyWithNullability(node.isNullable);
457457
} else if (isSdsUnionType(node)) {
458458
const typeArguments = getTypeArguments(node.typeArgumentList);
459459
return new UnionType(typeArguments.map((typeArgument) => this.computeType(typeArgument.value)));

src/language/typing/typeConformance.ts

Lines changed: 0 additions & 141 deletions
This file was deleted.

src/language/validation/builtins/deprecated.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export const argumentCorrespondingParameterShouldNotBeDeprecated =
7676

7777
export const namedTypeDeclarationShouldNotBeDeprecated =
7878
(services: SafeDsServices) => (node: SdsNamedType, accept: ValidationAcceptor) => {
79-
const declaration = node.declaration.ref;
79+
const declaration = node.declaration?.ref;
8080
if (!declaration) {
8181
return;
8282
}

src/language/validation/builtins/experimental.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export const argumentCorrespondingParameterShouldNotBeExperimental =
6868

6969
export const namedTypeDeclarationShouldNotBeExperimental =
7070
(services: SafeDsServices) => (node: SdsNamedType, accept: ValidationAcceptor) => {
71-
const declaration = node.declaration.ref;
71+
const declaration = node.declaration?.ref;
7272
if (!declaration) {
7373
return;
7474
}

0 commit comments

Comments
 (0)