diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src')
11 files changed, 71 insertions, 80 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 65d21518491..d486416f22a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1323,23 +1323,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { label_or_note(span, terr.to_string(self.tcx)); label_or_note(sp, msg); } - } else { - if let Some(values) = values - && let Some((e, f)) = values.ty() - && let TypeError::ArgumentSorts(..) | TypeError::Sorts(_) = terr - { - let e = self.tcx.erase_regions(e); - let f = self.tcx.erase_regions(f); - let expected = with_forced_trimmed_paths!(e.sort_string(self.tcx)); - let found = with_forced_trimmed_paths!(f.sort_string(self.tcx)); - if expected == found { - label_or_note(span, terr.to_string(self.tcx)); - } else { - label_or_note(span, Cow::from(format!("expected {expected}, found {found}"))); - } - } else { + } else if let Some(values) = values + && let Some((e, f)) = values.ty() + && let TypeError::ArgumentSorts(..) | TypeError::Sorts(_) = terr + { + let e = self.tcx.erase_regions(e); + let f = self.tcx.erase_regions(f); + let expected = with_forced_trimmed_paths!(e.sort_string(self.tcx)); + let found = with_forced_trimmed_paths!(f.sort_string(self.tcx)); + if expected == found { label_or_note(span, terr.to_string(self.tcx)); + } else { + label_or_note(span, Cow::from(format!("expected {expected}, found {found}"))); } + } else { + label_or_note(span, terr.to_string(self.tcx)); } if let Some((expected, found, path)) = expected_found { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 38d06f53fa6..b8ac83e8f96 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -842,14 +842,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { lifetime: Region<'tcx>, add_lt_suggs: &mut Vec<(Span, String)>, ) -> String { - struct LifetimeReplaceVisitor<'tcx, 'a> { + struct LifetimeReplaceVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, needle: hir::LifetimeName, new_lt: &'a str, add_lt_suggs: &'a mut Vec<(Span, String)>, } - impl<'hir, 'tcx> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'tcx, '_> { + impl<'hir, 'tcx> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'_, 'tcx> { fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) { if lt.res == self.needle { self.add_lt_suggs.push(lt.suggestion(self.new_lt)); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 9aa6d1f3d46..752ef729113 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -344,7 +344,8 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti write!( w, - " {} for {}", + " {}{} for {}", + tcx.impl_polarity(impl_def_id).as_str(), trait_ref.print_only_trait_path(), tcx.type_of(impl_def_id).instantiate_identity() ) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 45e157b1080..e2796c76412 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -61,9 +61,9 @@ pub enum CoroutineInteriorOrUpvar { // This type provides a uniform interface to retrieve data on coroutines, whether it originated from // the local crate being compiled or from a foreign crate. #[derive(Debug)] -struct CoroutineData<'tcx, 'a>(&'a TypeckResults<'tcx>); +struct CoroutineData<'a, 'tcx>(&'a TypeckResults<'tcx>); -impl<'tcx, 'a> CoroutineData<'tcx, 'a> { +impl<'a, 'tcx> CoroutineData<'a, 'tcx> { /// Try to get information about variables captured by the coroutine that matches a type we are /// looking for with `ty_matches` function. We uses it to find upvar which causes a failure to /// meet an obligation @@ -3237,16 +3237,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // then the tuple must be the one containing capture types. let is_upvar_tys_infer_tuple = if !matches!(ty.kind(), ty::Tuple(..)) { false + } else if let ObligationCauseCode::BuiltinDerived(data) = &*data.parent_code { + let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); + let nested_ty = parent_trait_ref.skip_binder().self_ty(); + matches!(nested_ty.kind(), ty::Coroutine(..)) + || matches!(nested_ty.kind(), ty::Closure(..)) } else { - if let ObligationCauseCode::BuiltinDerived(data) = &*data.parent_code { - let parent_trait_ref = - self.resolve_vars_if_possible(data.parent_trait_pred); - let nested_ty = parent_trait_ref.skip_binder().self_ty(); - matches!(nested_ty.kind(), ty::Coroutine(..)) - || matches!(nested_ty.kind(), ty::Closure(..)) - } else { - false - } + false }; if !is_upvar_tys_infer_tuple { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index f5f36f40f7e..cfc73e2e47e 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -302,7 +302,7 @@ fn fulfillment_error_for_stalled<'tcx>( Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => ( FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) }, // Don't look into overflows because we treat overflows weirdly anyways. - // In `instantiate_response_discarding_overflow` we set `has_changed = false`, + // We discard the inference constraints from overflowing goals, so // recomputing the goal again during `find_best_leaf_obligation` may apply // inference guidance that makes other goals go from ambig -> pass, for example. // diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index c8811bc37b3..de1d4ef15ac 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -35,8 +35,10 @@ where if infcx.next_trait_solver() { Box::new(NextFulfillmentCtxt::new(infcx)) } else { + let new_solver_globally = + infcx.tcx.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally); assert!( - !infcx.tcx.next_trait_solver_globally(), + !new_solver_globally, "using old solver even though new solver is enabled globally" ); Box::new(FulfillmentContext::new(infcx)) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 630acc91fbe..c27a9285b3a 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -408,7 +408,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( debug!("opt_normalize_projection_type: found error"); let result = normalize_to_error(selcx, param_env, projection_term, cause, depth); obligations.extend(result.obligations); - return Ok(Some(result.value.into())); + return Ok(Some(result.value)); } } @@ -478,7 +478,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( } let result = normalize_to_error(selcx, param_env, projection_term, cause, depth); obligations.extend(result.obligations); - Ok(Some(result.value.into())) + Ok(Some(result.value)) } } } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index f1b524d1325..525fba69a87 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -25,7 +25,7 @@ use crate::traits::{ }; #[extension(pub trait QueryNormalizeExt<'tcx>)] -impl<'cx, 'tcx> At<'cx, 'tcx> { +impl<'a, 'tcx> At<'a, 'tcx> { /// Normalize `value` in the context of the inference context, /// yielding a resulting type, or an error if `value` cannot be /// normalized. If you don't care about regions, you should prefer @@ -160,9 +160,9 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor { } } -struct QueryNormalizer<'cx, 'tcx> { - infcx: &'cx InferCtxt<'tcx>, - cause: &'cx ObligationCause<'tcx>, +struct QueryNormalizer<'a, 'tcx> { + infcx: &'a InferCtxt<'tcx>, + cause: &'a ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, obligations: Vec<PredicateObligation<'tcx>>, cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>, @@ -170,7 +170,7 @@ struct QueryNormalizer<'cx, 'tcx> { universes: Vec<Option<ty::UniverseIndex>>, } -impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> { +impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> { type Error = NoSolution; fn cx(&self) -> TyCtxt<'tcx> { 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 77efc2fc2db..3e3589538c7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -426,13 +426,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else if kind == ty::ClosureKind::FnOnce { candidates.vec.push(ClosureCandidate { is_const }); } + } else if kind == ty::ClosureKind::FnOnce { + candidates.vec.push(ClosureCandidate { is_const }); } else { - if kind == ty::ClosureKind::FnOnce { - candidates.vec.push(ClosureCandidate { is_const }); - } else { - // This stays ambiguous until kind+upvars are determined. - candidates.ambiguous = true; - } + // This stays ambiguous until kind+upvars are determined. + candidates.ambiguous = true; } } ty::Infer(ty::TyVar(_)) => { @@ -513,10 +511,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // then there's nothing else to check. if let Some(closure_kind) = self_ty.to_opt_closure_kind() && let Some(goal_kind) = target_kind_ty.to_opt_closure_kind() + && closure_kind.extends(goal_kind) { - if closure_kind.extends(goal_kind) { - candidates.vec.push(AsyncFnKindHelperCandidate); - } + candidates.vec.push(AsyncFnKindHelperCandidate); } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 241c3a3d141..f5cd7273ca2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1334,16 +1334,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } - if self.can_use_global_caches(param_env) { - if !trait_pred.has_infer() { - debug!(?trait_pred, ?result, "insert_evaluation_cache global"); - // This may overwrite the cache with the same value - // FIXME: Due to #50507 this overwrites the different values - // This should be changed to use HashMapExt::insert_same - // when that is fixed - self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result); - return; - } + if self.can_use_global_caches(param_env) && !trait_pred.has_infer() { + debug!(?trait_pred, ?result, "insert_evaluation_cache global"); + // This may overwrite the cache with the same value + // FIXME: Due to #50507 this overwrites the different values + // This should be changed to use HashMapExt::insert_same + // when that is fixed + self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result); + return; } debug!(?trait_pred, ?result, "insert_evaluation_cache"); @@ -1584,13 +1582,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if self.can_use_global_caches(param_env) { if let Err(Overflow(OverflowError::Canonical)) = candidate { // Don't cache overflow globally; we only produce this in certain modes. - } else if !pred.has_infer() { - if !candidate.has_infer() { - debug!(?pred, ?candidate, "insert_candidate_cache global"); - // This may overwrite the cache with the same value. - tcx.selection_cache.insert((param_env, pred), dep_node, candidate); - return; - } + } else if !pred.has_infer() && !candidate.has_infer() { + debug!(?pred, ?candidate, "insert_candidate_cache global"); + // This may overwrite the cache with the same value. + tcx.selection_cache.insert((param_env, pred), dep_node, candidate); + return; } } @@ -1980,10 +1976,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // impls have to be always applicable, meaning that the only allowed // region constraints may be constraints also present on the default impl. let tcx = self.tcx(); - if other.evaluation.must_apply_modulo_regions() { - if tcx.specializes((other_def, victim_def)) { - return DropVictim::Yes; - } + if other.evaluation.must_apply_modulo_regions() + && tcx.specializes((other_def, victim_def)) + { + return DropVictim::Yes; } match tcx.impls_are_allowed_to_overlap(other_def, victim_def) { diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 0fb13799e67..99445d03965 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -332,8 +332,8 @@ pub fn with_replaced_escaping_bound_vars< } } -pub struct BoundVarReplacer<'me, 'tcx> { - infcx: &'me InferCtxt<'tcx>, +pub struct BoundVarReplacer<'a, 'tcx> { + infcx: &'a InferCtxt<'tcx>, // These three maps track the bound variable that were replaced by placeholders. It might be // nice to remove these since we already have the `kind` in the placeholder; we really just need // the `var` (but we *could* bring that into scope if we were to track them as we pass them). @@ -345,15 +345,15 @@ pub struct BoundVarReplacer<'me, 'tcx> { current_index: ty::DebruijnIndex, // The `UniverseIndex` of the binding levels above us. These are optional, since we are lazy: // we don't actually create a universe until we see a bound var we have to replace. - universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>, + universe_indices: &'a mut Vec<Option<ty::UniverseIndex>>, } -impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> { +impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> { /// Returns `Some` if we *were* able to replace bound vars. If there are any bound vars that /// use a binding level above `universe_indices.len()`, we fail. pub fn replace_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>( - infcx: &'me InferCtxt<'tcx>, - universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>, + infcx: &'a InferCtxt<'tcx>, + universe_indices: &'a mut Vec<Option<ty::UniverseIndex>>, value: T, ) -> ( T, @@ -479,22 +479,22 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> { } /// The inverse of [`BoundVarReplacer`]: replaces placeholders with the bound vars from which they came. -pub struct PlaceholderReplacer<'me, 'tcx> { - infcx: &'me InferCtxt<'tcx>, +pub struct PlaceholderReplacer<'a, 'tcx> { + infcx: &'a InferCtxt<'tcx>, mapped_regions: FxIndexMap<ty::PlaceholderRegion, ty::BoundRegion>, mapped_types: FxIndexMap<ty::PlaceholderType, ty::BoundTy>, mapped_consts: BTreeMap<ty::PlaceholderConst, ty::BoundVar>, - universe_indices: &'me [Option<ty::UniverseIndex>], + universe_indices: &'a [Option<ty::UniverseIndex>], current_index: ty::DebruijnIndex, } -impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> { +impl<'a, 'tcx> PlaceholderReplacer<'a, 'tcx> { pub fn replace_placeholders<T: TypeFoldable<TyCtxt<'tcx>>>( - infcx: &'me InferCtxt<'tcx>, + infcx: &'a InferCtxt<'tcx>, mapped_regions: FxIndexMap<ty::PlaceholderRegion, ty::BoundRegion>, mapped_types: FxIndexMap<ty::PlaceholderType, ty::BoundTy>, mapped_consts: BTreeMap<ty::PlaceholderConst, ty::BoundVar>, - universe_indices: &'me [Option<ty::UniverseIndex>], + universe_indices: &'a [Option<ty::UniverseIndex>], value: T, ) -> T { let mut replacer = PlaceholderReplacer { |
