diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src')
6 files changed, 30 insertions, 6 deletions
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 5af912fee54..c7b8f063196 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -4,7 +4,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::ty::{ - self, GenericArgKind, GenericArgs, OpaqueTypeKey, TyCtxt, TypeVisitableExt, + self, DefiningScopeKind, GenericArgKind, GenericArgs, OpaqueTypeKey, TyCtxt, TypeVisitableExt, TypingMode, fold_regions, }; use rustc_span::{ErrorGuaranteed, Span}; @@ -21,19 +21,36 @@ pub fn check_opaque_type_parameter_valid<'tcx>( infcx: &InferCtxt<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>, span: Span, + defining_scope_kind: DefiningScopeKind, ) -> Result<(), ErrorGuaranteed> { let tcx = infcx.tcx; let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); + // Avoid duplicate errors in case the opaque has already been malformed in + // HIR typeck. + if let DefiningScopeKind::MirBorrowck = defining_scope_kind { + if let Err(guar) = infcx + .tcx + .type_of_opaque_hir_typeck(opaque_type_key.def_id) + .instantiate_identity() + .error_reported() + { + return Err(guar); + } + } + for (i, arg) in opaque_type_key.iter_captured_args(tcx) { let arg_is_param = match arg.unpack() { + GenericArgKind::Lifetime(lt) => match defining_scope_kind { + DefiningScopeKind::HirTypeck => continue, + DefiningScopeKind::MirBorrowck => { + matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) + || (lt.is_static() && opaque_env.param_equal_static(i)) + } + }, GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), - GenericArgKind::Lifetime(lt) => { - matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) - || (lt.is_static() && opaque_env.param_equal_static(i)) - } GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)), }; diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index f2725411e13..e0b425fa739 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -195,6 +195,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< match self.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => false, TypingMode::PostAnalysis => { let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref); diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index ad62b456ad4..4ac45172a0e 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -130,6 +130,7 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>( // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis TypingMode::Coherence | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), TypingMode::PostAnalysis => {} } @@ -226,6 +227,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis TypingMode::Coherence | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => ty.super_fold_with(self), TypingMode::PostAnalysis => { let recursion_limit = self.cx().recursion_limit(); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 6057b66c483..349569d750e 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -952,6 +952,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( match selcx.infcx.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => { debug!( assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id), diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 165c63f3745..5dbb4382fd1 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -216,6 +216,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> { match self.infcx.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => ty.try_super_fold_with(self)?, TypingMode::PostAnalysis => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0679dbf1296..d78938225f1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1446,6 +1446,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.infcx.typing_mode() { TypingMode::Coherence => {} TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } | TypingMode::PostAnalysis => return Ok(()), } @@ -1491,7 +1492,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // However, if we disqualify *all* goals from being cached, perf suffers. // This is likely fixed by better caching in general in the new solver. // See: <https://github.com/rust-lang/rust/issues/132064>. - TypingMode::Analysis { defining_opaque_types } => { + TypingMode::Analysis { defining_opaque_types } + | TypingMode::Borrowck { defining_opaque_types } => { defining_opaque_types.is_empty() || !pred.has_opaque_types() } // The hidden types of `defined_opaque_types` is not local to the current |
