Skip to content

Commit ca97579

Browse files
committed
Move duplicated functions to common place
1 parent 17b45b9 commit ca97579

3 files changed

Lines changed: 76 additions & 118 deletions

File tree

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 4 additions & 66 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::errors::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
};
@@ -695,70 +697,6 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
695697
Some(bounds)
696698
}
697699

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

compiler/rustc_trait_selection/src/regions.rs

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +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};
8-
use rustc_span::Span;
10+
use rustc_middle::ty::{self, Ty, TyCtxt, TypingMode, Unnormalized, elaborate};
11+
use rustc_span::{DUMMY_SP, Span};
912

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

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)