@@ -669,30 +669,11 @@ fn project<'cx, 'tcx>(
669
669
670
670
match candidates {
671
671
ProjectionCandidateSet :: Single ( candidate) => {
672
- Ok ( Projected :: Progress ( confirm_candidate ( selcx, obligation, candidate) ) )
672
+ confirm_candidate ( selcx, obligation, candidate)
673
673
}
674
674
ProjectionCandidateSet :: None => {
675
675
let tcx = selcx. tcx ( ) ;
676
- let term = match tcx. def_kind ( obligation. predicate . def_id ) {
677
- DefKind :: AssocTy => Ty :: new_projection_from_args (
678
- tcx,
679
- obligation. predicate . def_id ,
680
- obligation. predicate . args ,
681
- )
682
- . into ( ) ,
683
- DefKind :: AssocConst => ty:: Const :: new_unevaluated (
684
- tcx,
685
- ty:: UnevaluatedConst :: new (
686
- obligation. predicate . def_id ,
687
- obligation. predicate . args ,
688
- ) ,
689
- )
690
- . into ( ) ,
691
- kind => {
692
- bug ! ( "unknown projection def-id: {}" , kind. descr( obligation. predicate. def_id) )
693
- }
694
- } ;
695
-
676
+ let term = obligation. predicate . to_term ( tcx) ;
696
677
Ok ( Projected :: NoProgress ( term) )
697
678
}
698
679
// Error occurred while trying to processing impls.
@@ -1244,18 +1225,16 @@ fn confirm_candidate<'cx, 'tcx>(
1244
1225
selcx : & mut SelectionContext < ' cx , ' tcx > ,
1245
1226
obligation : & ProjectionTermObligation < ' tcx > ,
1246
1227
candidate : ProjectionCandidate < ' tcx > ,
1247
- ) -> Progress < ' tcx > {
1228
+ ) -> Result < Projected < ' tcx > , ProjectionError < ' tcx > > {
1248
1229
debug ! ( ?obligation, ?candidate, "confirm_candidate" ) ;
1249
- let mut progress = match candidate {
1230
+ let mut result = match candidate {
1250
1231
ProjectionCandidate :: ParamEnv ( poly_projection)
1251
- | ProjectionCandidate :: Object ( poly_projection) => {
1252
- confirm_param_env_candidate ( selcx, obligation, poly_projection, false )
1253
- }
1254
-
1255
- ProjectionCandidate :: TraitDef ( poly_projection) => {
1256
- confirm_param_env_candidate ( selcx, obligation, poly_projection, true )
1257
- }
1258
-
1232
+ | ProjectionCandidate :: Object ( poly_projection) => Ok ( Projected :: Progress (
1233
+ confirm_param_env_candidate ( selcx, obligation, poly_projection, false ) ,
1234
+ ) ) ,
1235
+ ProjectionCandidate :: TraitDef ( poly_projection) => Ok ( Projected :: Progress (
1236
+ confirm_param_env_candidate ( selcx, obligation, poly_projection, true ) ,
1237
+ ) ) ,
1259
1238
ProjectionCandidate :: Select ( impl_source) => {
1260
1239
confirm_select_candidate ( selcx, obligation, impl_source)
1261
1240
}
@@ -1266,23 +1245,26 @@ fn confirm_candidate<'cx, 'tcx>(
1266
1245
// with new region variables, we need to resolve them to existing variables
1267
1246
// when possible for this to work. See `auto-trait-projection-recursion.rs`
1268
1247
// for a case where this matters.
1269
- if progress. term . has_infer_regions ( ) {
1248
+ if let Ok ( Projected :: Progress ( progress) ) = & mut result
1249
+ && progress. term . has_infer_regions ( )
1250
+ {
1270
1251
progress. term = progress. term . fold_with ( & mut OpportunisticRegionResolver :: new ( selcx. infcx ) ) ;
1271
1252
}
1272
- progress
1253
+
1254
+ result
1273
1255
}
1274
1256
1275
1257
fn confirm_select_candidate < ' cx , ' tcx > (
1276
1258
selcx : & mut SelectionContext < ' cx , ' tcx > ,
1277
1259
obligation : & ProjectionTermObligation < ' tcx > ,
1278
1260
impl_source : Selection < ' tcx > ,
1279
- ) -> Progress < ' tcx > {
1261
+ ) -> Result < Projected < ' tcx > , ProjectionError < ' tcx > > {
1280
1262
match impl_source {
1281
1263
ImplSource :: UserDefined ( data) => confirm_impl_candidate ( selcx, obligation, data) ,
1282
1264
ImplSource :: Builtin ( BuiltinImplSource :: Misc | BuiltinImplSource :: Trivial , data) => {
1283
1265
let tcx = selcx. tcx ( ) ;
1284
1266
let trait_def_id = obligation. predicate . trait_def_id ( tcx) ;
1285
- if tcx. is_lang_item ( trait_def_id, LangItem :: Coroutine ) {
1267
+ let progress = if tcx. is_lang_item ( trait_def_id, LangItem :: Coroutine ) {
1286
1268
confirm_coroutine_candidate ( selcx, obligation, data)
1287
1269
} else if tcx. is_lang_item ( trait_def_id, LangItem :: Future ) {
1288
1270
confirm_future_candidate ( selcx, obligation, data)
@@ -1304,7 +1286,8 @@ fn confirm_select_candidate<'cx, 'tcx>(
1304
1286
confirm_async_fn_kind_helper_candidate ( selcx, obligation, data)
1305
1287
} else {
1306
1288
confirm_builtin_candidate ( selcx, obligation, data)
1307
- }
1289
+ } ;
1290
+ Ok ( Projected :: Progress ( progress) )
1308
1291
}
1309
1292
ImplSource :: Builtin ( BuiltinImplSource :: Object { .. } , _)
1310
1293
| ImplSource :: Param ( ..)
@@ -2000,7 +1983,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
2000
1983
selcx : & mut SelectionContext < ' cx , ' tcx > ,
2001
1984
obligation : & ProjectionTermObligation < ' tcx > ,
2002
1985
impl_impl_source : ImplSourceUserDefinedData < ' tcx , PredicateObligation < ' tcx > > ,
2003
- ) -> Progress < ' tcx > {
1986
+ ) -> Result < Projected < ' tcx > , ProjectionError < ' tcx > > {
2004
1987
let tcx = selcx. tcx ( ) ;
2005
1988
2006
1989
let ImplSourceUserDefinedData { impl_def_id, args, mut nested } = impl_impl_source;
@@ -2011,19 +1994,47 @@ fn confirm_impl_candidate<'cx, 'tcx>(
2011
1994
let param_env = obligation. param_env ;
2012
1995
let assoc_ty = match specialization_graph:: assoc_def ( tcx, impl_def_id, assoc_item_id) {
2013
1996
Ok ( assoc_ty) => assoc_ty,
2014
- Err ( guar) => return Progress :: error ( tcx, guar) ,
1997
+ Err ( guar) => return Ok ( Projected :: Progress ( Progress :: error ( tcx, guar) ) ) ,
2015
1998
} ;
1999
+
2000
+ // This means that the impl is missing a definition for the
2001
+ // associated type. This is either because the associate item
2002
+ // has impossible-to-satisfy predicates (since those were
2003
+ // allowed in <https://github.com/rust-lang/rust/pull/135480>),
2004
+ // or because the impl is literally missing the definition.
2016
2005
if !assoc_ty. item . defaultness ( tcx) . has_value ( ) {
2017
- // This means that the impl is missing a definition for the
2018
- // associated type. This error will be reported by the type
2019
- // checker method `check_impl_items_against_trait`, so here we
2020
- // just return Error.
2021
2006
debug ! (
2022
2007
"confirm_impl_candidate: no associated type {:?} for {:?}" ,
2023
2008
assoc_ty. item. name, obligation. predicate
2024
2009
) ;
2025
- return Progress { term : Ty :: new_misc_error ( tcx) . into ( ) , obligations : nested } ;
2010
+ let tail = selcx. tcx ( ) . struct_tail_raw (
2011
+ tcx. type_of ( impl_def_id) . instantiate ( tcx, args) ,
2012
+ |ty| {
2013
+ normalize_with_depth_to (
2014
+ selcx,
2015
+ obligation. param_env ,
2016
+ obligation. cause . clone ( ) ,
2017
+ obligation. recursion_depth + 1 ,
2018
+ ty,
2019
+ & mut nested,
2020
+ )
2021
+ } ,
2022
+ || { } ,
2023
+ ) ;
2024
+ if tail. is_guaranteed_unsized_raw ( ) {
2025
+ // We treat this projection as rigid here, which is represented via
2026
+ // `Projected::NoProgress`. This will ensure that the projection is
2027
+ // checked for well-formedness, and it's either satisfied by a trivial
2028
+ // where clause in its env or it results in an error.
2029
+ return Ok ( Projected :: NoProgress ( obligation. predicate . to_term ( tcx) ) ) ;
2030
+ } else {
2031
+ return Ok ( Projected :: Progress ( Progress {
2032
+ term : Ty :: new_misc_error ( tcx) . into ( ) ,
2033
+ obligations : nested,
2034
+ } ) ) ;
2035
+ }
2026
2036
}
2037
+
2027
2038
// If we're trying to normalize `<Vec<u32> as X>::A<S>` using
2028
2039
//`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then:
2029
2040
//
@@ -2033,6 +2044,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
2033
2044
let args = obligation. predicate . args . rebase_onto ( tcx, trait_def_id, args) ;
2034
2045
let args = translate_args ( selcx. infcx , param_env, impl_def_id, args, assoc_ty. defining_node ) ;
2035
2046
let is_const = matches ! ( tcx. def_kind( assoc_ty. item. def_id) , DefKind :: AssocConst ) ;
2047
+
2036
2048
let term: ty:: EarlyBinder < ' tcx , ty:: Term < ' tcx > > = if is_const {
2037
2049
let did = assoc_ty. item . def_id ;
2038
2050
let identity_args = crate :: traits:: GenericArgs :: identity_for_item ( tcx, did) ;
@@ -2041,7 +2053,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
2041
2053
} else {
2042
2054
tcx. type_of ( assoc_ty. item . def_id ) . map_bound ( |ty| ty. into ( ) )
2043
2055
} ;
2044
- if !tcx. check_args_compatible ( assoc_ty. item . def_id , args) {
2056
+
2057
+ let progress = if !tcx. check_args_compatible ( assoc_ty. item . def_id , args) {
2045
2058
let err = Ty :: new_error_with_message (
2046
2059
tcx,
2047
2060
obligation. cause . span ,
@@ -2051,7 +2064,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
2051
2064
} else {
2052
2065
assoc_ty_own_obligations ( selcx, obligation, & mut nested) ;
2053
2066
Progress { term : term. instantiate ( tcx, args) , obligations : nested }
2054
- }
2067
+ } ;
2068
+ Ok ( Projected :: Progress ( progress) )
2055
2069
}
2056
2070
2057
2071
// Get obligations corresponding to the predicates from the where-clause of the
0 commit comments