@@ -5,7 +5,7 @@ use rustc_type_ir::fast_reject::DeepRejectCtxt;
55use rustc_type_ir:: inherent:: * ;
66use rustc_type_ir:: lang_items:: SolverTraitLangItem ;
77use rustc_type_ir:: solve:: {
8- AliasBoundKind , CandidatePreferenceMode , CanonicalResponse , MaybeInfo ,
8+ AliasBoundKind , CandidatePreferenceMode , CanonicalResponse , ExternalConstraintsData , MaybeInfo ,
99 NoSolutionOrRerunNonErased , OpaqueTypesJank , QueryResultOrRerunNonErased , RerunNonErased ,
1010 RerunReason , RerunResultExt , SizedTraitKind ,
1111} ;
@@ -1286,9 +1286,6 @@ where
12861286 ) -> Result < Candidate < I > , NoSolutionOrRerunNonErased > {
12871287 let cx = self . cx ( ) ;
12881288 let source = CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Misc ) ;
1289- if self . opaque_accesses . might_rerun ( ) {
1290- match self . opaque_accesses . rerun_always ( RerunReason :: AutoTraitLeakage ) ? { }
1291- }
12921289
12931290 for item_bound in cx. item_self_bounds ( def_id. into ( ) ) . skip_binder ( ) {
12941291 if item_bound. as_trait_clause ( ) . is_some_and ( |b| b. def_id ( ) == goal. predicate . def_id ( ) ) {
@@ -1303,25 +1300,49 @@ where
13031300 goal. with ( cx, goal. predicate . with_replaced_self_ty ( cx, hidden_ty) ) ,
13041301 ) ?;
13051302 ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
1306- } ) ;
1303+ } ) ? ;
13071304
1308- let opaque_types_may_leak = match self . typing_mode ( ) {
1309- TypingMode :: PostTypeckUntilBorrowck { .. } => false ,
1310- TypingMode :: Coherence
1311- | TypingMode :: Typeck { .. }
1312- | TypingMode :: PostBorrowck { .. }
1313- | TypingMode :: Reflection
1314- | TypingMode :: PostAnalysis
1315- | TypingMode :: Codegen
1316- | TypingMode :: ErasedNotCoherence ( MayBeErased ) => true ,
1317- } ;
1305+ // Proving an auto trait for the hidden type must not constrain inference
1306+ // variables, as that would leak the hidden type itself.
1307+ if !candidate. result . value . var_values . is_identity_modulo_regions ( ) {
1308+ return self . forced_ambiguity ( MaybeInfo :: AMBIGUOUS ) ;
1309+ }
13181310
1319- match candidate {
1320- Ok ( candidate) if has_only_region_constraints ( candidate. result ) => Ok ( candidate) ,
1321- Ok ( candidate) if !opaque_types_may_leak => Ok ( candidate) ,
1322- Ok ( _) => self . forced_ambiguity ( MaybeInfo :: AMBIGUOUS ) ,
1323- Err ( err) => Err ( err) ,
1311+ let ExternalConstraintsData {
1312+ region_constraints : _,
1313+ ref opaque_types,
1314+ ref normalization_nested_goals,
1315+ } = * candidate. result . value . external_constraints ;
1316+ debug_assert ! ( normalization_nested_goals. is_empty( ) ) ;
1317+
1318+ // New defining uses may leak an opaque's hidden type into the caller's
1319+ // inference state. This is safe after typeck, where hidden types are already
1320+ // fixed and only regions are inferred, but not during typeck while hidden
1321+ // types may still contain inference variables.
1322+ if !opaque_types. is_empty ( ) {
1323+ match self . typing_mode ( ) {
1324+ // We're inferring regions of opaque types, but
1325+ // the type itself is already fully known, no way
1326+ // to leak the hidden type.
1327+ TypingMode :: PostTypeckUntilBorrowck { .. } => { }
1328+ // We're inferring the hidden type of opaques, could
1329+ // leak types through it.
1330+ TypingMode :: Typeck { .. } => {
1331+ return self . forced_ambiguity ( MaybeInfo :: AMBIGUOUS ) ;
1332+ }
1333+ // we never add new uses to the opaque type storage
1334+ TypingMode :: Coherence
1335+ | TypingMode :: PostBorrowck { .. }
1336+ | TypingMode :: Reflection
1337+ | TypingMode :: PostAnalysis
1338+ | TypingMode :: Codegen
1339+ | TypingMode :: ErasedNotCoherence ( MayBeErased ) => {
1340+ return self . forced_ambiguity ( MaybeInfo :: AMBIGUOUS ) ;
1341+ }
1342+ }
13241343 }
1344+
1345+ Ok ( candidate)
13251346 }
13261347
13271348 // Return `Some` if there is an impl (built-in or user provided) that may
0 commit comments