@@ -669,30 +669,11 @@ fn project<'cx, 'tcx>(
669669
670670 match candidates {
671671 ProjectionCandidateSet :: Single ( candidate) => {
672- Ok ( Projected :: Progress ( confirm_candidate ( selcx, obligation, candidate) ) )
672+ confirm_candidate ( selcx, obligation, candidate)
673673 }
674674 ProjectionCandidateSet :: None => {
675675 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) ;
696677 Ok ( Projected :: NoProgress ( term) )
697678 }
698679 // Error occurred while trying to processing impls.
@@ -1244,18 +1225,16 @@ fn confirm_candidate<'cx, 'tcx>(
12441225 selcx : & mut SelectionContext < ' cx , ' tcx > ,
12451226 obligation : & ProjectionTermObligation < ' tcx > ,
12461227 candidate : ProjectionCandidate < ' tcx > ,
1247- ) -> Progress < ' tcx > {
1228+ ) -> Result < Projected < ' tcx > , ProjectionError < ' tcx > > {
12481229 debug ! ( ?obligation, ?candidate, "confirm_candidate" ) ;
1249- let mut progress = match candidate {
1230+ let mut result = match candidate {
12501231 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+ ) ) ,
12591238 ProjectionCandidate :: Select ( impl_source) => {
12601239 confirm_select_candidate ( selcx, obligation, impl_source)
12611240 }
@@ -1266,23 +1245,26 @@ fn confirm_candidate<'cx, 'tcx>(
12661245 // with new region variables, we need to resolve them to existing variables
12671246 // when possible for this to work. See `auto-trait-projection-recursion.rs`
12681247 // 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+ {
12701251 progress. term = progress. term . fold_with ( & mut OpportunisticRegionResolver :: new ( selcx. infcx ) ) ;
12711252 }
1272- progress
1253+
1254+ result
12731255}
12741256
12751257fn confirm_select_candidate < ' cx , ' tcx > (
12761258 selcx : & mut SelectionContext < ' cx , ' tcx > ,
12771259 obligation : & ProjectionTermObligation < ' tcx > ,
12781260 impl_source : Selection < ' tcx > ,
1279- ) -> Progress < ' tcx > {
1261+ ) -> Result < Projected < ' tcx > , ProjectionError < ' tcx > > {
12801262 match impl_source {
12811263 ImplSource :: UserDefined ( data) => confirm_impl_candidate ( selcx, obligation, data) ,
12821264 ImplSource :: Builtin ( BuiltinImplSource :: Misc | BuiltinImplSource :: Trivial , data) => {
12831265 let tcx = selcx. tcx ( ) ;
12841266 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 ) {
12861268 confirm_coroutine_candidate ( selcx, obligation, data)
12871269 } else if tcx. is_lang_item ( trait_def_id, LangItem :: Future ) {
12881270 confirm_future_candidate ( selcx, obligation, data)
@@ -1304,7 +1286,8 @@ fn confirm_select_candidate<'cx, 'tcx>(
13041286 confirm_async_fn_kind_helper_candidate ( selcx, obligation, data)
13051287 } else {
13061288 confirm_builtin_candidate ( selcx, obligation, data)
1307- }
1289+ } ;
1290+ Ok ( Projected :: Progress ( progress) )
13081291 }
13091292 ImplSource :: Builtin ( BuiltinImplSource :: Object { .. } , _)
13101293 | ImplSource :: Param ( ..)
@@ -2000,7 +1983,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20001983 selcx : & mut SelectionContext < ' cx , ' tcx > ,
20011984 obligation : & ProjectionTermObligation < ' tcx > ,
20021985 impl_impl_source : ImplSourceUserDefinedData < ' tcx , PredicateObligation < ' tcx > > ,
2003- ) -> Progress < ' tcx > {
1986+ ) -> Result < Projected < ' tcx > , ProjectionError < ' tcx > > {
20041987 let tcx = selcx. tcx ( ) ;
20051988
20061989 let ImplSourceUserDefinedData { impl_def_id, args, mut nested } = impl_impl_source;
@@ -2011,19 +1994,33 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20111994 let param_env = obligation. param_env ;
20121995 let assoc_ty = match specialization_graph:: assoc_def ( tcx, impl_def_id, assoc_item_id) {
20131996 Ok ( assoc_ty) => assoc_ty,
2014- Err ( guar) => return Progress :: error ( tcx, guar) ,
1997+ Err ( guar) => return Ok ( Projected :: Progress ( Progress :: error ( tcx, guar) ) ) ,
20151998 } ;
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.
20162005 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.
20212006 debug ! (
20222007 "confirm_impl_candidate: no associated type {:?} for {:?}" ,
20232008 assoc_ty. item. name, obligation. predicate
20242009 ) ;
2025- return Progress { term : Ty :: new_misc_error ( tcx) . into ( ) , obligations : nested } ;
2010+ if tcx. impl_self_is_guaranteed_unsized ( impl_def_id) {
2011+ // We treat this projection as rigid here, which is represented via
2012+ // `Projected::NoProgress`. This will ensure that the projection is
2013+ // checked for well-formedness, and it's either satisfied by a trivial
2014+ // where clause in its env or it results in an error.
2015+ return Ok ( Projected :: NoProgress ( obligation. predicate . to_term ( tcx) ) ) ;
2016+ } else {
2017+ return Ok ( Projected :: Progress ( Progress {
2018+ term : Ty :: new_misc_error ( tcx) . into ( ) ,
2019+ obligations : nested,
2020+ } ) ) ;
2021+ }
20262022 }
2023+
20272024 // If we're trying to normalize `<Vec<u32> as X>::A<S>` using
20282025 //`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then:
20292026 //
@@ -2033,6 +2030,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20332030 let args = obligation. predicate . args . rebase_onto ( tcx, trait_def_id, args) ;
20342031 let args = translate_args ( selcx. infcx , param_env, impl_def_id, args, assoc_ty. defining_node ) ;
20352032 let is_const = matches ! ( tcx. def_kind( assoc_ty. item. def_id) , DefKind :: AssocConst ) ;
2033+
20362034 let term: ty:: EarlyBinder < ' tcx , ty:: Term < ' tcx > > = if is_const {
20372035 let did = assoc_ty. item . def_id ;
20382036 let identity_args = crate :: traits:: GenericArgs :: identity_for_item ( tcx, did) ;
@@ -2041,7 +2039,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20412039 } else {
20422040 tcx. type_of ( assoc_ty. item . def_id ) . map_bound ( |ty| ty. into ( ) )
20432041 } ;
2044- if !tcx. check_args_compatible ( assoc_ty. item . def_id , args) {
2042+
2043+ let progress = if !tcx. check_args_compatible ( assoc_ty. item . def_id , args) {
20452044 let err = Ty :: new_error_with_message (
20462045 tcx,
20472046 obligation. cause . span ,
@@ -2051,7 +2050,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20512050 } else {
20522051 assoc_ty_own_obligations ( selcx, obligation, & mut nested) ;
20532052 Progress { term : term. instantiate ( tcx, args) , obligations : nested }
2054- }
2053+ } ;
2054+ Ok ( Projected :: Progress ( progress) )
20552055}
20562056
20572057// Get obligations corresponding to the predicates from the where-clause of the
0 commit comments