# 7. Types nominaux et fichiers `.saseltype` ## 7.1 Nommage — V1 REQUIS — FIGÉ Les types nominaux non primitifs commencent obligatoirement par une lettre ASCII majuscule. Aucune convention `UpperCamelCase`, `PascalCase` ou autre n'est imposée au-delà de cette première lettre. ## 7.2 Types nominaux V1 — V1 REQUIS — FIGÉ Un fichier `.saseltype` peut définir exactement un des types suivants : ```text class struct interface enum union ``` Le nom du fichier doit correspondre exactement au nom du type. Le fichier ne contient pas d'autres types top-level ni de fonctions auxiliaires top-level. ## 7.3 Ordre source et découverte nominale — V1 REQUIS — FIGÉ L'ordre textuel des fichiers ou des déclarations n'a pas de signification sémantique pour la résolution des types. Le frontend doit d'abord construire un index des déclarations nominales accessibles avant de finaliser leurs dépendances sémantiques. Saselang n'expose pas de syntaxe utilisateur de forward declaration telle que : ```text class Foo; struct Bar; ``` Une forward declaration manuelle serait redondante avec la collecte nominale du compilateur et réintroduirait des problèmes de cohérence inutiles. ## 7.4 États conceptuels de complétude — V1 REQUIS — FIGÉ EN PRINCIPE La spécification distingue conceptuellement : ```text nominalement connu identité du type, kind et paramètres génériques connus sémantiquement complet déclaration, héritage, interfaces et contrats résolus layout-complet représentation by-value, taille et alignement calculables lorsque nécessaires ``` Ces états décrivent le travail du compilateur ; le programmeur n'a pas à gérer explicitement des « types incomplets » comme en C/C++. Une déclaration générique peut être sémantiquement complète sans posséder un layout concret unique avant instanciation. ## 7.5 Dépendances de layout by-value — V1 REQUIS — FIGÉ Toute dépendance récursive **par valeur** est interdite, même lorsqu'une instanciation particulière pourrait théoriquement avoir une taille nulle. Exemples interdits : ```text struct A { A value; } ``` ```text struct A { B b; } struct B { A a; } ``` ```text struct A { StaticArray values; } ``` La longueur nulle ne crée aucune exception à la règle. Les tuples, payloads d'enums algébriques, structs et autres composants réellement stockés inline participent au graphe de layout. `StaticArray` participe également à ce graphe quel que soit `N`. Le compilateur doit détecter les cycles directs et indirects du graphe by-value. ## 7.6 Classes et références — V1 REQUIS — FIGÉ EN PRINCIPE Une valeur de type classe représente une référence d'objet et non une copie inline de l'objet complet. Ainsi : ```text class A { B b; } class B { A a; } ``` ne crée pas un cycle de layout by-value. Une classe peut néanmoins contenir des champs réellement by-value, par exemple un struct ; le layout de ces champs reste soumis aux règles normales du graphe de layout. Le modèle mémoire exact des références sera détaillé au chapitre mémoire sans modifier cette propriété sémantique. ## 7.7 Interfaces et stockage — V1 REQUIS — FIGÉ Une interface est un contrat et ne possède pas d'état d'instance propre. Le fait qu'une classe, un struct ou un autre type admissible implémente une interface ne change jamais implicitement son modèle de stockage, son identité ou son mode d'indirection. Un struct qui implémente une interface reste donc soumis exactement aux mêmes interdictions de récursivité by-value qu'un autre struct. ## 7.8 Héritage cyclique — V1 REQUIS — FIGÉ Le graphe `extends` doit être acyclique. Sont interdits : ```text class A extends B class B extends A ``` et : ```text interface A extends B interface B extends A ``` ainsi que tout cycle indirect. Les diamants non cycliques restent autorisés pour les interfaces. Le fait d'atteindre un ancêtre commun par plusieurs chemins ne constitue pas un cycle. Les diagnostics doivent identifier le graphe réellement fautif, par exemple : ```text cyclic inheritance recursive by-value layout ``` et non produire un message générique de « circular dependency ». ---