@@ -45,7 +45,7 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4545
4646 // Ensure that if ~T is cast to ~Trait, then T : Trait
4747 push_cast_obligation ( fcx, cast_expr, object_trait, referent_ty) ;
48- check_object_safety ( fcx. tcx ( ) , object_trait, source_expr. span ) ;
48+ check_object_safety ( fcx. tcx ( ) , & object_trait. principal , source_expr. span ) ;
4949 }
5050
5151 ( & ty:: ty_rptr( referent_region, ty:: mt { ty : referent_ty,
@@ -69,7 +69,7 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
6969 target_region,
7070 referent_region) ;
7171
72- check_object_safety ( fcx. tcx ( ) , object_trait, source_expr. span ) ;
72+ check_object_safety ( fcx. tcx ( ) , & object_trait. principal , source_expr. span ) ;
7373 }
7474 }
7575
@@ -133,17 +133,32 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
133133// self by value, has no type parameters and does not use the `Self` type, except
134134// in self position.
135135pub fn check_object_safety < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
136- object_trait : & ty:: TyTrait < ' tcx > ,
136+ object_trait : & ty:: TraitRef < ' tcx > ,
137+ span : Span ) {
138+
139+ let mut object = object_trait. clone ( ) ;
140+ if object. substs . types . len ( SelfSpace ) == 0 {
141+ object. substs . types . push ( SelfSpace , ty:: mk_err ( ) ) ;
142+ }
143+
144+ let object = Rc :: new ( object) ;
145+ for tr in traits:: supertraits ( tcx, object) {
146+ check_object_safety_inner ( tcx, & * tr, span) ;
147+ }
148+ }
149+
150+ fn check_object_safety_inner < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
151+ object_trait : & ty:: TraitRef < ' tcx > ,
137152 span : Span ) {
138153 // Skip the fn_once lang item trait since only the compiler should call
139154 // `call_once` which is the method which takes self by value. What could go
140155 // wrong?
141156 match tcx. lang_items . fn_once_trait ( ) {
142- Some ( def_id) if def_id == object_trait. principal . def_id => return ,
157+ Some ( def_id) if def_id == object_trait. def_id => return ,
143158 _ => { }
144159 }
145160
146- let trait_items = ty:: trait_items ( tcx, object_trait. principal . def_id ) ;
161+ let trait_items = ty:: trait_items ( tcx, object_trait. def_id ) ;
147162
148163 let mut errors = Vec :: new ( ) ;
149164 for item in trait_items. iter ( ) {
@@ -157,7 +172,7 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
157172
158173 let mut errors = errors. iter ( ) . flat_map ( |x| x. iter ( ) ) . peekable ( ) ;
159174 if errors. peek ( ) . is_some ( ) {
160- let trait_name = ty:: item_path_str ( tcx, object_trait. principal . def_id ) ;
175+ let trait_name = ty:: item_path_str ( tcx, object_trait. def_id ) ;
161176 span_err ! ( tcx. sess, span, E0038 ,
162177 "cannot convert to a trait object because trait `{}` is not object-safe" ,
163178 trait_name) ;
0 commit comments