@@ -9,6 +9,8 @@ use rustc_middle::ty::{
9
9
self , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
10
10
} ;
11
11
use rustc_span:: Span ;
12
+ use rustc_type_ir:: lang_items:: TraitSolverLangItem ;
13
+ use rustc_type_ir:: { InferCtxtLike , Interner , Upcast } ;
12
14
use smallvec:: { SmallVec , smallvec} ;
13
15
use tracing:: debug;
14
16
@@ -504,3 +506,68 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
504
506
}
505
507
}
506
508
}
509
+
510
+ /// To improve performance, Sizedness traits are not elaborated and so special-casing is required
511
+ /// in the trait solver to find a `Sized` candidate for a `MetaSized` predicate. This is a helper
512
+ /// function for that special-casing, intended to be used when the obligation to be proven has been
513
+ /// confirmed to be `MetaSized`, and checking whether the `param_env` contains `Sized` for the same
514
+ /// `self_ty` is all that remains to be done.
515
+ // Ideally this would be re-used by the next solver, but there is no `InferCtxtLike` implementor.
516
+ pub ( crate ) fn sizedness_elab_opt_fast_path_from_paramenv < Infcx , I > (
517
+ infcx : & Infcx ,
518
+ self_ty : rustc_type_ir:: Binder < I , I :: Ty > ,
519
+ param_env : I :: ParamEnv ,
520
+ ) -> Option < rustc_type_ir:: Binder < I , rustc_type_ir:: TraitPredicate < I > > >
521
+ where
522
+ I : Interner ,
523
+ Infcx : InferCtxtLike < Interner = I > ,
524
+ {
525
+ #[ allow( rustc:: usage_of_type_ir_inherent) ]
526
+ use rustc_type_ir:: inherent:: * ;
527
+ sizedness_elab_opt_fast_path_from_clauses ( infcx, self_ty, param_env. caller_bounds ( ) . iter ( ) )
528
+ }
529
+
530
+ /// Same as `sizedness_elab_opt_fast_path_from_paramenv` but takes an iterator of clauses instead
531
+ /// of a parameter environment.
532
+ pub ( crate ) fn sizedness_elab_opt_fast_path_from_clauses < Infcx , I , Trs > (
533
+ infcx : & Infcx ,
534
+ self_ty : rustc_type_ir:: Binder < I , I :: Ty > ,
535
+ clauses : Trs ,
536
+ ) -> Option < rustc_type_ir:: Binder < I , rustc_type_ir:: TraitPredicate < I > > >
537
+ where
538
+ I : Interner ,
539
+ Infcx : InferCtxtLike < Interner = I > ,
540
+ Trs : IntoIterator < Item = I :: Clause > ,
541
+ {
542
+ #[ allow( rustc:: usage_of_type_ir_inherent) ]
543
+ use rustc_type_ir:: inherent:: * ;
544
+ sizedness_elab_opt_fast_path_from_traitrefs (
545
+ infcx,
546
+ self_ty,
547
+ clauses
548
+ . into_iter ( )
549
+ . filter_map ( |p| p. as_trait_clause ( ) )
550
+ . map ( |c| c. map_bound ( |c| c. trait_ref ) ) ,
551
+ )
552
+ . map ( |f| f. map_bound ( |f| f. upcast ( infcx. cx ( ) ) ) )
553
+ }
554
+
555
+ /// Same as `sizedness_elab_opt_fast_path_from_paramenv` but takes an iterator of trait refs instead
556
+ /// of a parameter environment.
557
+ pub ( crate ) fn sizedness_elab_opt_fast_path_from_traitrefs < Infcx , I , TraitRefs > (
558
+ infcx : & Infcx ,
559
+ self_ty : rustc_type_ir:: Binder < I , I :: Ty > ,
560
+ trait_refs : TraitRefs ,
561
+ ) -> Option < rustc_type_ir:: Binder < I , rustc_type_ir:: TraitRef < I > > >
562
+ where
563
+ I : Interner ,
564
+ Infcx : InferCtxtLike < Interner = I > ,
565
+ TraitRefs : IntoIterator < Item = rustc_type_ir:: Binder < I , rustc_type_ir:: TraitRef < I > > > ,
566
+ {
567
+ trait_refs. into_iter ( ) . find ( |c| {
568
+ let expected_self_ty = infcx. resolve_vars_if_possible ( self_ty) ;
569
+ let found_self_ty = infcx. resolve_vars_if_possible ( c. self_ty ( ) ) ;
570
+ expected_self_ty == found_self_ty
571
+ && infcx. cx ( ) . is_lang_item ( c. def_id ( ) , TraitSolverLangItem :: Sized )
572
+ } )
573
+ }
0 commit comments