@@ -221,7 +221,7 @@ private bool KeyNameToObjectPath(KeySyntax key, ObjectKind kind, bool fromDotted
221221 }
222222
223223 var name = GetStringFromBasic ( key . Key ! ) ;
224- if ( string . IsNullOrWhiteSpace ( name ) ) return false ;
224+ if ( name is null ) return false ;
225225
226226 _currentPath . Add ( name ! ) ;
227227
@@ -230,7 +230,7 @@ private bool KeyNameToObjectPath(KeySyntax key, ObjectKind kind, bool fromDotted
230230 {
231231 AddObjectPath ( key , kind , true , fromDottedKeys ) ;
232232 var dotItem = GetStringFromBasic ( items . GetChild ( i ) ! . Key ! ) ! ;
233- if ( string . IsNullOrWhiteSpace ( dotItem ) ) return false ;
233+ if ( dotItem is null ) return false ;
234234 _currentPath . Add ( dotItem ) ;
235235 }
236236
@@ -249,6 +249,18 @@ private ObjectPathValue AddObjectPath(SyntaxNode node, ObjectKind kind, bool isI
249249
250250 if ( _maps . TryGetValue ( currentPath , out var existingValue ) )
251251 {
252+ // TOML 1.1: if a super-table was created implicitly by a dotted table header (e.g. `[a.b]`),
253+ // defining it later explicitly (`[a]`) is invalid (toml-test: super-twice.toml, append-with-dotted-keys-04.toml).
254+ if ( existingValue . Kind == ObjectKind . Table &&
255+ existingValue . IsImplicit &&
256+ ! existingValue . FromDottedKeys &&
257+ kind == ObjectKind . Table &&
258+ ! isImplicit )
259+ {
260+ _diagnostics . Error ( node . Span , $ "The table `{ currentPath } ` was implicitly created by a dotted table header and cannot be defined explicitly.") ;
261+ return existingValue ;
262+ }
263+
252264 // The following tests are the trickiest to get right with the spec, as the behavior
253265 // of TOML Table/TableArray with implicit/non implicit and dotted keys is quite complicated.
254266
@@ -273,6 +285,16 @@ private ObjectPathValue AddObjectPath(SyntaxNode node, ObjectKind kind, bool isI
273285 {
274286 _currentPath . Add ( existingValue . ArrayIndex ) ;
275287 }
288+ else if ( existingValue . IsImplicit && ! isImplicit )
289+ {
290+ // Upgrade an implicit table created by dotted keys to an explicit table so further redefinitions are rejected.
291+ var upgraded = new ObjectPathValue ( node , existingValue . Kind , isImplicit : false , existingValue . FromDottedKeys )
292+ {
293+ ArrayIndex = existingValue . ArrayIndex ,
294+ } ;
295+ _maps [ currentPath ] = upgraded ;
296+ existingValue = upgraded ;
297+ }
276298 }
277299 else
278300 {
@@ -489,4 +511,4 @@ private enum KeySource
489511 KeyValue
490512 }
491513 }
492- }
514+ }
0 commit comments