diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_infer/src/infer/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/opaque_types.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/undo_log.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/traits/project.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/arena.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/select.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/lifetimes.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_type_ir/src/lib.rs | 8 |
12 files changed, 34 insertions, 17 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 6f88b83a473..3ff14a10b90 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -891,6 +891,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .region_constraints_added_in_snapshot(&snapshot.undo_snapshot) } + pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'a, 'tcx>) -> bool { + self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot) + } + pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) { self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup); } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 7684d861f3c..41a53705450 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -103,7 +103,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } let (a, b) = if a_is_expected { (a, b) } else { (b, a) }; let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() { - ty::Opaque(def_id, substs) => { + ty::Opaque(def_id, substs) if def_id.is_local() => { let origin = if self.defining_use_anchor.is_some() { // Check that this is `impl Trait` type is // declared by `parent_def_id` -- i.e., one whose diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs index 1b696f21cbc..74a26ebc39f 100644 --- a/compiler/rustc_infer/src/infer/undo_log.rs +++ b/compiler/rustc_infer/src/infer/undo_log.rs @@ -185,6 +185,10 @@ impl<'tcx> InferCtxtUndoLogs<'tcx> { }) } + pub(crate) fn opaque_types_in_snapshot(&self, s: &Snapshot<'tcx>) -> bool { + self.logs[s.undo_len..].iter().any(|log| matches!(log, UndoLog::OpaqueTypes(..))) + } + pub(crate) fn region_constraints( &self, ) -> impl Iterator<Item = &'_ region_constraints::UndoLog<'tcx>> + Clone { diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index b84ed3dc689..18469208731 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -203,7 +203,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { Some(&ProjectionCacheEntry::NormalizedTy { ref ty, complete: _ }) => { info!("ProjectionCacheEntry::complete({:?}) - completing {:?}", key, ty); let mut ty = ty.clone(); - if result == EvaluationResult::EvaluatedToOk { + if result.must_apply_considering_regions() { ty.obligations = vec![]; } map.insert(key, ProjectionCacheEntry::NormalizedTy { ty, complete: Some(result) }); diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 984c95b314b..661a9b1944c 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -96,6 +96,7 @@ macro_rules! arena_types { // (during lowering) and the `librustc_middle` arena (for decoding MIR) [decode] asm_template: rustc_ast::InlineAsmTemplatePiece, [decode] used_trait_imports: rustc_data_structures::fx::FxHashSet<rustc_hir::def_id::LocalDefId>, + [decode] is_late_bound_map: rustc_data_structures::fx::FxIndexSet<rustc_hir::def_id::LocalDefId>, [decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, [] dep_kind: rustc_middle::dep_graph::DepKindStruct, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index ca2c03cb614..29a691f2546 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1572,7 +1572,7 @@ rustc_queries! { Option<&'tcx FxHashMap<ItemLocalId, Region>> { desc { "looking up a named region" } } - query is_late_bound_map(_: LocalDefId) -> Option<&'tcx FxHashSet<LocalDefId>> { + query is_late_bound_map(_: LocalDefId) -> Option<&'tcx FxIndexSet<LocalDefId>> { desc { "testing if a region is late bound" } } /// For a given item (like a struct), gets the default lifetimes to be used diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index ffa70cddbd5..854dd215a37 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -176,6 +176,10 @@ pub enum EvaluationResult { EvaluatedToOk, /// Evaluation successful, but there were unevaluated region obligations. EvaluatedToOkModuloRegions, + /// Evaluation successful, but need to rerun because opaque types got + /// hidden types assigned without it being known whether the opaque types + /// are within their defining scope + EvaluatedToOkModuloOpaqueTypes, /// Evaluation is known to be ambiguous -- it *might* hold for some /// assignment of inference variables, but it might not. /// @@ -252,9 +256,11 @@ impl EvaluationResult { pub fn may_apply(self) -> bool { match self { - EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToUnknown => { - true - } + EvaluatedToOkModuloOpaqueTypes + | EvaluatedToOk + | EvaluatedToOkModuloRegions + | EvaluatedToAmbig + | EvaluatedToUnknown => true, EvaluatedToErr | EvaluatedToRecur => false, } @@ -264,7 +270,11 @@ impl EvaluationResult { match self { EvaluatedToUnknown | EvaluatedToRecur => true, - EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToErr => false, + EvaluatedToOkModuloOpaqueTypes + | EvaluatedToOk + | EvaluatedToOkModuloRegions + | EvaluatedToAmbig + | EvaluatedToErr => false, } } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 00403ff044c..4d7aa0d9ed5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1105,6 +1105,7 @@ impl<'tcx> InstantiatedPredicates<'tcx> { Lift )] pub struct OpaqueTypeKey<'tcx> { + // FIXME(oli-obk): make this a LocalDefId pub def_id: DefId, pub substs: SubstsRef<'tcx>, } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index ed5d1165c7d..557dbecfabe 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2539,12 +2539,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { /// "Constrained" basically means that it appears in any type but /// not amongst the inputs to a projection. In other words, `<&'a /// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`. -fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxHashSet<LocalDefId>> { +fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<LocalDefId>> { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let decl = tcx.hir().fn_decl_by_hir_id(hir_id)?; let generics = tcx.hir().get_generics(def_id)?; - let mut late_bound = FxHashSet::default(); + let mut late_bound = FxIndexSet::default(); let mut constrained_by_input = ConstrainedCollector::default(); for arg_ty in decl.inputs { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index fbe66d7dcdd..6c91aa1556d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -777,6 +777,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { Ok( EvaluationResult::EvaluatedToOk | EvaluationResult::EvaluatedToOkModuloRegions + | EvaluationResult::EvaluatedToOkModuloOpaqueTypes | EvaluationResult::EvaluatedToAmbig, ) => {} _ => return false, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 297fbfa1c32..2641faff80f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -394,6 +394,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Err(_) => return Ok(EvaluatedToErr), } + if self.infcx.opaque_types_added_in_snapshot(snapshot) { + return Ok(result.max(EvaluatedToOkModuloOpaqueTypes)); + } + match self.infcx.region_constraints_added_in_snapshot(snapshot) { None => Ok(result), Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)), diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index cb1602816ae..fe9a1554b99 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -203,14 +203,6 @@ bitflags! { | TypeFlags::HAS_CT_INFER.bits | TypeFlags::HAS_TY_PLACEHOLDER.bits | TypeFlags::HAS_CT_PLACEHOLDER.bits - // The `evaluate_obligation` query does not return further - // obligations. If it evaluates an obligation with an opaque - // type, that opaque type may get compared to another type, - // constraining it. We would lose this information. - // FIXME: differentiate between crate-local opaque types - // and opaque types from other crates, as only opaque types - // from the local crate can possibly be a local name - | TypeFlags::HAS_TY_OPAQUE.bits // We consider 'freshened' types and constants // to depend on a particular fn. // The freshening process throws away information, |
