@@ -102,12 +102,26 @@ impl flags::Scip {
102102 // This is called after definitions have been deduplicated by token_ids_emitted. The purpose
103103 // is to detect reuse of symbol names because this causes ambiguity about their meaning.
104104 let mut record_error_if_symbol_already_used =
105- |symbol : String , relative_path : & str , line_index : & LineIndex , text_range : TextRange | {
105+ |symbol : String ,
106+ is_inherent_impl : bool ,
107+ relative_path : & str ,
108+ line_index : & LineIndex ,
109+ text_range : TextRange | {
106110 let is_local = symbol. starts_with ( "local " ) ;
107111 if !is_local && !nonlocal_symbols_emitted. insert ( symbol. clone ( ) ) {
108- let source_location =
109- text_range_to_string ( relative_path, line_index, text_range) ;
110- duplicate_symbol_errors. push ( ( source_location, symbol) ) ;
112+ // See #18772. Duplicate SymbolInformation for inherent impls is omitted.
113+ if is_inherent_impl {
114+ false
115+ } else {
116+ let source_location =
117+ text_range_to_string ( relative_path, line_index, text_range) ;
118+ duplicate_symbol_errors. push ( ( source_location, symbol) ) ;
119+ // Keep duplicate SymbolInformation. This behavior is preferred over
120+ // omitting so that the issue might be visible within downstream tools.
121+ true
122+ }
123+ } else {
124+ true
111125 }
112126 } ;
113127
@@ -126,13 +140,13 @@ impl flags::Scip {
126140 tokens. into_iter ( ) . for_each ( |( text_range, id) | {
127141 let token = si. tokens . get ( id) . unwrap ( ) ;
128142
129- let ( symbol, enclosing_symbol) =
130- if let Some ( TokenSymbols { symbol, enclosing_symbol } ) =
143+ let ( symbol, enclosing_symbol, is_inherent_impl ) =
144+ if let Some ( TokenSymbols { symbol, enclosing_symbol, is_inherent_impl } ) =
131145 symbol_generator. token_symbols ( id, token)
132146 {
133- ( symbol, enclosing_symbol)
147+ ( symbol, enclosing_symbol, is_inherent_impl )
134148 } else {
135- ( "" . to_owned ( ) , None )
149+ ( "" . to_owned ( ) , None , false )
136150 } ;
137151
138152 if !symbol. is_empty ( ) {
@@ -144,17 +158,20 @@ impl flags::Scip {
144158 if token_ids_emitted. insert ( id) {
145159 // token_ids_emitted does deduplication. This checks that this results
146160 // in unique emitted symbols, as otherwise references are ambiguous.
147- record_error_if_symbol_already_used (
161+ let should_emit = record_error_if_symbol_already_used (
148162 symbol. clone ( ) ,
163+ is_inherent_impl,
149164 relative_path. as_str ( ) ,
150165 & line_index,
151166 text_range,
152167 ) ;
153- symbols. push ( compute_symbol_info (
154- symbol. clone ( ) ,
155- enclosing_symbol,
156- token,
157- ) ) ;
168+ if should_emit {
169+ symbols. push ( compute_symbol_info (
170+ symbol. clone ( ) ,
171+ enclosing_symbol,
172+ token,
173+ ) ) ;
174+ }
158175 }
159176 } else {
160177 token_ids_referenced. insert ( id) ;
@@ -227,12 +244,13 @@ impl flags::Scip {
227244 continue ;
228245 }
229246
230- let TokenSymbols { symbol, enclosing_symbol } = symbol_generator
247+ let TokenSymbols { symbol, enclosing_symbol, .. } = symbol_generator
231248 . token_symbols ( id, token)
232249 . expect ( "To have been referenced, the symbol must be in the cache." ) ;
233250
234251 record_error_if_symbol_already_used (
235252 symbol. clone ( ) ,
253+ false ,
236254 relative_path. as_str ( ) ,
237255 & line_index,
238256 text_range,
@@ -395,6 +413,9 @@ struct TokenSymbols {
395413 symbol : String ,
396414 /// Definition that contains this one. Only set when `symbol` is local.
397415 enclosing_symbol : Option < String > ,
416+ /// True if this symbol is for an inherent impl. This is used to only emit `SymbolInformation`
417+ /// for a struct's first inherent impl, since their symbol names are not disambiguated.
418+ is_inherent_impl : bool ,
398419}
399420
400421struct SymbolGenerator {
@@ -421,6 +442,14 @@ impl SymbolGenerator {
421442 MonikerResult :: Moniker ( moniker) => TokenSymbols {
422443 symbol : scip:: symbol:: format_symbol ( moniker_to_symbol ( moniker) ) ,
423444 enclosing_symbol : None ,
445+ is_inherent_impl : moniker
446+ . identifier
447+ . description
448+ . get ( moniker. identifier . description . len ( ) - 2 )
449+ . map_or ( false , |descriptor| {
450+ descriptor. desc == MonikerDescriptorKind :: Type
451+ && descriptor. name == "impl"
452+ } ) ,
424453 } ,
425454 MonikerResult :: Local { enclosing_moniker } => {
426455 let local_symbol = scip:: types:: Symbol :: new_local ( local_count) ;
@@ -431,6 +460,7 @@ impl SymbolGenerator {
431460 . as_ref ( )
432461 . map ( moniker_to_symbol)
433462 . map ( scip:: symbol:: format_symbol) ,
463+ is_inherent_impl : false ,
434464 }
435465 }
436466 } )
0 commit comments