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