diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:03:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:03:36 +0000 |
commit | 17d40c6057c88f4c432b0d7bac88e1b84cb7e67f (patch) | |
tree | 3f66c4a5918660bb8a758ab6cda5ff8ee4f6cdcd /compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs | |
parent | Adding upstream version 1.64.0+dfsg1. (diff) | |
download | rustc-f7f0cc2a5d72e2c61c1f6900e70eec992bea4273.tar.xz rustc-f7f0cc2a5d72e2c61c1f6900e70eec992bea4273.zip |
Adding upstream version 1.65.0+dfsg1.upstream/1.65.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index a60ce0f34..a80527f63 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -8,7 +8,7 @@ use hir::LangItem; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_infer::traits::TraitEngine; +use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -28,7 +28,7 @@ use super::SelectionCandidate::{self, *}; use super::{EvaluatedCandidate, SelectionCandidateSet, SelectionContext, TraitObligationStack}; impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { - #[instrument(level = "debug", skip(self))] + #[instrument(level = "debug", skip(self), ret)] pub(super) fn candidate_from_obligation<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, @@ -48,7 +48,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let Some(c) = self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred) { - debug!(candidate = ?c, "CACHE HIT"); + debug!("CACHE HIT"); return c; } @@ -61,7 +61,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let (candidate, dep_node) = self.in_task(|this| this.candidate_from_obligation_no_cache(stack)); - debug!(?candidate, "CACHE MISS"); + debug!("CACHE MISS"); self.insert_candidate_cache( stack.obligation.param_env, cache_fresh_trait_pred, @@ -75,7 +75,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { - if let Some(conflict) = self.is_knowable(stack) { + if let Err(conflict) = self.is_knowable(stack) { debug!("coherence stage: not knowable"); if self.intercrate_ambiguity_causes.is_some() { debug!("evaluate_stack: intercrate_ambiguity_causes is some"); @@ -309,6 +309,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // User-defined transmutability impls are permitted. self.assemble_candidates_from_impls(obligation, &mut candidates); self.assemble_candidates_for_transmutability(obligation, &mut candidates); + } else if lang_items.tuple_trait() == Some(def_id) { + self.assemble_candidate_for_tuple(obligation, &mut candidates); } else { if lang_items.clone_trait() == Some(def_id) { // Same builtin conditions as `Copy`, i.e., every type which has builtin support @@ -337,7 +339,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Ok(candidates) } - #[tracing::instrument(level = "debug", skip(self, candidates))] + #[instrument(level = "debug", skip(self, candidates))] fn assemble_candidates_from_projected_tys( &mut self, obligation: &TraitObligation<'tcx>, @@ -367,7 +369,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// supplied to find out whether it is listed among them. /// /// Never affects the inference environment. - #[tracing::instrument(level = "debug", skip(self, stack, candidates))] + #[instrument(level = "debug", skip(self, stack, candidates))] fn assemble_candidates_from_caller_bounds<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, @@ -706,8 +708,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn need_migrate_deref_output_trait_object( &mut self, ty: Ty<'tcx>, - cause: &traits::ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, + cause: &ObligationCause<'tcx>, ) -> Option<(Ty<'tcx>, DefId)> { let tcx = self.tcx(); if tcx.features().trait_upcasting { @@ -729,24 +731,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return None; } - let mut fulfillcx = traits::FulfillmentContext::new_in_snapshot(); - let normalized_ty = fulfillcx.normalize_projection_type( - &self.infcx, + let ty = traits::normalize_projection_type( + self, param_env, ty::ProjectionTy { item_def_id: tcx.lang_items().deref_target()?, substs: trait_ref.substs, }, cause.clone(), - ); - - let ty::Dynamic(data, ..) = normalized_ty.kind() else { - return None; - }; - - let def_id = data.principal_def_id()?; - - return Some((normalized_ty, def_id)); + 0, + // We're *intentionally* throwing these away, + // since we don't actually use them. + &mut vec![], + ) + .ty() + .unwrap(); + + if let ty::Dynamic(data, ..) = ty.kind() { + Some((ty, data.principal_def_id()?)) + } else { + None + } } /// Searches for unsizing that might apply to `obligation`. @@ -809,8 +814,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let Some((deref_output_ty, deref_output_trait_did)) = self .need_migrate_deref_output_trait_object( source, - &obligation.cause, obligation.param_env, + &obligation.cause, ) { if deref_output_trait_did == target_trait_did { @@ -877,7 +882,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }; } - #[tracing::instrument(level = "debug", skip(self, obligation, candidates))] + #[instrument(level = "debug", skip(self, obligation, candidates))] fn assemble_candidates_for_transmutability( &mut self, obligation: &TraitObligation<'tcx>, @@ -895,7 +900,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates.vec.push(TransmutabilityCandidate); } - #[tracing::instrument(level = "debug", skip(self, obligation, candidates))] + #[instrument(level = "debug", skip(self, obligation, candidates))] fn assemble_candidates_for_trait_alias( &mut self, obligation: &TraitObligation<'tcx>, @@ -914,7 +919,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Assembles the trait which are built-in to the language itself: /// `Copy`, `Clone` and `Sized`. - #[tracing::instrument(level = "debug", skip(self, candidates))] + #[instrument(level = "debug", skip(self, candidates))] fn assemble_builtin_bound_candidates( &mut self, conditions: BuiltinImplConditions<'tcx>, @@ -1006,4 +1011,46 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } } + + fn assemble_candidate_for_tuple( + &mut self, + obligation: &TraitObligation<'tcx>, + candidates: &mut SelectionCandidateSet<'tcx>, + ) { + let self_ty = self.infcx().shallow_resolve(obligation.self_ty().skip_binder()); + match self_ty.kind() { + ty::Tuple(_) => { + candidates.vec.push(TupleCandidate); + } + ty::Infer(ty::TyVar(_)) => { + candidates.ambiguous = true; + } + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Adt(_, _) + | ty::Foreign(_) + | ty::Str + | ty::Array(_, _) + | ty::Slice(_) + | ty::RawPtr(_) + | ty::Ref(_, _, _) + | ty::FnDef(_, _) + | ty::FnPtr(_) + | ty::Dynamic(_, _, _) + | ty::Closure(_, _) + | ty::Generator(_, _, _) + | ty::GeneratorWitness(_) + | ty::Never + | ty::Projection(_) + | ty::Opaque(_, _) + | ty::Param(_) + | ty::Bound(_, _) + | ty::Error(_) + | ty::Infer(_) + | ty::Placeholder(_) => {} + } + } } |