@@ -109,6 +109,8 @@ impl ToTokens for TemplateBody {
109109 None => quote ! { None } ,
110110 } ;
111111
112+ let key_warnings = self . check_for_duplicate_keys ( ) ;
113+
112114 let roots = node. quote_roots ( ) ;
113115
114116 // Print paths is easy - just print the paths
@@ -138,6 +140,8 @@ impl ToTokens for TemplateBody {
138140 dioxus_core:: Element :: Ok ( {
139141 #diagnostics
140142
143+ #key_warnings
144+
141145 // Components pull in the dynamic literal pool and template in debug mode, so they need to be defined before dynamic nodes
142146 #[ cfg( debug_assertions) ]
143147 fn __original_template( ) -> & ' static dioxus_core:: internal:: HotReloadedTemplate {
@@ -273,11 +277,7 @@ impl TemplateBody {
273277 }
274278
275279 pub fn implicit_key ( & self ) -> Option < & AttributeValue > {
276- match self . roots . first ( ) {
277- Some ( BodyNode :: Element ( el) ) => el. key ( ) ,
278- Some ( BodyNode :: Component ( comp) ) => comp. get_key ( ) ,
279- _ => None ,
280- }
280+ self . roots . first ( ) . and_then ( BodyNode :: key)
281281 }
282282
283283 /// Ensure only one key and that the key is not a static str
@@ -304,6 +304,22 @@ impl TemplateBody {
304304 }
305305 }
306306
307+ fn check_for_duplicate_keys ( & self ) -> TokenStream2 {
308+ let mut warnings = TokenStream2 :: new ( ) ;
309+
310+ // Make sure there are not multiple keys or keys on nodes other than the first in the block
311+ for root in self . roots . iter ( ) . skip ( 1 ) {
312+ if let Some ( key) = root. key ( ) {
313+ warnings. extend ( new_diagnostics:: warning_diagnostic (
314+ key. span ( ) ,
315+ "Keys are only allowed on the first node in the block." ,
316+ ) ) ;
317+ }
318+ }
319+
320+ warnings
321+ }
322+
307323 pub fn get_dyn_node ( & self , path : & [ u8 ] ) -> & BodyNode {
308324 let mut node = self . roots . get ( path[ 0 ] as usize ) . unwrap ( ) ;
309325 for idx in path. iter ( ) . skip ( 1 ) {
0 commit comments