-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #108339 - GuillaumeGomez:rollup-4z02kas, r=GuillaumeGomez
Rollup of 8 pull requests Successful merges: - #108110 (Move some `InferCtxt` methods to `EvalCtxt` in new solver) - #108168 (Fix ICE on type alias in recursion) - #108230 (Convert a hard-warning about named static lifetimes into lint "unused_lifetimes") - #108239 (Fix overlapping spans in removing extra arguments) - #108246 (Add an InstCombine for redundant casts) - #108264 (no-fail-fast support for tool testsuites) - #108310 (rustdoc: Fix duplicated attributes for first reexport) - #108318 (Remove unused FileDesc::get_cloexec) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
- Loading branch information
Showing
47 changed files
with
562 additions
and
400 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
use rustc_hir::def_id::DefId; | ||
use rustc_infer::infer::at::ToTrace; | ||
use rustc_infer::infer::canonical::CanonicalVarValues; | ||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; | ||
use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; | ||
use rustc_infer::traits::query::NoSolution; | ||
use rustc_infer::traits::ObligationCause; | ||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; | ||
use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable}; | ||
use rustc_span::DUMMY_SP; | ||
use std::ops::ControlFlow; | ||
|
||
use super::search_graph::SearchGraph; | ||
use super::Goal; | ||
|
||
pub struct EvalCtxt<'a, 'tcx> { | ||
// FIXME: should be private. | ||
pub(super) infcx: &'a InferCtxt<'tcx>, | ||
|
||
pub(super) var_values: CanonicalVarValues<'tcx>, | ||
|
||
pub(super) search_graph: &'a mut SearchGraph<'tcx>, | ||
|
||
/// This field is used by a debug assertion in [`EvalCtxt::evaluate_goal`], | ||
/// see the comment in that method for more details. | ||
pub in_projection_eq_hack: bool, | ||
} | ||
|
||
impl<'tcx> EvalCtxt<'_, 'tcx> { | ||
pub(super) fn probe<T>(&mut self, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> T) -> T { | ||
self.infcx.probe(|_| f(self)) | ||
} | ||
|
||
pub(super) fn tcx(&self) -> TyCtxt<'tcx> { | ||
self.infcx.tcx | ||
} | ||
|
||
pub(super) fn next_ty_infer(&self) -> Ty<'tcx> { | ||
self.infcx.next_ty_var(TypeVariableOrigin { | ||
kind: TypeVariableOriginKind::MiscVariable, | ||
span: DUMMY_SP, | ||
}) | ||
} | ||
|
||
pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> { | ||
self.infcx.next_const_var( | ||
ty, | ||
ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP }, | ||
) | ||
} | ||
|
||
/// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`. | ||
/// | ||
/// This is the case if the `term` is an inference variable in the innermost universe | ||
/// and does not occur in any other part of the predicate. | ||
pub(super) fn term_is_fully_unconstrained( | ||
&self, | ||
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>, | ||
) -> bool { | ||
let term_is_infer = match goal.predicate.term.unpack() { | ||
ty::TermKind::Ty(ty) => { | ||
if let &ty::Infer(ty::TyVar(vid)) = ty.kind() { | ||
match self.infcx.probe_ty_var(vid) { | ||
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"), | ||
Err(universe) => universe == self.universe(), | ||
} | ||
} else { | ||
false | ||
} | ||
} | ||
ty::TermKind::Const(ct) => { | ||
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() { | ||
match self.infcx.probe_const_var(vid) { | ||
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"), | ||
Err(universe) => universe == self.universe(), | ||
} | ||
} else { | ||
false | ||
} | ||
} | ||
}; | ||
|
||
// Guard against `<T as Trait<?0>>::Assoc = ?0>`. | ||
struct ContainsTerm<'tcx> { | ||
term: ty::Term<'tcx>, | ||
} | ||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> { | ||
type BreakTy = (); | ||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { | ||
if t.needs_infer() { | ||
if ty::Term::from(t) == self.term { | ||
ControlFlow::Break(()) | ||
} else { | ||
t.super_visit_with(self) | ||
} | ||
} else { | ||
ControlFlow::Continue(()) | ||
} | ||
} | ||
|
||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { | ||
if c.needs_infer() { | ||
if ty::Term::from(c) == self.term { | ||
ControlFlow::Break(()) | ||
} else { | ||
c.super_visit_with(self) | ||
} | ||
} else { | ||
ControlFlow::Continue(()) | ||
} | ||
} | ||
} | ||
|
||
let mut visitor = ContainsTerm { term: goal.predicate.term }; | ||
|
||
term_is_infer | ||
&& goal.predicate.projection_ty.visit_with(&mut visitor).is_continue() | ||
&& goal.param_env.visit_with(&mut visitor).is_continue() | ||
} | ||
|
||
#[instrument(level = "debug", skip(self, param_env), ret)] | ||
pub(super) fn eq<T: ToTrace<'tcx>>( | ||
&self, | ||
param_env: ty::ParamEnv<'tcx>, | ||
lhs: T, | ||
rhs: T, | ||
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> { | ||
self.infcx | ||
.at(&ObligationCause::dummy(), param_env) | ||
.eq(lhs, rhs) | ||
.map(|InferOk { value: (), obligations }| { | ||
obligations.into_iter().map(|o| o.into()).collect() | ||
}) | ||
.map_err(|e| { | ||
debug!(?e, "failed to equate"); | ||
NoSolution | ||
}) | ||
} | ||
|
||
pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<'tcx> + Copy>( | ||
&self, | ||
value: ty::Binder<'tcx, T>, | ||
) -> T { | ||
self.infcx.instantiate_binder_with_fresh_vars( | ||
DUMMY_SP, | ||
LateBoundRegionConversionTime::HigherRankedType, | ||
value, | ||
) | ||
} | ||
|
||
pub(super) fn instantiate_binder_with_placeholders<T: TypeFoldable<'tcx> + Copy>( | ||
&self, | ||
value: ty::Binder<'tcx, T>, | ||
) -> T { | ||
self.infcx.instantiate_binder_with_placeholders(value) | ||
} | ||
|
||
pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T | ||
where | ||
T: TypeFoldable<'tcx>, | ||
{ | ||
self.infcx.resolve_vars_if_possible(value) | ||
} | ||
|
||
pub(super) fn fresh_substs_for_item(&self, def_id: DefId) -> ty::SubstsRef<'tcx> { | ||
self.infcx.fresh_substs_for_item(DUMMY_SP, def_id) | ||
} | ||
|
||
pub(super) fn universe(&self) -> ty::UniverseIndex { | ||
self.infcx.universe() | ||
} | ||
} |
Oops, something went wrong.