22//! up data structures required by type-checking/codegen.
33
44use crate :: errors:: { CopyImplOnNonAdt , CopyImplOnTypeWithDtor , DropImplOnWrongItem } ;
5- use rustc_errors:: struct_span_err;
5+ use rustc_errors:: { struct_span_err, MultiSpan } ;
66use rustc_hir as hir;
77use rustc_hir:: def_id:: { DefId , LocalDefId } ;
88use rustc_hir:: lang_items:: LangItem ;
@@ -16,6 +16,7 @@ use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
1616use rustc_trait_selection:: traits:: misc:: { can_type_implement_copy, CopyImplementationError } ;
1717use rustc_trait_selection:: traits:: predicate_for_trait_def;
1818use rustc_trait_selection:: traits:: { self , ObligationCause , TraitEngine , TraitEngineExt } ;
19+ use std:: collections:: BTreeMap ;
1920
2021pub fn check_trait ( tcx : TyCtxt < ' _ > , trait_def_id : DefId ) {
2122 let lang_items = tcx. lang_items ( ) ;
@@ -101,6 +102,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
101102 generics = self_item. kind . generics ( ) ;
102103 }
103104 }
105+ let mut errors: BTreeMap < _ , Vec < _ > > = Default :: default ( ) ;
104106 let mut bounds = vec ! [ ] ;
105107
106108 for ( field, ty) in fields {
@@ -127,13 +129,10 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
127129 // FIXME: This error could be more descriptive, especially if the error_predicate
128130 // contains a foreign type or if it's a deeply nested type...
129131 if error_predicate != error. root_obligation . predicate {
130- err. span_note (
131- error. obligation . cause . span ,
132- & format ! (
133- "the `Copy` impl for `{}` requires that `{}`" ,
134- ty, error_predicate
135- ) ,
136- ) ;
132+ errors
133+ . entry ( ( ty. to_string ( ) , error_predicate. to_string ( ) ) )
134+ . or_default ( )
135+ . push ( error. obligation . cause . span ) ;
137136 }
138137 if let ty:: PredicateKind :: Trait ( ty:: TraitPredicate {
139138 trait_ref,
@@ -153,6 +152,13 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
153152 }
154153 } ) ;
155154 }
155+ for ( ( ty, error_predicate) , spans) in errors {
156+ let span: MultiSpan = spans. into ( ) ;
157+ err. span_note (
158+ span,
159+ & format ! ( "the `Copy` impl for `{}` requires that `{}`" , ty, error_predicate) ,
160+ ) ;
161+ }
156162 if let Some ( generics) = generics {
157163 suggest_constraining_type_params (
158164 tcx,
0 commit comments