@@ -21,7 +21,7 @@ use rustc_hir::{
21
21
TraitItemKind , TyKind , UnOp ,
22
22
} ;
23
23
use rustc_index:: bit_set:: BitSet ;
24
- use rustc_infer:: infer:: TyCtxtInferExt ;
24
+ use rustc_infer:: infer:: { InferOk , TyCtxtInferExt } ;
25
25
use rustc_lint:: { LateContext , LateLintPass } ;
26
26
use rustc_middle:: mir:: { Rvalue , StatementKind } ;
27
27
use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow , AutoBorrowMutability } ;
@@ -31,8 +31,9 @@ use rustc_middle::ty::{
31
31
} ;
32
32
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
33
33
use rustc_span:: { symbol:: sym, Span , Symbol } ;
34
- use rustc_trait_selection:: infer:: InferCtxtExt as _;
35
- use rustc_trait_selection:: traits:: { query:: evaluate_obligation:: InferCtxtExt as _, Obligation , ObligationCause } ;
34
+ use rustc_trait_selection:: infer:: { canonical:: OriginalQueryValues , InferCtxtExt as _} ;
35
+ use rustc_trait_selection:: traits:: query:: { evaluate_obligation:: InferCtxtExt as _, NormalizationResult } ;
36
+ use rustc_trait_selection:: traits:: { Obligation , ObligationCause } ;
36
37
use std:: collections:: VecDeque ;
37
38
38
39
declare_clippy_lint ! {
@@ -1359,13 +1360,30 @@ fn replace_types<'tcx>(
1359
1360
{
1360
1361
let item_def_id = projection_predicate. projection_ty . def_id ;
1361
1362
let assoc_item = cx. tcx . associated_item ( item_def_id) ;
1362
- let projection = cx. tcx
1363
- . mk_projection ( assoc_item. def_id , cx. tcx . mk_substs_trait ( new_ty, [ ] ) ) ;
1364
-
1365
- if let Ok ( projected_ty) = cx. tcx . try_normalize_erasing_regions ( cx. param_env , projection)
1366
- && substs[ term_param_ty. index as usize ] != ty:: GenericArg :: from ( projected_ty)
1363
+ let alias_ty = cx
1364
+ . tcx
1365
+ . mk_alias_ty ( assoc_item. def_id , cx. tcx . mk_substs_trait ( new_ty, [ ] ) ) ;
1366
+
1367
+ // The following normalization method is based on:
1368
+ // https://github.com/rust-lang/rust/blob/695072daa6cc04045f2aa79d751d884ad5263080/compiler/rustc_trait_selection/src/traits/query/normalize.rs#L258-L285
1369
+ // It is meant to address: https://github.com/rust-lang/rust/issues/107877
1370
+ let infcx = cx. tcx . infer_ctxt ( ) . build ( ) ;
1371
+ let mut orig_values = OriginalQueryValues :: default ( ) ;
1372
+ let canonical_ty =
1373
+ infcx. canonicalize_query_keep_static ( cx. param_env . and ( alias_ty) , & mut orig_values) ;
1374
+
1375
+ if let Ok ( result) = cx. tcx . normalize_projection_ty ( canonical_ty)
1376
+ && !result. is_ambiguous ( )
1377
+ && let Ok ( InferOk { value : NormalizationResult { normalized_ty, .. } , .. } ) =
1378
+ infcx. instantiate_query_response_and_region_obligations (
1379
+ & ObligationCause :: dummy ( ) ,
1380
+ cx. param_env ,
1381
+ & orig_values,
1382
+ result,
1383
+ )
1384
+ && substs[ term_param_ty. index as usize ] != ty:: GenericArg :: from ( normalized_ty)
1367
1385
{
1368
- deque. push_back ( ( * term_param_ty, projected_ty ) ) ;
1386
+ deque. push_back ( ( * term_param_ty, normalized_ty ) ) ;
1369
1387
}
1370
1388
}
1371
1389
}
0 commit comments