Skip to content

Commit 0718cad

Browse files
committed
Move duplicated functions to common place
1 parent 9ff8d67 commit 0718cad

3 files changed

Lines changed: 75 additions & 116 deletions

File tree

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use rustc_hir::def::{DefKind, Res};
1313
use rustc_hir::def_id::{DefId, LocalDefId};
1414
use rustc_hir::lang_items::LangItem;
1515
use rustc_hir::{AmbigArg, ItemKind, find_attr};
16+
use rustc_infer::infer::TyCtxtInferExt;
1617
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
17-
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin, TyCtxtInferExt};
1818
use rustc_infer::traits::PredicateObligations;
1919
use rustc_lint_defs::builtin::SHADOWING_SUPERTRAIT_ITEMS;
2020
use rustc_macros::Diagnostic;
@@ -30,7 +30,9 @@ use rustc_middle::{bug, span_bug};
3030
use rustc_session::parse::feature_err;
3131
use rustc_span::{DUMMY_SP, Span, sym};
3232
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
33-
use rustc_trait_selection::regions::{InferCtxtRegionExt, OutlivesEnvironmentBuildExt};
33+
use rustc_trait_selection::regions::{
34+
InferCtxtRegionExt, OutlivesEnvironmentBuildExt, region_known_to_outlive, ty_known_to_outlive,
35+
};
3436
use rustc_trait_selection::traits::misc::{
3537
ConstParamTyImplementationError, type_allowed_to_implement_const_param_ty,
3638
};
@@ -694,69 +696,6 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
694696
Some(bounds)
695697
}
696698

697-
/// Given a known `param_env` and a set of well formed types, can we prove that
698-
/// `ty` outlives `region`.
699-
fn ty_known_to_outlive<'tcx>(
700-
tcx: TyCtxt<'tcx>,
701-
id: LocalDefId,
702-
param_env: ty::ParamEnv<'tcx>,
703-
wf_tys: &FxIndexSet<Ty<'tcx>>,
704-
ty: Ty<'tcx>,
705-
region: ty::Region<'tcx>,
706-
) -> bool {
707-
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
708-
infcx.register_type_outlives_constraint_inner(infer::TypeOutlivesConstraint {
709-
sub_region: region,
710-
sup_type: ty,
711-
origin: SubregionOrigin::RelateParamBound(DUMMY_SP, ty, None),
712-
});
713-
})
714-
}
715-
716-
/// Given a known `param_env` and a set of well formed types, can we prove that
717-
/// `region_a` outlives `region_b`
718-
fn region_known_to_outlive<'tcx>(
719-
tcx: TyCtxt<'tcx>,
720-
id: LocalDefId,
721-
param_env: ty::ParamEnv<'tcx>,
722-
wf_tys: &FxIndexSet<Ty<'tcx>>,
723-
region_a: ty::Region<'tcx>,
724-
region_b: ty::Region<'tcx>,
725-
) -> bool {
726-
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
727-
infcx.sub_regions(
728-
SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None),
729-
region_b,
730-
region_a,
731-
);
732-
})
733-
}
734-
735-
/// Given a known `param_env` and a set of well formed types, set up an
736-
/// `InferCtxt`, call the passed function (to e.g. set up region constraints
737-
/// to be tested), then resolve region and return errors
738-
fn test_region_obligations<'tcx>(
739-
tcx: TyCtxt<'tcx>,
740-
id: LocalDefId,
741-
param_env: ty::ParamEnv<'tcx>,
742-
wf_tys: &FxIndexSet<Ty<'tcx>>,
743-
add_constraints: impl FnOnce(&InferCtxt<'tcx>),
744-
) -> bool {
745-
// Unfortunately, we have to use a new `InferCtxt` each call, because
746-
// region constraints get added and solved there and we need to test each
747-
// call individually.
748-
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
749-
750-
add_constraints(&infcx);
751-
752-
let errors = infcx.resolve_regions(id, param_env, wf_tys.iter().copied());
753-
debug!(?errors, "errors");
754-
755-
// If we were able to prove that the type outlives the region without
756-
// an error, it must be because of the implied or explicit bounds...
757-
errors.is_empty()
758-
}
759-
760699
/// TypeVisitor that looks for uses of GATs like
761700
/// `<P0 as Trait<P1..Pn>>::GAT<Pn..Pm>` and adds the arguments `P0..Pm` into
762701
/// the two vectors, `regions` and `types` (depending on their kind). For each

compiler/rustc_trait_selection/src/regions.rs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
use rustc_data_structures::fx::FxIndexSet;
12
use rustc_hir::def_id::LocalDefId;
23
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
3-
use rustc_infer::infer::{InferCtxt, RegionResolutionError};
4+
use rustc_infer::infer::{
5+
InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt, TypeOutlivesConstraint,
6+
};
47
use rustc_macros::extension;
58
use rustc_middle::traits::ObligationCause;
69
use rustc_middle::traits::query::NoSolution;
7-
use rustc_middle::ty::{self, Ty, Unnormalized, elaborate};
10+
use rustc_middle::ty::{self, Ty, TyCtxt, TypingMode, Unnormalized, elaborate};
11+
use rustc_span::DUMMY_SP;
812

913
use crate::traits::ScrubbedTraitError;
1014
use crate::traits::outlives_bounds::InferCtxtExt;
@@ -116,3 +120,66 @@ impl<'tcx> InferCtxt<'tcx> {
116120
})
117121
}
118122
}
123+
124+
/// Given a known `param_env` and a set of well formed types, can we prove that
125+
/// `ty` outlives `region`.
126+
pub fn ty_known_to_outlive<'tcx>(
127+
tcx: TyCtxt<'tcx>,
128+
id: LocalDefId,
129+
param_env: ty::ParamEnv<'tcx>,
130+
wf_tys: &FxIndexSet<Ty<'tcx>>,
131+
ty: Ty<'tcx>,
132+
region: ty::Region<'tcx>,
133+
) -> bool {
134+
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
135+
infcx.register_type_outlives_constraint_inner(TypeOutlivesConstraint {
136+
sub_region: region,
137+
sup_type: ty,
138+
origin: SubregionOrigin::RelateParamBound(DUMMY_SP, ty, None),
139+
});
140+
})
141+
}
142+
143+
/// Given a known `param_env` and a set of well formed types, can we prove that
144+
/// `region_a` outlives `region_b`
145+
pub fn region_known_to_outlive<'tcx>(
146+
tcx: TyCtxt<'tcx>,
147+
id: LocalDefId,
148+
param_env: ty::ParamEnv<'tcx>,
149+
wf_tys: &FxIndexSet<Ty<'tcx>>,
150+
region_a: ty::Region<'tcx>,
151+
region_b: ty::Region<'tcx>,
152+
) -> bool {
153+
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
154+
infcx.sub_regions(
155+
SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None),
156+
region_b,
157+
region_a,
158+
);
159+
})
160+
}
161+
162+
/// Given a known `param_env` and a set of well formed types, set up an
163+
/// `InferCtxt`, call the passed function (to e.g. set up region constraints
164+
/// to be tested), then resolve region and return errors
165+
pub fn test_region_obligations<'tcx>(
166+
tcx: TyCtxt<'tcx>,
167+
id: LocalDefId,
168+
param_env: ty::ParamEnv<'tcx>,
169+
wf_tys: &FxIndexSet<Ty<'tcx>>,
170+
add_constraints: impl FnOnce(&InferCtxt<'tcx>),
171+
) -> bool {
172+
// Unfortunately, we have to use a new `InferCtxt` each call, because
173+
// region constraints get added and solved there and we need to test each
174+
// call individually.
175+
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
176+
177+
add_constraints(&infcx);
178+
179+
let errors = infcx.resolve_regions(id, param_env, wf_tys.iter().copied());
180+
tracing::debug!(?errors, "errors");
181+
182+
// If we were able to prove that the type outlives the region without
183+
// an error, it must be because of the implied or explicit bounds...
184+
errors.is_empty()
185+
}

compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1-
use rustc_data_structures::fx::FxIndexSet;
21
use rustc_data_structures::indexmap::IndexSet;
32
use rustc_hir::def_id::LocalDefId;
43
use rustc_middle::ty::{
54
self, Flags, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
6-
TypingMode, Unnormalized,
5+
Unnormalized,
76
};
8-
use rustc_span::DUMMY_SP;
97

108
use crate::infer::outlives::test_type_match;
119
use crate::infer::region_constraints::VerifyIfEq;
12-
use crate::infer::{InferCtxt, SubregionOrigin, TyCtxtInferExt};
13-
use crate::regions::InferCtxtRegionExt;
10+
use crate::regions::region_known_to_outlive;
1411

1512
/// For a given opaque type, this returns the set of generic args that are relevant for liveness, that can be inferred
1613
/// from outlives bounds on the opaque.
@@ -292,47 +289,3 @@ where
292289
}
293290
}
294291
}
295-
296-
/// Given a known `param_env` and a set of well formed types, can we prove that
297-
/// `region_a` outlives `region_b`
298-
fn region_known_to_outlive<'tcx>(
299-
tcx: TyCtxt<'tcx>,
300-
id: LocalDefId,
301-
param_env: ty::ParamEnv<'tcx>,
302-
wf_tys: &FxIndexSet<Ty<'tcx>>,
303-
region_a: ty::Region<'tcx>,
304-
region_b: ty::Region<'tcx>,
305-
) -> bool {
306-
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
307-
infcx.sub_regions(
308-
SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None),
309-
region_b,
310-
region_a,
311-
);
312-
})
313-
}
314-
315-
/// Given a known `param_env` and a set of well formed types, set up an
316-
/// `InferCtxt`, call the passed function (to e.g. set up region constraints
317-
/// to be tested), then resolve region and return errors
318-
fn test_region_obligations<'tcx>(
319-
tcx: TyCtxt<'tcx>,
320-
id: LocalDefId,
321-
param_env: ty::ParamEnv<'tcx>,
322-
wf_tys: &FxIndexSet<Ty<'tcx>>,
323-
add_constraints: impl FnOnce(&InferCtxt<'tcx>),
324-
) -> bool {
325-
// Unfortunately, we have to use a new `InferCtxt` each call, because
326-
// region constraints get added and solved there and we need to test each
327-
// call individually.
328-
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
329-
330-
add_constraints(&infcx);
331-
332-
let errors = infcx.resolve_regions(id, param_env, wf_tys.iter().copied());
333-
tracing::debug!(?errors, "errors");
334-
335-
// If we were able to prove that the type outlives the region without
336-
// an error, it must be because of the implied or explicit bounds...
337-
errors.is_empty()
338-
}

0 commit comments

Comments
 (0)