diff options
| author | Michael Goulet <michael@errs.io> | 2023-02-21 18:27:17 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-02-23 02:12:51 +0000 |
| commit | 9bf32c40b4c1b7558aee3421ed3e8e73ef518dd9 (patch) | |
| tree | c41aba5c5a5e475749366249a8f8820364411a3d /compiler/rustc_trait_selection/src/traits | |
| parent | 02b3664766f1053746a3068c6eed6c464d8a40dc (diff) | |
| download | rust-9bf32c40b4c1b7558aee3421ed3e8e73ef518dd9.tar.gz rust-9bf32c40b4c1b7558aee3421ed3e8e73ef518dd9.zip | |
Don't project specializable RPITIT projection
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 279725b16d8..c9e46ba41b0 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1307,21 +1307,38 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>( let _ = selcx.infcx.commit_if_ok(|_| { match selcx.select(&obligation.with(tcx, trait_predicate)) { Ok(Some(super::ImplSource::UserDefined(data))) => { - candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(data)); - Ok(()) + let Ok(leaf_def) = specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) else { + return Err(()); + }; + // Only reveal a specializable default if we're past type-checking + // and the obligation is monomorphic, otherwise passes such as + // transmute checking and polymorphic MIR optimizations could + // get a result which isn't correct for all monomorphizations. + if leaf_def.is_final() + || (obligation.param_env.reveal() == Reveal::All + && !selcx + .infcx + .resolve_vars_if_possible(obligation.predicate.trait_ref(tcx)) + .still_further_specializable()) + { + candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(data)); + Ok(()) + } else { + Err(()) + } } Ok(None) => { candidate_set.mark_ambiguous(); - return Err(()); + Err(()) } Ok(Some(_)) => { // Don't know enough about the impl to provide a useful signature - return Err(()); + Err(()) } Err(e) => { debug!(error = ?e, "selection error"); candidate_set.mark_error(e); - return Err(()); + Err(()) } } }); |
