@@ -11,8 +11,9 @@ use rustc_infer::infer::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TyCtx
1111use rustc_infer:: traits:: solve:: Goal ;
1212use rustc_middle:: traits:: query:: NoSolution ;
1313use rustc_middle:: traits:: solve:: Certainty ;
14- use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeFoldable , TypeVisitableExt as _, TypingMode } ;
15- use rustc_next_trait_solver:: solve:: HasChanged ;
14+ use rustc_middle:: ty:: {
15+ self , Ty , TyCtxt , TypeFlags , TypeFoldable , TypeVisitableExt as _, TypingMode ,
16+ } ;
1617use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Span } ;
1718
1819use crate :: traits:: { EvaluateConstErr , ObligationCause , specialization_graph} ;
@@ -61,19 +62,49 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
6162 & self ,
6263 goal : Goal < ' tcx , ty:: Predicate < ' tcx > > ,
6364 span : Span ,
64- ) -> Option < HasChanged > {
65+ ) -> Option < Certainty > {
66+ if let Some ( trait_pred) = goal. predicate . as_trait_clause ( ) {
67+ if trait_pred. polarity ( ) == ty:: PredicatePolarity :: Positive {
68+ match self . 0 . tcx . as_lang_item ( trait_pred. def_id ( ) ) {
69+ Some ( LangItem :: Sized )
70+ if self
71+ . resolve_vars_if_possible ( trait_pred. self_ty ( ) . skip_binder ( ) )
72+ . is_trivially_sized ( self . 0 . tcx ) =>
73+ {
74+ return Some ( Certainty :: Yes ) ;
75+ }
76+ Some ( LangItem :: Copy | LangItem :: Clone ) => {
77+ let self_ty =
78+ self . resolve_vars_if_possible ( trait_pred. self_ty ( ) . skip_binder ( ) ) ;
79+ // Unlike `Sized` traits, which always prefer the built-in impl,
80+ // `Copy`/`Clone` may be shadowed by a param-env candidate which
81+ // could force a lifetime error or guide inference. While that's
82+ // not generally desirable, it is observable, so for now let's
83+ // ignore this fast path for types that have regions or infer.
84+ if !self_ty
85+ . has_type_flags ( TypeFlags :: HAS_FREE_REGIONS | TypeFlags :: HAS_INFER )
86+ && self_ty. is_trivially_pure_clone_copy ( )
87+ {
88+ return Some ( Certainty :: Yes ) ;
89+ }
90+ }
91+ _ => { }
92+ }
93+ }
94+ }
95+
6596 let pred = goal. predicate . kind ( ) ;
6697 match pred. no_bound_vars ( ) ? {
6798 ty:: PredicateKind :: DynCompatible ( def_id) if self . 0 . tcx . is_dyn_compatible ( def_id) => {
68- Some ( HasChanged :: No )
99+ Some ( Certainty :: Yes )
69100 }
70101 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: RegionOutlives ( outlives) ) => {
71102 self . 0 . sub_regions (
72103 SubregionOrigin :: RelateRegionParamBound ( span, None ) ,
73104 outlives. 1 ,
74105 outlives. 0 ,
75106 ) ;
76- Some ( HasChanged :: No )
107+ Some ( Certainty :: Yes )
77108 }
78109 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: TypeOutlives ( outlives) ) => {
79110 self . 0 . register_type_outlives_constraint (
@@ -82,22 +113,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
82113 & ObligationCause :: dummy_with_span ( span) ,
83114 ) ;
84115
85- Some ( HasChanged :: No )
86- }
87- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( trait_pred) ) => {
88- match self . 0 . tcx . as_lang_item ( trait_pred. def_id ( ) ) {
89- Some ( LangItem :: Sized )
90- if trait_pred. self_ty ( ) . is_trivially_sized ( self . 0 . tcx ) =>
91- {
92- Some ( HasChanged :: No )
93- }
94- Some ( LangItem :: Copy | LangItem :: Clone )
95- if trait_pred. self_ty ( ) . is_trivially_pure_clone_copy ( ) =>
96- {
97- Some ( HasChanged :: No )
98- }
99- _ => None ,
100- }
116+ Some ( Certainty :: Yes )
101117 }
102118 _ => None ,
103119 }
0 commit comments