@@ -2241,6 +2241,28 @@ def check_trait(trait_ref: Optional[L.LktNode],
22412241 'Inheritting from an enum node is forbidden'
22422242 )
22432243
2244+ with self .ctx .lkt_context (error_node_trait_ref ):
2245+ # Determine whether this node is abstract. Remember that base enum
2246+ # node types are abstract (it is their derivations that are
2247+ # concrete).
2248+ is_abstract = (
2249+ not isinstance (annotations , NodeAnnotations )
2250+ or annotations .abstract
2251+ )
2252+ if is_abstract and is_error_node :
2253+ error ("Error nodes cannot be abstract" )
2254+
2255+ # Determine whether this node is synthetic
2256+ is_synthetic = annotations .synthetic
2257+ if is_synthetic and is_error_node :
2258+ error ("Error nodes cannot be synthetic" )
2259+
2260+ if base_type and base_type .is_list and is_error_node :
2261+ error ("Error nodes cannot be lists" )
2262+
2263+ if is_token_node and is_error_node :
2264+ error ("Error nodes cannot be token nodes" )
2265+
22442266 # Lower fields. Regular nodes can hold all types of fields, but token
22452267 # nodes and enum nodes can hold only user field and properties.
22462268 allowed_field_types = (
@@ -2271,11 +2293,10 @@ def check_trait(trait_ref: Optional[L.LktNode],
22712293 doc = self .ctx .lkt_doc (decl .parent ),
22722294 base = base_type ,
22732295 fields = fields ,
2274- is_abstract = (not isinstance (annotations , NodeAnnotations )
2275- or annotations .abstract ),
2296+ is_abstract = is_abstract ,
22762297 is_token_node = is_token_node ,
22772298 is_error_node = is_error_node ,
2278- is_synthetic = annotations . synthetic ,
2299+ is_synthetic = is_synthetic ,
22792300 has_abstract_list = annotations .has_abstract_list ,
22802301 is_enum_node = is_enum_node ,
22812302 is_bool_node = is_bool_node ,
@@ -2292,6 +2313,18 @@ def check_trait(trait_ref: Optional[L.LktNode],
22922313 qualifier = annotations .qualifier
22932314 )
22942315
2316+ # Reject non-null fields for error nodes. Non-null fields can come from
2317+ # this node's own declaration, or they can come from inheritance.
2318+ if is_error_node :
2319+ error_msg = "Error nodes can only have null fields"
2320+ for f in result .get_parse_fields (include_inherited = True ):
2321+ if not (f .null or f .abstract ):
2322+ if f .struct != result :
2323+ error (f"{ error_msg } : { f .qualname } is not null" )
2324+ else :
2325+ with f .diagnostic_context :
2326+ error (error_msg )
2327+
22952328 return result
22962329
22972330 def create_enum_node_alternatives (
0 commit comments