@@ -26,7 +26,7 @@ use std::iter::{self};
2626#[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
2727pub enum ObjectSafetyViolation {
2828 /// `Self: Sized` declared on the trait.
29- SizedSelf ,
29+ SizedSelf ( Span ) ,
3030
3131 /// Supertrait reference references `Self` an in illegal location
3232 /// (e.g., `trait Foo : Bar<Self>`).
@@ -42,7 +42,7 @@ pub enum ObjectSafetyViolation {
4242impl ObjectSafetyViolation {
4343 pub fn error_msg ( & self ) -> Cow < ' static , str > {
4444 match * self {
45- ObjectSafetyViolation :: SizedSelf => {
45+ ObjectSafetyViolation :: SizedSelf ( _ ) => {
4646 "the trait cannot require that `Self : Sized`" . into ( )
4747 }
4848 ObjectSafetyViolation :: SupertraitSelf => {
@@ -80,6 +80,7 @@ impl ObjectSafetyViolation {
8080 // diagnostics use a `note` instead of a `span_label`.
8181 match * self {
8282 ObjectSafetyViolation :: AssocConst ( _, span)
83+ | ObjectSafetyViolation :: SizedSelf ( span)
8384 | ObjectSafetyViolation :: Method ( _, _, span)
8485 if span != DUMMY_SP =>
8586 {
@@ -179,17 +180,20 @@ fn object_safety_violations_for_trait(
179180 {
180181 // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
181182 // It's also hard to get a use site span, so we use the method definition span.
182- tcx. struct_span_lint_hir (
183+ let mut err = tcx. struct_span_lint_hir (
183184 WHERE_CLAUSES_OBJECT_SAFETY ,
184185 hir:: CRATE_HIR_ID ,
185186 * span,
186187 & format ! (
187188 "the trait `{}` cannot be made into an object" ,
188189 tcx. def_path_str( trait_def_id)
189190 ) ,
190- )
191- . note ( & violation. error_msg ( ) )
192- . emit ( ) ;
191+ ) ;
192+ match violation. span ( ) {
193+ Some ( span) => err. span_label ( span, violation. error_msg ( ) ) ,
194+ None => err. note ( & violation. error_msg ( ) ) ,
195+ } ;
196+ err. emit ( ) ;
193197 false
194198 } else {
195199 true
@@ -199,7 +203,8 @@ fn object_safety_violations_for_trait(
199203
200204 // Check the trait itself.
201205 if trait_has_sized_self ( tcx, trait_def_id) {
202- violations. push ( ObjectSafetyViolation :: SizedSelf ) ;
206+ let span = get_sized_bound ( tcx, trait_def_id) ;
207+ violations. push ( ObjectSafetyViolation :: SizedSelf ( span) ) ;
203208 }
204209 if predicates_reference_self ( tcx, trait_def_id, false ) {
205210 violations. push ( ObjectSafetyViolation :: SupertraitSelf ) ;
@@ -219,6 +224,27 @@ fn object_safety_violations_for_trait(
219224 violations
220225}
221226
227+ fn get_sized_bound ( tcx : TyCtxt < ' _ > , trait_def_id : DefId ) -> Span {
228+ tcx. hir ( )
229+ . get_if_local ( trait_def_id)
230+ . and_then ( |node| match node {
231+ hir:: Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Trait ( .., bounds, _) , .. } ) => bounds
232+ . iter ( )
233+ . filter_map ( |b| match b {
234+ hir:: GenericBound :: Trait ( trait_ref, hir:: TraitBoundModifier :: None )
235+ if Some ( trait_ref. trait_ref . trait_def_id ( ) )
236+ == tcx. lang_items ( ) . sized_trait ( ) =>
237+ {
238+ Some ( trait_ref. span )
239+ }
240+ _ => None ,
241+ } )
242+ . next ( ) ,
243+ _ => None ,
244+ } )
245+ . unwrap_or ( DUMMY_SP )
246+ }
247+
222248fn predicates_reference_self ( tcx : TyCtxt < ' _ > , trait_def_id : DefId , supertraits_only : bool ) -> bool {
223249 let trait_ref = ty:: Binder :: dummy ( ty:: TraitRef :: identity ( tcx, trait_def_id) ) ;
224250 let predicates = if supertraits_only {
0 commit comments