Skip to content

Commit 10a9ee0

Browse files
committed
Auto merge of #131404 - matthiaskrgr:rollup-z0dawoo, r=matthiaskrgr
Rollup of 3 pull requests Successful merges: - #131348 (More `rustc_infer` cleanups) - #131392 (Drop compiletest legacy directive check) - #131395 (Add a mailmap entry for bjorn3) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 68e4d96 + 37a8ad8 commit 10a9ee0

File tree

15 files changed

+219
-347
lines changed

15 files changed

+219
-347
lines changed

.mailmap

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Ben Striegel <[email protected]>
7474
Benjamin Jackman <[email protected]>
7575
Benoît Cortier <[email protected]>
7676
Bheesham Persaud <[email protected]> Bheesham Persaud <[email protected]>
77+
7778
7879
blake2-ppc <[email protected]> <blake2-ppc>
7980
blyxyas <[email protected]> Alejandra González <[email protected]>

compiler/rustc_infer/src/infer/mod.rs

+29-25
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub use relate::combine::PredicateEmittingRelation;
1818
use rustc_data_structures::captures::Captures;
1919
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
2020
use rustc_data_structures::sync::Lrc;
21-
use rustc_data_structures::undo_log::Rollback;
21+
use rustc_data_structures::undo_log::{Rollback, UndoLogs};
2222
use rustc_data_structures::unify as ut;
2323
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed};
2424
use rustc_hir as hir;
@@ -50,6 +50,7 @@ use snapshot::undo_log::InferCtxtUndoLogs;
5050
use tracing::{debug, instrument};
5151
use type_variable::TypeVariableOrigin;
5252

53+
use crate::infer::region_constraints::UndoLog;
5354
use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
5455

5556
pub mod at;
@@ -67,6 +68,13 @@ pub mod resolve;
6768
pub(crate) mod snapshot;
6869
mod type_variable;
6970

71+
/// `InferOk<'tcx, ()>` is used a lot. It may seem like a useless wrapper
72+
/// around `Vec<PredicateObligation<'tcx>>`, but it has one important property:
73+
/// because `InferOk` is marked with `#[must_use]`, if you have a method
74+
/// `InferCtxt::f` that returns `InferResult<'tcx, ()>` and you call it with
75+
/// `infcx.f()?;` you'll get a warning about the obligations being discarded
76+
/// without use, which is probably unintentional and has been a source of bugs
77+
/// in the past.
7078
#[must_use]
7179
#[derive(Debug)]
7280
pub struct InferOk<'tcx, T> {
@@ -163,12 +171,12 @@ impl<'tcx> InferCtxtInner<'tcx> {
163171
undo_log: InferCtxtUndoLogs::default(),
164172

165173
projection_cache: Default::default(),
166-
type_variable_storage: type_variable::TypeVariableStorage::new(),
167-
const_unification_storage: ut::UnificationTableStorage::new(),
168-
int_unification_storage: ut::UnificationTableStorage::new(),
169-
float_unification_storage: ut::UnificationTableStorage::new(),
170-
effect_unification_storage: ut::UnificationTableStorage::new(),
171-
region_constraint_storage: Some(RegionConstraintStorage::new()),
174+
type_variable_storage: Default::default(),
175+
const_unification_storage: Default::default(),
176+
int_unification_storage: Default::default(),
177+
float_unification_storage: Default::default(),
178+
effect_unification_storage: Default::default(),
179+
region_constraint_storage: Some(Default::default()),
172180
region_obligations: vec![],
173181
opaque_type_storage: Default::default(),
174182
}
@@ -1004,8 +1012,8 @@ impl<'tcx> InferCtxt<'tcx> {
10041012
ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid)).into()
10051013
}
10061014

1007-
/// Given a set of generics defined on a type or impl, returns the generic parameters mapping each
1008-
/// type/region parameter to a fresh inference variable.
1015+
/// Given a set of generics defined on a type or impl, returns the generic parameters mapping
1016+
/// each type/region parameter to a fresh inference variable.
10091017
pub fn fresh_args_for_item(&self, span: Span, def_id: DefId) -> GenericArgsRef<'tcx> {
10101018
GenericArgs::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param))
10111019
}
@@ -1036,18 +1044,14 @@ impl<'tcx> InferCtxt<'tcx> {
10361044
/// Clone the list of variable regions. This is used only during NLL processing
10371045
/// to put the set of region variables into the NLL region context.
10381046
pub fn get_region_var_origins(&self) -> VarInfos {
1039-
let mut inner = self.inner.borrow_mut();
1040-
let (var_infos, data) = inner
1041-
.region_constraint_storage
1042-
// We clone instead of taking because borrowck still wants to use
1043-
// the inference context after calling this for diagnostics
1044-
// and the new trait solver.
1045-
.clone()
1046-
.expect("regions already resolved")
1047-
.with_log(&mut inner.undo_log)
1048-
.into_infos_and_data();
1049-
assert!(data.is_empty());
1050-
var_infos
1047+
let inner = self.inner.borrow();
1048+
assert!(!UndoLogs::<UndoLog<'_>>::in_snapshot(&inner.undo_log));
1049+
let storage = inner.region_constraint_storage.as_ref().expect("regions already resolved");
1050+
assert!(storage.data.is_empty());
1051+
// We clone instead of taking because borrowck still wants to use the
1052+
// inference context after calling this for diagnostics and the new
1053+
// trait solver.
1054+
storage.var_infos.clone()
10511055
}
10521056

10531057
#[instrument(level = "debug", skip(self), ret)]
@@ -1383,10 +1387,10 @@ impl<'tcx> InferCtxt<'tcx> {
13831387
///
13841388
/// The constant can be located on a trait like `<A as B>::C`, in which case the given
13851389
/// generic parameters and environment are used to resolve the constant. Alternatively if the
1386-
/// constant has generic parameters in scope the instantiations are used to evaluate the value of
1387-
/// the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
1388-
/// constant `bar::<T>()` requires a instantiation for `T`, if the instantiation for `T` is still
1389-
/// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
1390+
/// constant has generic parameters in scope the instantiations are used to evaluate the value
1391+
/// of the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
1392+
/// constant `bar::<T>()` requires a instantiation for `T`, if the instantiation for `T` is
1393+
/// still too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
13901394
/// returned.
13911395
///
13921396
/// This handles inferences variables within both `param_env` and `args` by

compiler/rustc_infer/src/infer/opaque_types/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,11 @@ impl<'tcx> InferCtxt<'tcx> {
148148
}
149149

150150
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
151-
// We could accept this, but there are various ways to handle this situation, and we don't
152-
// want to make a decision on it right now. Likely this case is so super rare anyway, that
153-
// no one encounters it in practice.
154-
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
155-
// where it is of no concern, so we only check for TAITs.
151+
// We could accept this, but there are various ways to handle this situation,
152+
// and we don't want to make a decision on it right now. Likely this case is so
153+
// super rare anyway, that no one encounters it in practice. It does occur
154+
// however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`, where
155+
// it is of no concern, so we only check for TAITs.
156156
if self.can_define_opaque_ty(b_def_id)
157157
&& self.tcx.is_type_alias_impl_trait(b_def_id)
158158
{
+26-61
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use rustc_data_structures::fx::FxIndexSet;
22
use rustc_data_structures::transitive_relation::TransitiveRelationBuilder;
3-
use rustc_middle::bug;
4-
use rustc_middle::ty::{self, Region};
5-
use tracing::{debug, instrument};
3+
use rustc_middle::{bug, ty};
4+
use tracing::debug;
65

76
use super::explicit_outlives_bounds;
87
use crate::infer::GenericKind;
@@ -54,94 +53,44 @@ pub struct OutlivesEnvironment<'tcx> {
5453
region_bound_pairs: RegionBoundPairs<'tcx>,
5554
}
5655

57-
/// Builder of OutlivesEnvironment.
58-
#[derive(Debug)]
59-
struct OutlivesEnvironmentBuilder<'tcx> {
60-
param_env: ty::ParamEnv<'tcx>,
61-
region_relation: TransitiveRelationBuilder<Region<'tcx>>,
62-
region_bound_pairs: RegionBoundPairs<'tcx>,
63-
}
64-
6556
/// "Region-bound pairs" tracks outlives relations that are known to
6657
/// be true, either because of explicit where-clauses like `T: 'a` or
6758
/// because of implied bounds.
6859
pub type RegionBoundPairs<'tcx> = FxIndexSet<ty::OutlivesPredicate<'tcx, GenericKind<'tcx>>>;
6960

7061
impl<'tcx> OutlivesEnvironment<'tcx> {
71-
/// Create a builder using `ParamEnv` and add explicit outlives bounds into it.
72-
fn builder(param_env: ty::ParamEnv<'tcx>) -> OutlivesEnvironmentBuilder<'tcx> {
73-
let mut builder = OutlivesEnvironmentBuilder {
74-
param_env,
75-
region_relation: Default::default(),
76-
region_bound_pairs: Default::default(),
77-
};
78-
79-
builder.add_outlives_bounds(explicit_outlives_bounds(param_env));
80-
81-
builder
82-
}
83-
84-
#[inline]
8562
/// Create a new `OutlivesEnvironment` without extra outlives bounds.
63+
#[inline]
8664
pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
87-
Self::builder(param_env).build()
65+
Self::with_bounds(param_env, vec![])
8866
}
8967

9068
/// Create a new `OutlivesEnvironment` with extra outlives bounds.
9169
pub fn with_bounds(
9270
param_env: ty::ParamEnv<'tcx>,
9371
extra_bounds: impl IntoIterator<Item = OutlivesBound<'tcx>>,
9472
) -> Self {
95-
let mut builder = Self::builder(param_env);
96-
builder.add_outlives_bounds(extra_bounds);
97-
builder.build()
98-
}
73+
let mut region_relation = TransitiveRelationBuilder::default();
74+
let mut region_bound_pairs = RegionBoundPairs::default();
9975

100-
/// Borrows current value of the `free_region_map`.
101-
pub fn free_region_map(&self) -> &FreeRegionMap<'tcx> {
102-
&self.free_region_map
103-
}
104-
105-
/// Borrows current `region_bound_pairs`.
106-
pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
107-
&self.region_bound_pairs
108-
}
109-
}
110-
111-
impl<'tcx> OutlivesEnvironmentBuilder<'tcx> {
112-
#[inline]
113-
#[instrument(level = "debug")]
114-
fn build(self) -> OutlivesEnvironment<'tcx> {
115-
OutlivesEnvironment {
116-
param_env: self.param_env,
117-
free_region_map: FreeRegionMap { relation: self.region_relation.freeze() },
118-
region_bound_pairs: self.region_bound_pairs,
119-
}
120-
}
121-
122-
/// Processes outlives bounds that are known to hold, whether from implied or other sources.
123-
fn add_outlives_bounds<I>(&mut self, outlives_bounds: I)
124-
where
125-
I: IntoIterator<Item = OutlivesBound<'tcx>>,
126-
{
12776
// Record relationships such as `T:'x` that don't go into the
12877
// free-region-map but which we use here.
129-
for outlives_bound in outlives_bounds {
78+
for outlives_bound in explicit_outlives_bounds(param_env).chain(extra_bounds) {
13079
debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
13180
match outlives_bound {
13281
OutlivesBound::RegionSubParam(r_a, param_b) => {
133-
self.region_bound_pairs
82+
region_bound_pairs
13483
.insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
13584
}
13685
OutlivesBound::RegionSubAlias(r_a, alias_b) => {
137-
self.region_bound_pairs
86+
region_bound_pairs
13887
.insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a));
13988
}
14089
OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) {
14190
(
14291
ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
14392
ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
144-
) => self.region_relation.add(r_a, r_b),
93+
) => region_relation.add(r_a, r_b),
14594
(ty::ReError(_), _) | (_, ty::ReError(_)) => {}
14695
// FIXME(#109628): We shouldn't have existential variables in implied bounds.
14796
// Panic here once the linked issue is resolved!
@@ -150,5 +99,21 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> {
15099
},
151100
}
152101
}
102+
103+
OutlivesEnvironment {
104+
param_env,
105+
free_region_map: FreeRegionMap { relation: region_relation.freeze() },
106+
region_bound_pairs,
107+
}
108+
}
109+
110+
/// Borrows current value of the `free_region_map`.
111+
pub fn free_region_map(&self) -> &FreeRegionMap<'tcx> {
112+
&self.free_region_map
113+
}
114+
115+
/// Borrows current `region_bound_pairs`.
116+
pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
117+
&self.region_bound_pairs
153118
}
154119
}

compiler/rustc_infer/src/infer/outlives/mod.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
//! Various code related to computing outlives relations.
22
3+
use rustc_data_structures::undo_log::UndoLogs;
34
use rustc_middle::traits::query::{NoSolution, OutlivesBound};
45
use rustc_middle::ty;
56
use tracing::instrument;
67

78
use self::env::OutlivesEnvironment;
8-
use super::region_constraints::RegionConstraintData;
9+
use super::region_constraints::{RegionConstraintData, UndoLog};
910
use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
1011
use crate::infer::free_regions::RegionRelations;
1112
use crate::infer::lexical_region_resolve;
@@ -63,26 +64,22 @@ impl<'tcx> InferCtxt<'tcx> {
6364
}
6465
};
6566

66-
let (var_infos, data) = {
67+
let storage = {
6768
let mut inner = self.inner.borrow_mut();
6869
let inner = &mut *inner;
6970
assert!(
7071
self.tainted_by_errors().is_some() || inner.region_obligations.is_empty(),
7172
"region_obligations not empty: {:#?}",
7273
inner.region_obligations
7374
);
74-
inner
75-
.region_constraint_storage
76-
.take()
77-
.expect("regions already resolved")
78-
.with_log(&mut inner.undo_log)
79-
.into_infos_and_data()
75+
assert!(!UndoLogs::<UndoLog<'_>>::in_snapshot(&inner.undo_log));
76+
inner.region_constraint_storage.take().expect("regions already resolved")
8077
};
8178

8279
let region_rels = &RegionRelations::new(self.tcx, outlives_env.free_region_map());
8380

8481
let (lexical_region_resolutions, errors) =
85-
lexical_region_resolve::resolve(region_rels, var_infos, data);
82+
lexical_region_resolve::resolve(region_rels, storage.var_infos, storage.data);
8683

8784
let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
8885
assert!(old_value.is_none());

compiler/rustc_infer/src/infer/outlives/obligations.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -396,11 +396,12 @@ where
396396
// 'a` in the environment but `trait Foo<'b> { type Item: 'b
397397
// }` in the trait definition.
398398
approx_env_bounds.retain(|bound_outlives| {
399-
// OK to skip binder because we only manipulate and compare against other
400-
// values from the same binder. e.g. if we have (e.g.) `for<'a> <T as Trait<'a>>::Item: 'a`
401-
// in `bound`, the `'a` will be a `^1` (bound, debruijn index == innermost) region.
402-
// If the declaration is `trait Trait<'b> { type Item: 'b; }`, then `projection_declared_bounds_from_trait`
403-
// will be invoked with `['b => ^1]` and so we will get `^1` returned.
399+
// OK to skip binder because we only manipulate and compare against other values from
400+
// the same binder. e.g. if we have (e.g.) `for<'a> <T as Trait<'a>>::Item: 'a` in
401+
// `bound`, the `'a` will be a `^1` (bound, debruijn index == innermost) region. If the
402+
// declaration is `trait Trait<'b> { type Item: 'b; }`, then
403+
// `projection_declared_bounds_from_trait` will be invoked with `['b => ^1]` and so we
404+
// will get `^1` returned.
404405
let bound = bound_outlives.skip_binder();
405406
let ty::Alias(_, alias_ty) = bound.0.kind() else { bug!("expected AliasTy") };
406407
self.verify_bound.declared_bounds_from_definition(*alias_ty).all(|r| r != bound.1)

0 commit comments

Comments
 (0)