Problème de compréhension de l’inférence de type C # comme décrit dans la spécification du langage

La spécification du langage C # décrit l’inférence de type dans la section §7.5.2. Il y a un détail dans ce que je ne comprends pas. Considérons le cas suivant:

// declaration void Method(T obj, Func func); // call Method("obj", s => (object) s); 

Les compilateurs Microsoft et Mono C # infèrent correctement T = object , mais ma compréhension de l’algorithme dans la spécification donnerait T = ssortingng et échouerait ensuite. Voici comment je le comprends:

La première phase

  • Si Ei est une fonction anonyme, une inférence de type de paramètre explicite (§ 7.5.2.7) est faite de Ei à Ti

    ⇒ n’a aucun effet, car l’expression lambda n’a pas de types de parameters explicites. Droite?

  • Sinon, si Ei a un type U et que xi est un paramètre de valeur, une inférence inférieure est faite de U à Ti.

    ⇒ le premier paramètre est de type statique ssortingng , donc cela ajoute une ssortingng aux limites inférieures de T , n’est-ce pas?

La deuxième phase

  • Toutes les variables de type non corrigées Xi qui ne dépendent pas de (§7.5.2.5) des Xj sont fixes (§7.5.2.10).

    T est non fixé; T ne dépend de rien … alors T devrait être réparé, non?

§7.5.2.11 Fixation

  • L’ensemble des types candidats Uj commence comme l’ensemble de tous les types dans l’ensemble des limites pour Xi.

    ⇒ { ssortingng (limite inférieure)}

  • Nous examinons ensuite chaque borne pour Xi à tour de rôle: […] Pour chaque limite inférieure U de Xi, tous les types Uj auxquels il n’y a pas de conversion implicite de U sont supprimés de l’ensemble candidat. […]

    ⇒ ne retire rien de l’ensemble des candidats, n’est-ce pas?

  • Si parmi les types candidats restants Uj il existe un type unique V à partir duquel il existe une conversion implicite à tous les autres types candidats, alors Xi est fixé à V.

    ⇒ Comme il n’ya qu’un seul type candidat, c’est vrai, donc Xi est fixé à ssortingng . Droite?


Alors, où est-ce que je me trompe?

MISE À JOUR: Mon enquête initiale dans le bus ce matin était incomplète et erronée. Le texte de la spécification de la première phase est correct. La mise en œuvre est correcte.

La spécification est erronée dans la mesure où l’ordre des événements est erroné dans la deuxième phase. Nous devrions spécifier que nous faisons des inférences de type de sortie avant de fixer les parameters non dépendants.

Man, ce truc est compliqué. J’ai réécrit cette section de la spécification plus de fois que je peux m’en souvenir.

J’ai déjà vu ce problème et je me souviens très bien d’avoir effectué des révisions telles que le terme incorrect “variable de type” était remplacé partout par “paramètre de type”. (Les parameters de type ne sont pas des emplacements de stockage dont le contenu peut varier, il n’ya donc pas de sens à les appeler des variables.) Je pense en même temps que la commande était incorrecte. Ce qui est probablement arrivé, c’est que nous avons accidentellement envoyé une ancienne version de la spécification sur le Web. Beaucoup d’excuses.

Je vais travailler avec Mads pour obtenir la spécification mise à jour pour correspondre à l’implémentation. Je pense que la formulation correcte de la deuxième phase devrait aller quelque chose comme ceci:

  • Si aucun paramètre de type non défini n’existe, l’inférence de type réussit.
  • Sinon, s’il existe un ou plusieurs arguments Ei avec le type de paramètre correspondant Ti tel que le type de sortie de Ei de type Ti contienne au moins un paramètre de type non fixé Xj, et aucun des types d’entrée de type Ei contenant un paramètre de type non fixé Xj, alors une inférence de type de sortie est faite de tous ces Ei à Ti.

Que l’étape précédente ait ou non fait une inférence, nous devons maintenant corriger au moins un paramètre de type, comme suit:

  • S’il existe un ou plusieurs parameters de type Xi tels que Xi est non fixé et que Xi possède un ensemble de limites non vide, et que Xi ne dépend d’aucun Xj, chacun de ces Xi est fixe. Si une opération de réparation échoue, la déduction de type échoue.
  • Sinon, s’il existe un ou plusieurs parameters de type Xi tels que Xi est non fixé et que Xi possède un ensemble de bornes non vide, et qu’il existe au moins un paramètre de type Xj dépendant de Xi, chacun de ces Xi est fixe. Si une opération de réparation échoue, la déduction de type échoue.
  • Sinon, nous ne pouvons pas progresser et il y a des parameters non corrigés. La déduction de type échoue.

Si l’inférence de type n’échoue ni ne réussit, la deuxième phase est répétée.

L’idée ici est que nous voulons nous assurer que l’algorithme ne passe jamais dans une boucle infinie. À chaque répétition de la deuxième phase, elle réussit, échoue ou progresse. Il est impossible de boucler plus de fois qu’il n’y a de parameters de type à corriger pour les types.

Merci d’avoir attiré mon attention.