@@ -38,6 +38,7 @@ use rustc_span::def_id::CRATE_DEF_ID;
3838use rustc_span:: source_map:: Spanned ;
3939use rustc_span:: symbol:: sym;
4040use rustc_span:: Span ;
41+ use rustc_span:: DUMMY_SP ;
4142use rustc_target:: abi:: { FieldIdx , FIRST_VARIANT } ;
4243use rustc_trait_selection:: traits:: query:: type_op:: custom:: scrape_region_constraints;
4344use rustc_trait_selection:: traits:: query:: type_op:: custom:: CustomTypeOp ;
@@ -49,6 +50,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
4950use rustc_mir_dataflow:: move_paths:: MoveData ;
5051use rustc_mir_dataflow:: ResultsCursor ;
5152
53+ use crate :: renumber:: RegionCtxt ;
5254use crate :: session_diagnostics:: { MoveUnsized , SimdIntrinsicArgConst } ;
5355use crate :: {
5456 borrow_set:: BorrowSet ,
@@ -1352,7 +1354,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13521354 }
13531355 // FIXME: check the values
13541356 }
1355- TerminatorKind :: Call { func, args, destination, call_source, target, .. } => {
1357+ TerminatorKind :: Call { func, args, .. }
1358+ | TerminatorKind :: TailCall { func, args, .. } => {
1359+ let call_source = match term. kind {
1360+ TerminatorKind :: Call { call_source, .. } => call_source,
1361+ TerminatorKind :: TailCall { .. } => CallSource :: Normal ,
1362+ _ => unreachable ! ( ) ,
1363+ } ;
1364+
13561365 self . check_operand ( func, term_location) ;
13571366 for arg in args {
13581367 self . check_operand ( & arg. node , term_location) ;
@@ -1425,7 +1434,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
14251434 ) ;
14261435 }
14271436
1428- self . check_call_dest ( body, term, & sig, * destination, * target, term_location) ;
1437+ if let TerminatorKind :: Call { destination, target, .. } = term. kind {
1438+ self . check_call_dest ( body, term, & sig, destination, target, term_location) ;
1439+ }
14291440
14301441 // The ordinary liveness rules will ensure that all
14311442 // regions in the type of the callee are live here. We
@@ -1443,7 +1454,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
14431454 . add_location ( region_vid, term_location) ;
14441455 }
14451456
1446- self . check_call_inputs ( body, term, func, & sig, args, term_location, * call_source) ;
1457+ self . check_call_inputs ( body, term, func, & sig, args, term_location, call_source) ;
14471458 }
14481459 TerminatorKind :: Assert { cond, msg, .. } => {
14491460 self . check_operand ( cond, term_location) ;
@@ -1675,6 +1686,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16751686 span_mirbug ! ( self , block_data, "return on cleanup block" )
16761687 }
16771688 }
1689+ TerminatorKind :: TailCall { .. } => {
1690+ if is_cleanup {
1691+ span_mirbug ! ( self , block_data, "tailcall on cleanup block" )
1692+ }
1693+ }
16781694 TerminatorKind :: CoroutineDrop { .. } => {
16791695 if is_cleanup {
16801696 span_mirbug ! ( self , block_data, "coroutine_drop in cleanup block" )
@@ -2319,7 +2335,57 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
23192335 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
23202336 let cast_ty_to = CastTy :: from_ty ( * ty) ;
23212337 match ( cast_ty_from, cast_ty_to) {
2322- ( Some ( CastTy :: Ptr ( _) ) , Some ( CastTy :: Ptr ( _) ) ) => ( ) ,
2338+ ( Some ( CastTy :: Ptr ( src) ) , Some ( CastTy :: Ptr ( dst) ) ) => {
2339+ let mut normalize = |t| self . normalize ( t, location) ;
2340+ let src_tail =
2341+ tcx. struct_tail_with_normalize ( src. ty , & mut normalize, || ( ) ) ;
2342+ let dst_tail =
2343+ tcx. struct_tail_with_normalize ( dst. ty , & mut normalize, || ( ) ) ;
2344+
2345+ // This checks (lifetime part of) vtable validity for pointer casts,
2346+ // which is irrelevant when there are aren't principal traits on both sides (aka only auto traits).
2347+ //
2348+ // Note that other checks (such as denying `dyn Send` -> `dyn Debug`) are in `rustc_hir_typeck`.
2349+ if let ty:: Dynamic ( src_tty, ..) = src_tail. kind ( )
2350+ && let ty:: Dynamic ( dst_tty, ..) = dst_tail. kind ( )
2351+ && src_tty. principal ( ) . is_some ( )
2352+ && dst_tty. principal ( ) . is_some ( )
2353+ {
2354+ // Remove auto traits.
2355+ // Auto trait checks are handled in `rustc_hir_typeck` as FCW.
2356+ let src_obj = tcx. mk_ty_from_kind ( ty:: Dynamic (
2357+ tcx. mk_poly_existential_predicates (
2358+ & src_tty. without_auto_traits ( ) . collect :: < Vec < _ > > ( ) ,
2359+ ) ,
2360+ tcx. lifetimes . re_static ,
2361+ ty:: Dyn ,
2362+ ) ) ;
2363+ let dst_obj = tcx. mk_ty_from_kind ( ty:: Dynamic (
2364+ tcx. mk_poly_existential_predicates (
2365+ & dst_tty. without_auto_traits ( ) . collect :: < Vec < _ > > ( ) ,
2366+ ) ,
2367+ tcx. lifetimes . re_static ,
2368+ ty:: Dyn ,
2369+ ) ) ;
2370+
2371+ // Replace trait object lifetimes with fresh vars, to allow casts like
2372+ // `*mut dyn FnOnce() + 'a` -> `*mut dyn FnOnce() + 'static`,
2373+ let src_obj =
2374+ freshen_single_trait_object_lifetime ( self . infcx , src_obj) ;
2375+ let dst_obj =
2376+ freshen_single_trait_object_lifetime ( self . infcx , dst_obj) ;
2377+
2378+ debug ! ( ?src_tty, ?dst_tty, ?src_obj, ?dst_obj) ;
2379+
2380+ self . eq_types (
2381+ src_obj,
2382+ dst_obj,
2383+ location. to_locations ( ) ,
2384+ ConstraintCategory :: Cast { unsize_to : None } ,
2385+ )
2386+ . unwrap ( ) ;
2387+ }
2388+ }
23232389 _ => {
23242390 span_mirbug ! (
23252391 self ,
@@ -2842,3 +2908,16 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
28422908 Ok ( output)
28432909 }
28442910}
2911+
2912+ fn freshen_single_trait_object_lifetime < ' tcx > (
2913+ infcx : & BorrowckInferCtxt < ' tcx > ,
2914+ ty : Ty < ' tcx > ,
2915+ ) -> Ty < ' tcx > {
2916+ let & ty:: Dynamic ( tty, _, dyn_kind @ ty:: Dyn ) = ty. kind ( ) else { bug ! ( "expected trait object" ) } ;
2917+
2918+ let fresh = infcx
2919+ . next_region_var ( rustc_infer:: infer:: RegionVariableOrigin :: MiscVariable ( DUMMY_SP ) , || {
2920+ RegionCtxt :: Unknown
2921+ } ) ;
2922+ infcx. tcx . mk_ty_from_kind ( ty:: Dynamic ( tty, fresh, dyn_kind) )
2923+ }
0 commit comments