@@ -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.
@@ -1243,18 +1224,16 @@ fn confirm_candidate<'cx, 'tcx>(
12431224 selcx : & mut SelectionContext < ' cx , ' tcx > ,
12441225 obligation : & ProjectionTermObligation < ' tcx > ,
12451226 candidate : ProjectionCandidate < ' tcx > ,
1246- ) -> Progress < ' tcx > {
1227+ ) -> Result < Projected < ' tcx > , ProjectionError < ' tcx > > {
12471228 debug ! ( ?obligation, ?candidate, "confirm_candidate" ) ;
1248- let mut progress = match candidate {
1229+ let mut result = match candidate {
12491230 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+ ) ) ,
12581237 ProjectionCandidate :: Select ( impl_source) => {
12591238 confirm_select_candidate ( selcx, obligation, impl_source)
12601239 }
@@ -1265,23 +1244,26 @@ fn confirm_candidate<'cx, 'tcx>(
12651244 // with new region variables, we need to resolve them to existing variables
12661245 // when possible for this to work. See `auto-trait-projection-recursion.rs`
12671246 // 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+ {
12691250 progress. term = progress. term . fold_with ( & mut OpportunisticRegionResolver :: new ( selcx. infcx ) ) ;
12701251 }
1271- progress
1252+
1253+ result
12721254}
12731255
12741256fn confirm_select_candidate < ' cx , ' tcx > (
12751257 selcx : & mut SelectionContext < ' cx , ' tcx > ,
12761258 obligation : & ProjectionTermObligation < ' tcx > ,
12771259 impl_source : Selection < ' tcx > ,
1278- ) -> Progress < ' tcx > {
1260+ ) -> Result < Projected < ' tcx > , ProjectionError < ' tcx > > {
12791261 match impl_source {
12801262 ImplSource :: UserDefined ( data) => confirm_impl_candidate ( selcx, obligation, data) ,
12811263 ImplSource :: Builtin ( BuiltinImplSource :: Misc | BuiltinImplSource :: Trivial , data) => {
12821264 let tcx = selcx. tcx ( ) ;
12831265 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 ) {
12851267 confirm_coroutine_candidate ( selcx, obligation, data)
12861268 } else if tcx. is_lang_item ( trait_def_id, LangItem :: Future ) {
12871269 confirm_future_candidate ( selcx, obligation, data)
@@ -1303,7 +1285,8 @@ fn confirm_select_candidate<'cx, 'tcx>(
13031285 confirm_async_fn_kind_helper_candidate ( selcx, obligation, data)
13041286 } else {
13051287 confirm_builtin_candidate ( selcx, obligation, data)
1306- }
1288+ } ;
1289+ Ok ( Projected :: Progress ( progress) )
13071290 }
13081291 ImplSource :: Builtin ( BuiltinImplSource :: Object { .. } , _)
13091292 | ImplSource :: Param ( ..)
@@ -1999,7 +1982,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
19991982 selcx : & mut SelectionContext < ' cx , ' tcx > ,
20001983 obligation : & ProjectionTermObligation < ' tcx > ,
20011984 impl_impl_source : ImplSourceUserDefinedData < ' tcx , PredicateObligation < ' tcx > > ,
2002- ) -> Progress < ' tcx > {
1985+ ) -> Result < Projected < ' tcx > , ProjectionError < ' tcx > > {
20031986 let tcx = selcx. tcx ( ) ;
20041987
20051988 let ImplSourceUserDefinedData { impl_def_id, args, mut nested } = impl_impl_source;
@@ -2010,19 +1993,33 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20101993 let param_env = obligation. param_env ;
20111994 let assoc_ty = match specialization_graph:: assoc_def ( tcx, impl_def_id, assoc_item_id) {
20121995 Ok ( assoc_ty) => assoc_ty,
2013- Err ( guar) => return Progress :: error ( tcx, guar) ,
1996+ Err ( guar) => return Ok ( Projected :: Progress ( Progress :: error ( tcx, guar) ) ) ,
20141997 } ;
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.
20152004 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.
20202005 debug ! (
20212006 "confirm_impl_candidate: no associated type {:?} for {:?}" ,
20222007 assoc_ty. item. name, obligation. predicate
20232008 ) ;
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+ }
20252021 }
2022+
20262023 // If we're trying to normalize `<Vec<u32> as X>::A<S>` using
20272024 //`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then:
20282025 //
@@ -2032,6 +2029,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20322029 let args = obligation. predicate . args . rebase_onto ( tcx, trait_def_id, args) ;
20332030 let args = translate_args ( selcx. infcx , param_env, impl_def_id, args, assoc_ty. defining_node ) ;
20342031 let is_const = matches ! ( tcx. def_kind( assoc_ty. item. def_id) , DefKind :: AssocConst ) ;
2032+
20352033 let term: ty:: EarlyBinder < ' tcx , ty:: Term < ' tcx > > = if is_const {
20362034 let did = assoc_ty. item . def_id ;
20372035 let identity_args = crate :: traits:: GenericArgs :: identity_for_item ( tcx, did) ;
@@ -2040,7 +2038,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20402038 } else {
20412039 tcx. type_of ( assoc_ty. item . def_id ) . map_bound ( |ty| ty. into ( ) )
20422040 } ;
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) {
20442043 let err = Ty :: new_error_with_message (
20452044 tcx,
20462045 obligation. cause . span ,
@@ -2050,7 +2049,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20502049 } else {
20512050 assoc_ty_own_obligations ( selcx, obligation, & mut nested) ;
20522051 Progress { term : term. instantiate ( tcx, args) , obligations : nested }
2053- }
2052+ } ;
2053+ Ok ( Projected :: Progress ( progress) )
20542054}
20552055
20562056// Get obligations corresponding to the predicates from the where-clause of the
0 commit comments