From 4e98bec3f19bdf1b930c264521b275403296123a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bastian=20K=C3=B6cher?= <git@kchr.de>
Date: Mon, 16 Oct 2023 14:41:44 +0200
Subject: [PATCH] sp-api: Improve error message for duplicate runtime apis
 (#1877)

Co-authored-by: command-bot <>
---
 .../api/proc-macro/src/impl_runtime_apis.rs        | 14 +++++++++-----
 .../tests/ui/impl_two_traits_with_same_name.stderr |  6 ++++++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs
index 74cfa098062..e439a796e28 100644
--- a/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs
+++ b/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs
@@ -38,7 +38,7 @@ use syn::{
 	Attribute, Ident, ImplItem, ItemImpl, LitInt, LitStr, Path, Signature, Type, TypePath,
 };
 
-use std::collections::HashSet;
+use std::collections::HashMap;
 
 /// The structure used for parsing the runtime api implementations.
 struct RuntimeApiImpls {
@@ -726,7 +726,7 @@ fn populate_runtime_api_versions(
 fn generate_runtime_api_versions(impls: &[ItemImpl]) -> Result<TokenStream> {
 	let mut result = Vec::<TokenStream>::with_capacity(impls.len());
 	let mut sections = Vec::<TokenStream>::with_capacity(impls.len());
-	let mut processed_traits = HashSet::new();
+	let mut processed_traits = HashMap::new();
 
 	let c = generate_crate_access();
 
@@ -746,13 +746,17 @@ fn generate_runtime_api_versions(impls: &[ItemImpl]) -> Result<TokenStream> {
 			.ident;
 
 		let span = trait_.span();
-		if !processed_traits.insert(trait_) {
-			return Err(Error::new(
+		if let Some(other_span) = processed_traits.insert(trait_, span) {
+			let mut error = Error::new(
 				span,
 				"Two traits with the same name detected! \
 					The trait name is used to generate its ID. \
 					Please rename one trait at the declaration!",
-			))
+			);
+
+			error.combine(Error::new(other_span, "First trait implementation."));
+
+			return Err(error)
 		}
 
 		let id: Path = parse_quote!( #path ID );
diff --git a/substrate/primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr b/substrate/primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr
index 9e014e3ea82..2197bbc99cf 100644
--- a/substrate/primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr
+++ b/substrate/primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr
@@ -3,3 +3,9 @@ error: Two traits with the same name detected! The trait name is used to generat
    |
 41 |     impl second::Api<Block> for Runtime {
    |                  ^^^
+
+error: First trait implementation.
+  --> tests/ui/impl_two_traits_with_same_name.rs:37:13
+   |
+37 |     impl self::Api<Block> for Runtime {
+   |                ^^^
-- 
GitLab