Auto merge of #125665 - matthiaskrgr:rollup-srkx0v1, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #117671 (NVPTX: Avoid PassMode::Direct for args in C abi) - #125573 (Migrate `run-make/allow-warnings-cmdline-stability` to `rmake.rs`) - #125590 (Add a "Setup Python" action for github-hosted runners and remove unnecessary `CUSTOM_MINGW` environment variable) - #125598 (Make `ProofTreeBuilder` actually generic over `Interner`) - #125637 (rustfmt fixes) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
274499dd0f
34 changed files with 720 additions and 286 deletions
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
|
@ -154,9 +154,12 @@ jobs:
|
|||
|
||||
- name: checkout submodules
|
||||
run: src/ci/scripts/checkout-submodules.sh
|
||||
|
||||
- name: install MSYS2
|
||||
run: src/ci/scripts/install-msys2.sh
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
if: runner.environment == 'github-hosted'
|
||||
|
||||
- name: install MinGW
|
||||
run: src/ci/scripts/install-mingw.sh
|
||||
|
|
|
@ -218,6 +218,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
self.check_and_mk_args(def_id, args)
|
||||
}
|
||||
|
||||
fn intern_canonical_goal_evaluation_step(
|
||||
self,
|
||||
step: solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>,
|
||||
) -> &'tcx solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>> {
|
||||
self.arena.alloc(step)
|
||||
}
|
||||
|
||||
fn parent(self, def_id: Self::DefId) -> Self::DefId {
|
||||
self.parent(def_id)
|
||||
}
|
||||
|
|
|
@ -219,10 +219,8 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
|
|||
for (i, field) in variant.fields.iter_enumerated() {
|
||||
let field_ty = field.ty(self.tcx, args);
|
||||
if field_ty == *cast_ty {
|
||||
let place = place.project_deeper(
|
||||
&[ProjectionElem::Field(i, *cast_ty)],
|
||||
self.tcx,
|
||||
);
|
||||
let place = place
|
||||
.project_deeper(&[ProjectionElem::Field(i, *cast_ty)], self.tcx);
|
||||
let operand = if operand.is_move() {
|
||||
Operand::Move(place)
|
||||
} else {
|
||||
|
|
|
@ -691,7 +691,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
location,
|
||||
format!(
|
||||
"You can't project to field {f:?} of `DynMetadata` because \
|
||||
layout is weird and thinks it doesn't have fields."
|
||||
layout is weird and thinks it doesn't have fields."
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,11 +11,10 @@ fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
|
|||
}
|
||||
|
||||
fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
|
||||
if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 {
|
||||
arg.make_indirect();
|
||||
} else {
|
||||
// FIXME: this is wrong! Need to decide which ABI we really want here.
|
||||
arg.make_direct_deprecated();
|
||||
if arg.layout.is_aggregate() {
|
||||
arg.make_indirect_byval(None);
|
||||
} else if arg.layout.size.bits() < 32 {
|
||||
arg.extend_integer_width_to(32);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
&mut self,
|
||||
goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let Goal { param_env, predicate: (lhs, rhs, direction) } = goal;
|
||||
debug_assert!(lhs.to_alias_term().is_some() || rhs.to_alias_term().is_some());
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ pub(super) trait GoalKind<'tcx>:
|
|||
assumption: ty::Clause<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
|
||||
bug!("expected object type in `probe_and_consider_object_bound_candidate`");
|
||||
};
|
||||
|
@ -288,8 +288,10 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
|
||||
}
|
||||
|
||||
let goal: Goal<'tcx, G> =
|
||||
goal.with(self.tcx(), goal.predicate.with_self_ty(self.tcx(), normalized_self_ty));
|
||||
let goal: Goal<'tcx, G> = goal.with(
|
||||
self.interner(),
|
||||
goal.predicate.with_self_ty(self.interner(), normalized_self_ty),
|
||||
);
|
||||
// Vars that show up in the rest of the goal substs may have been constrained by
|
||||
// normalizing the self type as well, since type variables are not uniquified.
|
||||
let goal = self.resolve_vars_if_possible(goal);
|
||||
|
@ -339,7 +341,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx));
|
||||
let mut consider_impls_for_simplified_type = |simp| {
|
||||
|
@ -455,7 +457,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx));
|
||||
for &impl_def_id in trait_impls.blanket_impls() {
|
||||
// For every `default impl`, there's always a non-default `impl`
|
||||
|
@ -478,7 +480,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let lang_items = tcx.lang_items();
|
||||
let trait_def_id = goal.predicate.trait_def_id(tcx);
|
||||
|
||||
|
@ -505,9 +507,9 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
G::consider_builtin_pointer_like_candidate(self, goal)
|
||||
} else if lang_items.fn_ptr_trait() == Some(trait_def_id) {
|
||||
G::consider_builtin_fn_ptr_trait_candidate(self, goal)
|
||||
} else if let Some(kind) = self.tcx().fn_trait_kind_from_def_id(trait_def_id) {
|
||||
} else if let Some(kind) = self.interner().fn_trait_kind_from_def_id(trait_def_id) {
|
||||
G::consider_builtin_fn_trait_candidates(self, goal, kind)
|
||||
} else if let Some(kind) = self.tcx().async_fn_trait_kind_from_def_id(trait_def_id) {
|
||||
} else if let Some(kind) = self.interner().async_fn_trait_kind_from_def_id(trait_def_id) {
|
||||
G::consider_builtin_async_fn_trait_candidates(self, goal, kind)
|
||||
} else if lang_items.async_fn_kind_helper() == Some(trait_def_id) {
|
||||
G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
|
||||
|
@ -634,7 +636,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
|
||||
ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
|
||||
ty::Alias(ty::Inherent | ty::Weak, _) => {
|
||||
self.tcx().sess.dcx().span_delayed_bug(
|
||||
self.interner().sess.dcx().span_delayed_bug(
|
||||
DUMMY_SP,
|
||||
format!("could not normalize {self_ty}, it is not WF"),
|
||||
);
|
||||
|
@ -643,7 +645,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
};
|
||||
|
||||
for assumption in
|
||||
self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args)
|
||||
self.interner().item_bounds(alias_ty.def_id).instantiate(self.interner(), alias_ty.args)
|
||||
{
|
||||
candidates.extend(G::probe_and_consider_implied_clause(
|
||||
self,
|
||||
|
@ -673,7 +675,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
if !tcx.trait_def(goal.predicate.trait_def_id(tcx)).implement_via_object {
|
||||
return;
|
||||
}
|
||||
|
@ -764,7 +766,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
|
||||
candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter(
|
||||
|ecx| {
|
||||
|
@ -793,7 +795,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
goal: Goal<'tcx, G>,
|
||||
candidates: &mut Vec<Candidate<'tcx>>,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> =
|
||||
goal.with(tcx, goal.predicate.trait_ref(tcx));
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
|
|||
ecx: &EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution> {
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
match *ty.kind() {
|
||||
ty::Uint(_)
|
||||
| ty::Int(_)
|
||||
|
@ -75,7 +75,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
|
|||
}
|
||||
|
||||
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
||||
.tcx()
|
||||
.interner()
|
||||
.bound_coroutine_hidden_types(def_id)
|
||||
.map(|bty| bty.instantiate(tcx, args))
|
||||
.collect()),
|
||||
|
@ -151,8 +151,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
|
|||
// "best effort" optimization and `sized_constraint` may return `Some`, even
|
||||
// if the ADT is sized for all possible args.
|
||||
ty::Adt(def, args) => {
|
||||
if let Some(sized_crit) = def.sized_constraint(ecx.tcx()) {
|
||||
Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.tcx(), args))])
|
||||
if let Some(sized_crit) = def.sized_constraint(ecx.interner()) {
|
||||
Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.interner(), args))])
|
||||
} else {
|
||||
Ok(vec![])
|
||||
}
|
||||
|
@ -210,10 +210,10 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
|
|||
|
||||
// only when `coroutine_clone` is enabled and the coroutine is movable
|
||||
// impl Copy/Clone for Coroutine where T: Copy/Clone forall T in (upvars, witnesses)
|
||||
ty::Coroutine(def_id, args) => match ecx.tcx().coroutine_movability(def_id) {
|
||||
ty::Coroutine(def_id, args) => match ecx.interner().coroutine_movability(def_id) {
|
||||
Movability::Static => Err(NoSolution),
|
||||
Movability::Movable => {
|
||||
if ecx.tcx().features().coroutine_clone {
|
||||
if ecx.interner().features().coroutine_clone {
|
||||
let coroutine = args.as_coroutine();
|
||||
Ok(vec![
|
||||
ty::Binder::dummy(coroutine.tupled_upvars_ty()),
|
||||
|
@ -227,9 +227,9 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
|
|||
|
||||
// impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types
|
||||
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
||||
.tcx()
|
||||
.interner()
|
||||
.bound_coroutine_hidden_types(def_id)
|
||||
.map(|bty| bty.instantiate(ecx.tcx(), args))
|
||||
.map(|bty| bty.instantiate(ecx.interner(), args))
|
||||
.collect()),
|
||||
}
|
||||
}
|
||||
|
@ -666,7 +666,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
|
|||
trait_ref: ty::TraitRef<'tcx>,
|
||||
object_bound: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||
) -> Vec<Goal<'tcx, ty::Predicate<'tcx>>> {
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
let mut requirements = vec![];
|
||||
requirements.extend(
|
||||
tcx.super_predicates_of(trait_ref.def_id).instantiate(tcx, trait_ref.args).predicates,
|
||||
|
@ -722,7 +722,7 @@ struct ReplaceProjectionWith<'a, 'tcx> {
|
|||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
self.ecx.tcx()
|
||||
self.ecx.interner()
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
|
@ -739,7 +739,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> {
|
|||
.eq_and_get_goals(
|
||||
self.param_env,
|
||||
alias_ty,
|
||||
proj.projection_term.expect_ty(self.ecx.tcx()),
|
||||
proj.projection_term.expect_ty(self.ecx.interner()),
|
||||
)
|
||||
.expect("expected to be able to unify goal projection with dyn's projection"),
|
||||
);
|
||||
|
|
|
@ -16,7 +16,6 @@ use crate::solve::{
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
|
||||
use rustc_infer::infer::canonical::CanonicalVarValues;
|
||||
use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
|
||||
use rustc_infer::infer::RegionVariableOrigin;
|
||||
use rustc_infer::infer::{InferCtxt, InferOk};
|
||||
|
@ -32,22 +31,24 @@ use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable}
|
|||
use rustc_next_trait_solver::canonicalizer::{CanonicalizeMode, Canonicalizer};
|
||||
use rustc_next_trait_solver::resolve::EagerResolver;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_type_ir::CanonicalVarValues;
|
||||
use rustc_type_ir::{InferCtxtLike, Interner};
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::iter;
|
||||
use std::ops::Deref;
|
||||
|
||||
trait ResponseT<'tcx> {
|
||||
fn var_values(&self) -> CanonicalVarValues<'tcx>;
|
||||
fn var_values(&self) -> CanonicalVarValues<TyCtxt<'tcx>>;
|
||||
}
|
||||
|
||||
impl<'tcx> ResponseT<'tcx> for Response<TyCtxt<'tcx>> {
|
||||
fn var_values(&self) -> CanonicalVarValues<'tcx> {
|
||||
fn var_values(&self) -> CanonicalVarValues<TyCtxt<'tcx>> {
|
||||
self.var_values
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> ResponseT<'tcx> for inspect::State<TyCtxt<'tcx>, T> {
|
||||
fn var_values(&self) -> CanonicalVarValues<'tcx> {
|
||||
fn var_values(&self) -> CanonicalVarValues<TyCtxt<'tcx>> {
|
||||
self.var_values
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +72,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
QueryInput {
|
||||
goal,
|
||||
predefined_opaques_in_body: self
|
||||
.tcx()
|
||||
.interner()
|
||||
.mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }),
|
||||
},
|
||||
);
|
||||
|
@ -144,7 +145,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
Response {
|
||||
var_values,
|
||||
certainty,
|
||||
external_constraints: self.tcx().mk_external_constraints(external_constraints),
|
||||
external_constraints: self.interner().mk_external_constraints(external_constraints),
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -160,7 +161,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
maybe_cause: MaybeCause,
|
||||
) -> CanonicalResponse<'tcx> {
|
||||
response_no_constraints_raw(
|
||||
self.tcx(),
|
||||
self.interner(),
|
||||
self.max_input_universe,
|
||||
self.variables,
|
||||
Certainty::Maybe(maybe_cause),
|
||||
|
@ -194,7 +195,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned();
|
||||
let mut region_constraints = self.infcx.with_region_constraints(|region_constraints| {
|
||||
make_query_region_constraints(
|
||||
self.tcx(),
|
||||
self.interner(),
|
||||
region_obligations.iter().map(|r_o| {
|
||||
(r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())
|
||||
}),
|
||||
|
@ -239,7 +240,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
);
|
||||
|
||||
let Response { var_values, external_constraints, certainty } =
|
||||
response.instantiate(self.tcx(), &instantiation);
|
||||
response.instantiate(self.interner(), &instantiation);
|
||||
|
||||
Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values);
|
||||
|
||||
|
@ -260,7 +261,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
infcx: &InferCtxt<'tcx>,
|
||||
original_values: &[ty::GenericArg<'tcx>],
|
||||
response: &Canonical<'tcx, T>,
|
||||
) -> CanonicalVarValues<'tcx> {
|
||||
) -> CanonicalVarValues<TyCtxt<'tcx>> {
|
||||
// FIXME: Longterm canonical queries should deal with all placeholders
|
||||
// created inside of the query directly instead of returning them to the
|
||||
// caller.
|
||||
|
@ -354,7 +355,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
infcx: &InferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
original_values: &[ty::GenericArg<'tcx>],
|
||||
var_values: CanonicalVarValues<'tcx>,
|
||||
var_values: CanonicalVarValues<TyCtxt<'tcx>>,
|
||||
) {
|
||||
assert_eq!(original_values.len(), var_values.len());
|
||||
|
||||
|
@ -393,13 +394,18 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
/// evaluating a goal. The `var_values` not only include the bound variables
|
||||
/// of the query input, but also contain all unconstrained inference vars
|
||||
/// created while evaluating this goal.
|
||||
pub(in crate::solve) fn make_canonical_state<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
var_values: &[ty::GenericArg<'tcx>],
|
||||
pub(in crate::solve) fn make_canonical_state<Infcx, T, I>(
|
||||
infcx: &Infcx,
|
||||
var_values: &[I::GenericArg],
|
||||
max_input_universe: ty::UniverseIndex,
|
||||
data: T,
|
||||
) -> inspect::CanonicalState<TyCtxt<'tcx>, T> {
|
||||
let var_values = CanonicalVarValues { var_values: infcx.tcx.mk_args(var_values) };
|
||||
) -> inspect::CanonicalState<I, T>
|
||||
where
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
T: TypeFoldable<I>,
|
||||
{
|
||||
let var_values = CanonicalVarValues { var_values: infcx.interner().mk_args(var_values) };
|
||||
let state = inspect::State { var_values, data };
|
||||
let state = state.fold_with(&mut EagerResolver::new(infcx));
|
||||
Canonicalizer::canonicalize(
|
||||
|
|
|
@ -98,7 +98,7 @@ pub struct EvalCtxt<
|
|||
// evaluation code.
|
||||
tainted: Result<(), NoSolution>,
|
||||
|
||||
pub(super) inspect: ProofTreeBuilder<I>,
|
||||
pub(super) inspect: ProofTreeBuilder<Infcx>,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
|
@ -218,7 +218,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
search_graph: &'a mut search_graph::SearchGraph<TyCtxt<'tcx>>,
|
||||
canonical_input: CanonicalInput<'tcx>,
|
||||
canonical_goal_evaluation: &mut ProofTreeBuilder<TyCtxt<'tcx>>,
|
||||
canonical_goal_evaluation: &mut ProofTreeBuilder<InferCtxt<'tcx>>,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>, Goal<'tcx, ty::Predicate<'tcx>>) -> R,
|
||||
) -> R {
|
||||
let intercrate = match search_graph.solver_mode() {
|
||||
|
@ -280,7 +280,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
search_graph: &'a mut search_graph::SearchGraph<TyCtxt<'tcx>>,
|
||||
canonical_input: CanonicalInput<'tcx>,
|
||||
goal_evaluation: &mut ProofTreeBuilder<TyCtxt<'tcx>>,
|
||||
goal_evaluation: &mut ProofTreeBuilder<InferCtxt<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let mut canonical_goal_evaluation =
|
||||
goal_evaluation.new_canonical_goal_evaluation(canonical_input);
|
||||
|
@ -347,7 +347,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
|||
let mut goal_evaluation =
|
||||
self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
|
||||
let canonical_response = EvalCtxt::evaluate_canonical_goal(
|
||||
self.tcx(),
|
||||
self.interner(),
|
||||
self.search_graph,
|
||||
canonical_goal,
|
||||
&mut goal_evaluation,
|
||||
|
@ -450,7 +450,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
|||
}
|
||||
} else {
|
||||
self.infcx.enter_forall(kind, |kind| {
|
||||
let goal = goal.with(self.tcx(), ty::Binder::dummy(kind));
|
||||
let goal = goal.with(self.interner(), ty::Binder::dummy(kind));
|
||||
self.add_goal(GoalSource::InstantiateHigherRanked, goal);
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
})
|
||||
|
@ -511,7 +511,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
|||
///
|
||||
/// Goals for the next step get directly added to the nested goals of the `EvalCtxt`.
|
||||
fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution> {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let mut goals = core::mem::take(&mut self.nested_goals);
|
||||
|
||||
// If this loop did not result in any progress, what's our final certainty.
|
||||
|
@ -597,11 +597,13 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
pub(super) fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> EvalCtxt<'_, Infcx> {
|
||||
pub(super) fn interner(&self) -> I {
|
||||
self.infcx.interner()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
pub(super) fn next_ty_infer(&mut self) -> Ty<'tcx> {
|
||||
let ty = self.infcx.next_ty_var(DUMMY_SP);
|
||||
self.inspect.add_var_value(ty);
|
||||
|
@ -759,7 +761,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
// NOTE: this check is purely an optimization, the structural eq would
|
||||
// always fail if the term is not an inference variable.
|
||||
if term.is_infer() {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
// We need to relate `alias` to `term` treating only the outermost
|
||||
// constructor as rigid, relating any contained generic arguments as
|
||||
// normal. We do this by first structurally equating the `term`
|
||||
|
@ -1054,10 +1056,10 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
) -> Option<ty::Const<'tcx>> {
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
match self.infcx.const_eval_resolve(param_env, unevaluated, DUMMY_SP) {
|
||||
Ok(Some(val)) => Some(ty::Const::new_value(self.tcx(), val, ty)),
|
||||
Ok(Some(val)) => Some(ty::Const::new_value(self.interner(), val, ty)),
|
||||
Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None,
|
||||
Err(ErrorHandled::Reported(e, _)) => {
|
||||
Some(ty::Const::new_error(self.tcx(), e.into(), ty))
|
||||
Some(ty::Const::new_error(self.interner(), e.into(), ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1070,7 +1072,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
principal: ty::PolyTraitRef<'tcx>,
|
||||
mut supertrait_visitor: impl FnMut(&mut Self, ty::PolyTraitRef<'tcx>, usize, Option<usize>),
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let mut offset = 0;
|
||||
prepare_vtable_segments::<()>(tcx, principal, |segment| {
|
||||
match segment {
|
||||
|
@ -1112,7 +1114,7 @@ struct ReplaceAliasWithInfer<'me, 'a, 'tcx> {
|
|||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceAliasWithInfer<'_, '_, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
self.ecx.tcx()
|
||||
self.ecx.interner()
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
|
|
|
@ -3,18 +3,16 @@
|
|||
//! This code is *a bit* of a mess and can hopefully be
|
||||
//! mostly ignored. For a general overview of how it works,
|
||||
//! see the comment on [ProofTreeBuilder].
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
|
||||
use crate::solve::eval_ctxt::canonical;
|
||||
use crate::solve::{self, inspect, GenerateProofTree};
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::infer::canonical::CanonicalVarValues;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_next_trait_solver::solve::{
|
||||
CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult,
|
||||
};
|
||||
use rustc_type_ir::Interner;
|
||||
use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
|
||||
|
||||
/// The core data structure when building proof trees.
|
||||
///
|
||||
|
@ -36,7 +34,11 @@ use rustc_type_ir::Interner;
|
|||
/// trees. At the end of trait solving `ProofTreeBuilder::finalize`
|
||||
/// is called to recursively convert the whole structure to a
|
||||
/// finished proof tree.
|
||||
pub(in crate::solve) struct ProofTreeBuilder<I: Interner> {
|
||||
pub(in crate::solve) struct ProofTreeBuilder<
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner = <Infcx as InferCtxtLike>::Interner,
|
||||
> {
|
||||
_infcx: PhantomData<Infcx>,
|
||||
state: Option<Box<DebugSolver<I>>>,
|
||||
}
|
||||
|
||||
|
@ -229,36 +231,36 @@ impl<I: Interner> WipProbeStep<I> {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: Genericize this impl.
|
||||
impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
||||
fn new(state: impl Into<DebugSolver<TyCtxt<'tcx>>>) -> ProofTreeBuilder<TyCtxt<'tcx>> {
|
||||
ProofTreeBuilder { state: Some(Box::new(state.into())) }
|
||||
impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
||||
fn new(state: impl Into<DebugSolver<I>>) -> ProofTreeBuilder<Infcx> {
|
||||
ProofTreeBuilder { state: Some(Box::new(state.into())), _infcx: PhantomData }
|
||||
}
|
||||
|
||||
fn opt_nested<T: Into<DebugSolver<TyCtxt<'tcx>>>>(
|
||||
&self,
|
||||
state: impl FnOnce() -> Option<T>,
|
||||
) -> Self {
|
||||
fn opt_nested<T: Into<DebugSolver<I>>>(&self, state: impl FnOnce() -> Option<T>) -> Self {
|
||||
ProofTreeBuilder {
|
||||
state: self.state.as_ref().and_then(|_| Some(state()?.into())).map(Box::new),
|
||||
_infcx: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn nested<T: Into<DebugSolver<TyCtxt<'tcx>>>>(&self, state: impl FnOnce() -> T) -> Self {
|
||||
ProofTreeBuilder { state: self.state.as_ref().map(|_| Box::new(state().into())) }
|
||||
fn nested<T: Into<DebugSolver<I>>>(&self, state: impl FnOnce() -> T) -> Self {
|
||||
ProofTreeBuilder {
|
||||
state: self.state.as_ref().map(|_| Box::new(state().into())),
|
||||
_infcx: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn as_mut(&mut self) -> Option<&mut DebugSolver<TyCtxt<'tcx>>> {
|
||||
fn as_mut(&mut self) -> Option<&mut DebugSolver<I>> {
|
||||
self.state.as_deref_mut()
|
||||
}
|
||||
|
||||
pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder<TyCtxt<'tcx>> {
|
||||
let mut nested = ProofTreeBuilder { state: self.state.take() };
|
||||
pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder<Infcx> {
|
||||
let mut nested = ProofTreeBuilder { state: self.state.take(), _infcx: PhantomData };
|
||||
nested.enter_probe();
|
||||
nested
|
||||
}
|
||||
|
||||
pub fn finalize(self) -> Option<inspect::GoalEvaluation<TyCtxt<'tcx>>> {
|
||||
pub fn finalize(self) -> Option<inspect::GoalEvaluation<I>> {
|
||||
match *self.state? {
|
||||
DebugSolver::GoalEvaluation(wip_goal_evaluation) => {
|
||||
Some(wip_goal_evaluation.finalize())
|
||||
|
@ -267,21 +269,19 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_maybe_root(
|
||||
generate_proof_tree: GenerateProofTree,
|
||||
) -> ProofTreeBuilder<TyCtxt<'tcx>> {
|
||||
pub fn new_maybe_root(generate_proof_tree: GenerateProofTree) -> ProofTreeBuilder<Infcx> {
|
||||
match generate_proof_tree {
|
||||
GenerateProofTree::No => ProofTreeBuilder::new_noop(),
|
||||
GenerateProofTree::Yes => ProofTreeBuilder::new_root(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_root() -> ProofTreeBuilder<TyCtxt<'tcx>> {
|
||||
pub fn new_root() -> ProofTreeBuilder<Infcx> {
|
||||
ProofTreeBuilder::new(DebugSolver::Root)
|
||||
}
|
||||
|
||||
pub fn new_noop() -> ProofTreeBuilder<TyCtxt<'tcx>> {
|
||||
ProofTreeBuilder { state: None }
|
||||
pub fn new_noop() -> ProofTreeBuilder<Infcx> {
|
||||
ProofTreeBuilder { state: None, _infcx: PhantomData }
|
||||
}
|
||||
|
||||
pub fn is_noop(&self) -> bool {
|
||||
|
@ -290,10 +290,10 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
|
||||
pub(in crate::solve) fn new_goal_evaluation(
|
||||
&mut self,
|
||||
goal: Goal<TyCtxt<'tcx>, ty::Predicate<'tcx>>,
|
||||
orig_values: &[ty::GenericArg<'tcx>],
|
||||
goal: Goal<I, I::Predicate>,
|
||||
orig_values: &[I::GenericArg],
|
||||
kind: solve::GoalEvaluationKind,
|
||||
) -> ProofTreeBuilder<TyCtxt<'tcx>> {
|
||||
) -> ProofTreeBuilder<Infcx> {
|
||||
self.opt_nested(|| match kind {
|
||||
solve::GoalEvaluationKind::Root => Some(WipGoalEvaluation {
|
||||
uncanonicalized_goal: goal,
|
||||
|
@ -306,8 +306,8 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
|
||||
pub fn new_canonical_goal_evaluation(
|
||||
&mut self,
|
||||
goal: CanonicalInput<TyCtxt<'tcx>>,
|
||||
) -> ProofTreeBuilder<TyCtxt<'tcx>> {
|
||||
goal: CanonicalInput<I>,
|
||||
) -> ProofTreeBuilder<Infcx> {
|
||||
self.nested(|| WipCanonicalGoalEvaluation {
|
||||
goal,
|
||||
kind: None,
|
||||
|
@ -318,12 +318,13 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
|
||||
pub fn finalize_canonical_goal_evaluation(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Option<&'tcx inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>> {
|
||||
tcx: I,
|
||||
) -> Option<I::CanonicalGoalEvaluationStepRef> {
|
||||
self.as_mut().map(|this| match this {
|
||||
DebugSolver::CanonicalGoalEvaluation(evaluation) => {
|
||||
let final_revision = mem::take(&mut evaluation.final_revision).unwrap();
|
||||
let final_revision = &*tcx.arena.alloc(final_revision.finalize());
|
||||
let final_revision =
|
||||
tcx.intern_canonical_goal_evaluation_step(final_revision.finalize());
|
||||
let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision };
|
||||
assert_eq!(evaluation.kind.replace(kind), None);
|
||||
final_revision
|
||||
|
@ -334,7 +335,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
|
||||
pub fn canonical_goal_evaluation(
|
||||
&mut self,
|
||||
canonical_goal_evaluation: ProofTreeBuilder<TyCtxt<'tcx>>,
|
||||
canonical_goal_evaluation: ProofTreeBuilder<Infcx>,
|
||||
) {
|
||||
if let Some(this) = self.as_mut() {
|
||||
match (this, *canonical_goal_evaluation.state.unwrap()) {
|
||||
|
@ -350,10 +351,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn canonical_goal_evaluation_kind(
|
||||
&mut self,
|
||||
kind: WipCanonicalGoalEvaluationKind<TyCtxt<'tcx>>,
|
||||
) {
|
||||
pub fn canonical_goal_evaluation_kind(&mut self, kind: WipCanonicalGoalEvaluationKind<I>) {
|
||||
if let Some(this) = self.as_mut() {
|
||||
match this {
|
||||
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {
|
||||
|
@ -364,7 +362,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<TyCtxt<'tcx>>) {
|
||||
pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<Infcx>) {
|
||||
if let Some(this) = self.as_mut() {
|
||||
match this {
|
||||
DebugSolver::Root => *this = *goal_evaluation.state.unwrap(),
|
||||
|
@ -378,9 +376,9 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
|
||||
pub fn new_goal_evaluation_step(
|
||||
&mut self,
|
||||
var_values: CanonicalVarValues<'tcx>,
|
||||
instantiated_goal: QueryInput<TyCtxt<'tcx>, ty::Predicate<'tcx>>,
|
||||
) -> ProofTreeBuilder<TyCtxt<'tcx>> {
|
||||
var_values: ty::CanonicalVarValues<I>,
|
||||
instantiated_goal: QueryInput<I, I::Predicate>,
|
||||
) -> ProofTreeBuilder<Infcx> {
|
||||
self.nested(|| WipCanonicalGoalEvaluationStep {
|
||||
var_values: var_values.var_values.to_vec(),
|
||||
instantiated_goal,
|
||||
|
@ -394,7 +392,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<TyCtxt<'tcx>>) {
|
||||
pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<Infcx>) {
|
||||
if let Some(this) = self.as_mut() {
|
||||
match (this, *goal_evaluation_step.state.unwrap()) {
|
||||
(
|
||||
|
@ -408,7 +406,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_var_value<T: Into<ty::GenericArg<'tcx>>>(&mut self, arg: T) {
|
||||
pub fn add_var_value<T: Into<I::GenericArg>>(&mut self, arg: T) {
|
||||
match self.as_mut() {
|
||||
None => {}
|
||||
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
|
||||
|
@ -435,7 +433,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind<TyCtxt<'tcx>>) {
|
||||
pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind<I>) {
|
||||
match self.as_mut() {
|
||||
None => {}
|
||||
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
|
||||
|
@ -446,11 +444,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn probe_final_state(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
max_input_universe: ty::UniverseIndex,
|
||||
) {
|
||||
pub fn probe_final_state(&mut self, infcx: &Infcx, max_input_universe: ty::UniverseIndex) {
|
||||
match self.as_mut() {
|
||||
None => {}
|
||||
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
|
||||
|
@ -469,24 +463,24 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
|
||||
pub fn add_normalizes_to_goal(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
infcx: &Infcx,
|
||||
max_input_universe: ty::UniverseIndex,
|
||||
goal: Goal<TyCtxt<'tcx>, ty::NormalizesTo<'tcx>>,
|
||||
goal: Goal<I, ty::NormalizesTo<I>>,
|
||||
) {
|
||||
self.add_goal(
|
||||
infcx,
|
||||
max_input_universe,
|
||||
GoalSource::Misc,
|
||||
goal.with(infcx.tcx, goal.predicate),
|
||||
goal.with(infcx.interner(), goal.predicate),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn add_goal(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
infcx: &Infcx,
|
||||
max_input_universe: ty::UniverseIndex,
|
||||
source: GoalSource,
|
||||
goal: Goal<TyCtxt<'tcx>, ty::Predicate<'tcx>>,
|
||||
goal: Goal<I, I::Predicate>,
|
||||
) {
|
||||
match self.as_mut() {
|
||||
None => {}
|
||||
|
@ -505,9 +499,9 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
|
||||
pub(crate) fn record_impl_args(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
infcx: &Infcx,
|
||||
max_input_universe: ty::UniverseIndex,
|
||||
impl_args: ty::GenericArgsRef<'tcx>,
|
||||
impl_args: I::GenericArgs,
|
||||
) {
|
||||
match self.as_mut() {
|
||||
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
|
||||
|
@ -540,7 +534,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn finish_probe(mut self) -> ProofTreeBuilder<TyCtxt<'tcx>> {
|
||||
pub fn finish_probe(mut self) -> ProofTreeBuilder<Infcx> {
|
||||
match self.as_mut() {
|
||||
None => {}
|
||||
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
|
||||
|
@ -555,7 +549,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn query_result(&mut self, result: QueryResult<TyCtxt<'tcx>>) {
|
||||
pub fn query_result(&mut self, result: QueryResult<I>) {
|
||||
if let Some(this) = self.as_mut() {
|
||||
match this {
|
||||
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {
|
||||
|
|
|
@ -133,7 +133,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
|||
}
|
||||
|
||||
fn compute_object_safe_goal(&mut self, trait_def_id: DefId) -> QueryResult<'tcx> {
|
||||
if self.tcx().check_is_object_safe(trait_def_id) {
|
||||
if self.interner().check_is_object_safe(trait_def_id) {
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
|
@ -274,7 +274,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
if let ty::Alias(..) = ty.kind() {
|
||||
let normalized_ty = self.next_ty_infer();
|
||||
let alias_relate_goal = Goal::new(
|
||||
self.tcx(),
|
||||
self.interner(),
|
||||
param_env,
|
||||
ty::PredicateKind::AliasRelate(
|
||||
ty.into(),
|
||||
|
|
|
@ -12,7 +12,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
if let Some(normalized_const) = self.try_const_eval_resolve(
|
||||
goal.param_env,
|
||||
ty::UnevaluatedConst::new(goal.predicate.alias.def_id, goal.predicate.alias.args),
|
||||
self.tcx()
|
||||
self.interner()
|
||||
.type_of(goal.predicate.alias.def_id)
|
||||
.no_bound_vars()
|
||||
.expect("const ty should not rely on other generics"),
|
||||
|
|
|
@ -15,7 +15,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
&mut self,
|
||||
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let inherent = goal.predicate.alias.expect_ty(tcx);
|
||||
|
||||
let impl_def_id = tcx.parent(inherent.def_id);
|
||||
|
|
|
@ -54,7 +54,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
&mut self,
|
||||
goal: Goal<'tcx, NormalizesTo<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
match goal.predicate.alias.kind(self.tcx()) {
|
||||
match goal.predicate.alias.kind(self.interner()) {
|
||||
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
|
||||
let candidates = self.assemble_and_evaluate_candidates(goal);
|
||||
self.merge_candidates(candidates)
|
||||
|
@ -107,7 +107,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
if let Some(projection_pred) = assumption.as_projection_clause() {
|
||||
if projection_pred.projection_def_id() == goal.predicate.def_id() {
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
ecx.probe_trait_candidate(source).enter(|ecx| {
|
||||
let assumption_projection_pred =
|
||||
ecx.instantiate_binder_with_infer(projection_pred);
|
||||
|
@ -142,7 +142,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
goal: Goal<'tcx, NormalizesTo<'tcx>>,
|
||||
impl_def_id: DefId,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
|
||||
let goal_trait_ref = goal.predicate.alias.trait_ref(tcx);
|
||||
let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
|
||||
|
@ -290,8 +290,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
ecx.tcx().dcx().span_delayed_bug(
|
||||
ecx.tcx().def_span(goal.predicate.def_id()),
|
||||
ecx.interner().dcx().span_delayed_bug(
|
||||
ecx.interner().def_span(goal.predicate.def_id()),
|
||||
"associated types not allowed on auto traits",
|
||||
);
|
||||
Err(NoSolution)
|
||||
|
@ -337,7 +337,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
goal: Goal<'tcx, Self>,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
let tupled_inputs_and_output =
|
||||
match structural_traits::extract_tupled_inputs_and_output_from_callable(
|
||||
tcx,
|
||||
|
@ -380,7 +380,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
goal: Goal<'tcx, Self>,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
|
||||
let env_region = match goal_kind {
|
||||
ty::ClosureKind::Fn | ty::ClosureKind::FnMut => goal.predicate.alias.args.region_at(2),
|
||||
|
@ -493,7 +493,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
}
|
||||
|
||||
let upvars_ty = ty::CoroutineClosureSignature::tupled_upvars_by_closure_kind(
|
||||
ecx.tcx(),
|
||||
ecx.interner(),
|
||||
goal_kind,
|
||||
tupled_inputs_ty.expect_ty(),
|
||||
tupled_upvars_ty.expect_ty(),
|
||||
|
@ -518,7 +518,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
|
||||
goal: Goal<'tcx, Self>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
|
||||
assert_eq!(metadata_def_id, goal.predicate.def_id());
|
||||
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
|
||||
|
@ -606,7 +606,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
};
|
||||
|
||||
// Coroutines are not futures unless they come from `async` desugaring
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
if !tcx.coroutine_is_async(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
@ -618,7 +618,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||
goal,
|
||||
ty::ProjectionPredicate {
|
||||
projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]),
|
||||
projection_term: ty::AliasTerm::new(
|
||||
ecx.interner(),
|
||||
goal.predicate.def_id(),
|
||||
[self_ty],
|
||||
),
|
||||
term,
|
||||
}
|
||||
.upcast(tcx),
|
||||
|
@ -638,7 +642,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
};
|
||||
|
||||
// Coroutines are not Iterators unless they come from `gen` desugaring
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
if !tcx.coroutine_is_gen(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
@ -650,7 +654,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||
goal,
|
||||
ty::ProjectionPredicate {
|
||||
projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]),
|
||||
projection_term: ty::AliasTerm::new(
|
||||
ecx.interner(),
|
||||
goal.predicate.def_id(),
|
||||
[self_ty],
|
||||
),
|
||||
term,
|
||||
}
|
||||
.upcast(tcx),
|
||||
|
@ -677,7 +685,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
};
|
||||
|
||||
// Coroutines are not AsyncIterators unless they come from `gen` desugaring
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
if !tcx.coroutine_is_async_gen(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
@ -713,7 +721,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
};
|
||||
|
||||
// `async`-desugared coroutines do not implement the coroutine trait
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
if !tcx.is_general_coroutine(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
@ -735,7 +743,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
goal,
|
||||
ty::ProjectionPredicate {
|
||||
projection_term: ty::AliasTerm::new(
|
||||
ecx.tcx(),
|
||||
ecx.interner(),
|
||||
goal.predicate.def_id(),
|
||||
[self_ty, coroutine.resume_ty()],
|
||||
),
|
||||
|
@ -784,7 +792,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
| ty::Slice(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Tuple(_)
|
||||
| ty::Error(_) => self_ty.discriminant_ty(ecx.tcx()),
|
||||
| ty::Error(_) => self_ty.discriminant_ty(ecx.interner()),
|
||||
|
||||
// We do not call `Ty::discriminant_ty` on alias, param, or placeholder
|
||||
// types, which return `<self_ty as DiscriminantKind>::Discriminant`
|
||||
|
@ -831,7 +839,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
| ty::Str
|
||||
| ty::Slice(_)
|
||||
| ty::Tuple(_)
|
||||
| ty::Error(_) => self_ty.async_destructor_ty(ecx.tcx(), goal.param_env),
|
||||
| ty::Error(_) => self_ty.async_destructor_ty(ecx.interner(), goal.param_env),
|
||||
|
||||
// We do not call `Ty::async_destructor_ty` on alias, param, or placeholder
|
||||
// types, which return `<self_ty as AsyncDestruct>::AsyncDestructor`
|
||||
|
@ -887,8 +895,9 @@ fn fetch_eligible_assoc_item_def<'tcx>(
|
|||
trait_assoc_def_id: DefId,
|
||||
impl_def_id: DefId,
|
||||
) -> Result<Option<LeafDef>, NoSolution> {
|
||||
let node_item = specialization_graph::assoc_def(ecx.tcx(), impl_def_id, trait_assoc_def_id)
|
||||
.map_err(|ErrorGuaranteed { .. }| NoSolution)?;
|
||||
let node_item =
|
||||
specialization_graph::assoc_def(ecx.interner(), impl_def_id, trait_assoc_def_id)
|
||||
.map_err(|ErrorGuaranteed { .. }| NoSolution)?;
|
||||
|
||||
let eligible = if node_item.is_final() {
|
||||
// Non-specializable items are always projectable.
|
||||
|
|
|
@ -15,7 +15,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
&mut self,
|
||||
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let opaque_ty = goal.predicate.alias;
|
||||
let expected = goal.predicate.term.ty().expect("no such thing as an opaque const");
|
||||
|
||||
|
@ -31,7 +31,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
return Err(NoSolution);
|
||||
}
|
||||
// FIXME: This may have issues when the args contain aliases...
|
||||
match self.tcx().uses_unique_placeholders_ignoring_regions(opaque_ty.args) {
|
||||
match self.interner().uses_unique_placeholders_ignoring_regions(opaque_ty.args) {
|
||||
Err(NotUniqueParam::NotParam(param)) if param.is_non_region_infer() => {
|
||||
return self.evaluate_added_goals_and_make_canonical_response(
|
||||
Certainty::AMBIGUOUS,
|
||||
|
|
|
@ -14,7 +14,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
&mut self,
|
||||
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let weak_ty = goal.predicate.alias;
|
||||
|
||||
// Check where clauses
|
||||
|
|
|
@ -11,7 +11,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
&mut self,
|
||||
goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let projection_term = goal.predicate.projection_term.to_term(tcx);
|
||||
let goal = goal.with(
|
||||
tcx,
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::mem;
|
|||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_index::Idx;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::dep_graph::dep_kinds;
|
||||
use rustc_middle::traits::solve::CacheData;
|
||||
use rustc_middle::traits::solve::EvaluationCache;
|
||||
|
@ -261,10 +262,10 @@ impl<'tcx> SearchGraph<TyCtxt<'tcx>> {
|
|||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
input: CanonicalInput<TyCtxt<'tcx>>,
|
||||
inspect: &mut ProofTreeBuilder<TyCtxt<'tcx>>,
|
||||
inspect: &mut ProofTreeBuilder<InferCtxt<'tcx>>,
|
||||
mut prove_goal: impl FnMut(
|
||||
&mut Self,
|
||||
&mut ProofTreeBuilder<TyCtxt<'tcx>>,
|
||||
&mut ProofTreeBuilder<InferCtxt<'tcx>>,
|
||||
) -> QueryResult<TyCtxt<'tcx>>,
|
||||
) -> QueryResult<TyCtxt<'tcx>> {
|
||||
self.check_invariants();
|
||||
|
@ -426,7 +427,7 @@ impl<'tcx> SearchGraph<TyCtxt<'tcx>> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
input: CanonicalInput<TyCtxt<'tcx>>,
|
||||
available_depth: Limit,
|
||||
inspect: &mut ProofTreeBuilder<TyCtxt<'tcx>>,
|
||||
inspect: &mut ProofTreeBuilder<InferCtxt<'tcx>>,
|
||||
) -> Option<QueryResult<TyCtxt<'tcx>>> {
|
||||
let CacheData { result, proof_tree, additional_depth, encountered_overflow } = self
|
||||
.global_cache(tcx)
|
||||
|
@ -473,11 +474,11 @@ impl<'tcx> SearchGraph<TyCtxt<'tcx>> {
|
|||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
input: CanonicalInput<TyCtxt<'tcx>>,
|
||||
inspect: &mut ProofTreeBuilder<TyCtxt<'tcx>>,
|
||||
inspect: &mut ProofTreeBuilder<InferCtxt<'tcx>>,
|
||||
prove_goal: &mut F,
|
||||
) -> StepResult<TyCtxt<'tcx>>
|
||||
where
|
||||
F: FnMut(&mut Self, &mut ProofTreeBuilder<TyCtxt<'tcx>>) -> QueryResult<TyCtxt<'tcx>>,
|
||||
F: FnMut(&mut Self, &mut ProofTreeBuilder<InferCtxt<'tcx>>) -> QueryResult<TyCtxt<'tcx>>,
|
||||
{
|
||||
let result = prove_goal(self, inspect);
|
||||
let stack_entry = self.pop_stack();
|
||||
|
|
|
@ -42,7 +42,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
goal: Goal<'tcx, TraitPredicate<'tcx>>,
|
||||
impl_def_id: DefId,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
|
||||
let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
|
||||
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
|
||||
|
@ -181,7 +181,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
|
||||
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
|
||||
let nested_obligations = tcx
|
||||
|
@ -235,7 +235,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
}
|
||||
|
||||
// The regions of a type don't affect the size of the type
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
// We should erase regions from both the param-env and type, since both
|
||||
// may have infer regions. Specifically, after canonicalizing and instantiating,
|
||||
// early bound regions turn into region vars in both the new and old solver.
|
||||
|
@ -296,7 +296,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
let tupled_inputs_and_output =
|
||||
match structural_traits::extract_tupled_inputs_and_output_from_callable(
|
||||
tcx,
|
||||
|
@ -337,7 +337,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
let (tupled_inputs_and_output_and_coroutine, nested_preds) =
|
||||
structural_traits::extract_tupled_inputs_and_output_from_async_callable(
|
||||
tcx,
|
||||
|
@ -447,7 +447,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
};
|
||||
|
||||
// Coroutines are not futures unless they come from `async` desugaring
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
if !tcx.coroutine_is_async(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
@ -473,7 +473,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
};
|
||||
|
||||
// Coroutines are not iterators unless they come from `gen` desugaring
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
if !tcx.coroutine_is_gen(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
};
|
||||
|
||||
// Coroutines are not iterators unless they come from `gen` desugaring
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
if !tcx.coroutine_is_gen(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
@ -523,7 +523,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
};
|
||||
|
||||
// Coroutines are not iterators unless they come from `gen` desugaring
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
if !tcx.coroutine_is_async_gen(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
@ -550,7 +550,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
};
|
||||
|
||||
// `async`-desugared coroutines do not implement the coroutine trait
|
||||
let tcx = ecx.tcx();
|
||||
let tcx = ecx.interner();
|
||||
if !tcx.is_general_coroutine(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
@ -625,10 +625,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
|
||||
// Erase regions because we compute layouts in `rustc_transmute`,
|
||||
// which will ICE for region vars.
|
||||
let args = ecx.tcx().erase_regions(goal.predicate.trait_ref.args);
|
||||
let args = ecx.interner().erase_regions(goal.predicate.trait_ref.args);
|
||||
|
||||
let Some(assume) =
|
||||
rustc_transmute::Assume::from_const(ecx.tcx(), goal.param_env, args.const_at(2))
|
||||
rustc_transmute::Assume::from_const(ecx.interner(), goal.param_env, args.const_at(2))
|
||||
else {
|
||||
return Err(NoSolution);
|
||||
};
|
||||
|
@ -675,7 +675,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
return vec![];
|
||||
};
|
||||
|
||||
let goal = goal.with(ecx.tcx(), (a_ty, b_ty));
|
||||
let goal = goal.with(ecx.interner(), (a_ty, b_ty));
|
||||
match (a_ty.kind(), b_ty.kind()) {
|
||||
(ty::Infer(ty::TyVar(..)), ..) => bug!("unexpected infer {a_ty:?} {b_ty:?}"),
|
||||
|
||||
|
@ -741,7 +741,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||
b_region: ty::Region<'tcx>,
|
||||
) -> Vec<Candidate<'tcx>> {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let Goal { predicate: (a_ty, _b_ty), .. } = goal;
|
||||
|
||||
let mut responses = vec![];
|
||||
|
@ -787,7 +787,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||
b_region: ty::Region<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let Goal { predicate: (a_ty, _), .. } = goal;
|
||||
|
||||
// Can only unsize to an object-safe trait.
|
||||
|
@ -837,8 +837,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
let a_auto_traits: FxIndexSet<DefId> = a_data
|
||||
.auto_traits()
|
||||
.chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
|
||||
supertrait_def_ids(self.tcx(), principal_def_id)
|
||||
.filter(|def_id| self.tcx().trait_is_auto(*def_id))
|
||||
supertrait_def_ids(self.interner(), principal_def_id)
|
||||
.filter(|def_id| self.interner().trait_is_auto(*def_id))
|
||||
}))
|
||||
.collect();
|
||||
|
||||
|
@ -907,7 +907,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
ecx.add_goal(
|
||||
GoalSource::ImplWhereBound,
|
||||
Goal::new(
|
||||
ecx.tcx(),
|
||||
ecx.interner(),
|
||||
param_env,
|
||||
ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region)),
|
||||
),
|
||||
|
@ -956,7 +956,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
a_args: ty::GenericArgsRef<'tcx>,
|
||||
b_args: ty::GenericArgsRef<'tcx>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let Goal { predicate: (_a_ty, b_ty), .. } = goal;
|
||||
|
||||
let unsizing_params = tcx.unsizing_params_for_adt(def.did());
|
||||
|
@ -1017,7 +1017,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
a_tys: &'tcx ty::List<Ty<'tcx>>,
|
||||
b_tys: &'tcx ty::List<Ty<'tcx>>,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.interner();
|
||||
let Goal { predicate: (_a_ty, b_ty), .. } = goal;
|
||||
|
||||
let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap();
|
||||
|
@ -1077,9 +1077,9 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
// takes precedence over the structural auto trait candidate being
|
||||
// assembled.
|
||||
ty::Coroutine(def_id, _)
|
||||
if Some(goal.predicate.def_id()) == self.tcx().lang_items().unpin_trait() =>
|
||||
if Some(goal.predicate.def_id()) == self.interner().lang_items().unpin_trait() =>
|
||||
{
|
||||
match self.tcx().coroutine_movability(def_id) {
|
||||
match self.interner().coroutine_movability(def_id) {
|
||||
Movability::Static => Some(Err(NoSolution)),
|
||||
Movability::Movable => Some(
|
||||
self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
|
||||
|
@ -1124,7 +1124,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
| ty::Tuple(_)
|
||||
| ty::Adt(_, _) => {
|
||||
let mut disqualifying_impl = None;
|
||||
self.tcx().for_each_relevant_impl(
|
||||
self.interner().for_each_relevant_impl(
|
||||
goal.predicate.def_id(),
|
||||
goal.predicate.self_ty(),
|
||||
|impl_def_id| {
|
||||
|
@ -1164,7 +1164,10 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
.into_iter()
|
||||
.map(|ty| {
|
||||
ecx.enter_forall(ty, |ty| {
|
||||
goal.with(ecx.tcx(), goal.predicate.with_self_ty(ecx.tcx(), ty))
|
||||
goal.with(
|
||||
ecx.interner(),
|
||||
goal.predicate.with_self_ty(ecx.interner(), ty),
|
||||
)
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
|
|
|
@ -132,7 +132,14 @@ pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
|
|||
}
|
||||
|
||||
pub trait Predicate<I: Interner<Predicate = Self>>:
|
||||
Copy + Debug + Hash + Eq + TypeSuperVisitable<I> + TypeSuperFoldable<I> + Flags
|
||||
Copy
|
||||
+ Debug
|
||||
+ Hash
|
||||
+ Eq
|
||||
+ TypeSuperVisitable<I>
|
||||
+ TypeSuperFoldable<I>
|
||||
+ Flags
|
||||
+ UpcastFrom<I, ty::NormalizesTo<I>>
|
||||
{
|
||||
fn is_coinductive(self, interner: I) -> bool;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::fmt::Debug;
|
|||
use std::hash::Hash;
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::fold::TypeFoldable;
|
||||
use crate::inherent::*;
|
||||
use crate::ir_print::IrPrint;
|
||||
use crate::solve::inspect::CanonicalGoalEvaluationStep;
|
||||
|
@ -90,7 +91,7 @@ pub trait Interner:
|
|||
type PlaceholderRegion: PlaceholderLike;
|
||||
|
||||
// Predicates
|
||||
type ParamEnv: Copy + Debug + Hash + Eq;
|
||||
type ParamEnv: Copy + Debug + Hash + Eq + TypeFoldable<Self>;
|
||||
type Predicate: Predicate<Self>;
|
||||
type Clause: Clause<Self>;
|
||||
type Clauses: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
|
||||
|
@ -114,15 +115,18 @@ pub trait Interner:
|
|||
) -> (ty::TraitRef<Self>, Self::OwnItemArgs);
|
||||
|
||||
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
|
||||
|
||||
fn mk_args_from_iter(self, args: impl Iterator<Item = Self::GenericArg>) -> Self::GenericArgs;
|
||||
|
||||
fn check_and_mk_args(
|
||||
self,
|
||||
def_id: Self::DefId,
|
||||
args: impl IntoIterator<Item: Into<Self::GenericArg>>,
|
||||
) -> Self::GenericArgs;
|
||||
|
||||
fn intern_canonical_goal_evaluation_step(
|
||||
self,
|
||||
step: CanonicalGoalEvaluationStep<Self>,
|
||||
) -> Self::CanonicalGoalEvaluationStepRef;
|
||||
|
||||
fn parent(self, def_id: Self::DefId) -> Self::DefId;
|
||||
|
||||
fn recursion_limit(self) -> usize;
|
||||
|
|
|
@ -209,18 +209,14 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> {
|
|||
// Consider a reference like `&(i32, dyn Send)`: the vtable will only store the size of the
|
||||
// `Send` part!
|
||||
// SAFETY: DynMetadata always contains a valid vtable pointer
|
||||
return unsafe {
|
||||
crate::intrinsics::vtable_size(self.vtable_ptr() as *const ())
|
||||
};
|
||||
return unsafe { crate::intrinsics::vtable_size(self.vtable_ptr() as *const ()) };
|
||||
}
|
||||
|
||||
/// Returns the alignment of the type associated with this vtable.
|
||||
#[inline]
|
||||
pub fn align_of(self) -> usize {
|
||||
// SAFETY: DynMetadata always contains a valid vtable pointer
|
||||
return unsafe {
|
||||
crate::intrinsics::vtable_align(self.vtable_ptr() as *const ())
|
||||
};
|
||||
return unsafe { crate::intrinsics::vtable_align(self.vtable_ptr() as *const ()) };
|
||||
}
|
||||
|
||||
/// Returns the size and alignment together as a `Layout`
|
||||
|
|
19
rustfmt.toml
19
rustfmt.toml
|
@ -3,25 +3,18 @@ version = "Two"
|
|||
use_small_heuristics = "Max"
|
||||
merge_derives = false
|
||||
|
||||
# by default we ignore everything in the repository
|
||||
# tidy only checks files which are not ignored, each entry follows gitignore style
|
||||
# Files to ignore. Each entry uses gitignore syntax, but `!` prefixes aren't allowed.
|
||||
ignore = [
|
||||
"/build/",
|
||||
"/*-build/",
|
||||
"/build-*/",
|
||||
"/vendor/",
|
||||
|
||||
# tests for now are not formatted, as they are sometimes pretty-printing constrained
|
||||
# (and generally rustfmt can move around comments in UI-testing incompatible ways)
|
||||
"/tests/*",
|
||||
# Tests for now are not formatted, as they are sometimes pretty-printing constrained
|
||||
# (and generally rustfmt can move around comments in UI-testing incompatible ways).
|
||||
"/tests/",
|
||||
|
||||
# but we still want to format rmake.rs files in tests/run-make/ so we need to do this
|
||||
# dance to avoid the parent directory from being excluded
|
||||
"!/tests/run-make/",
|
||||
"/tests/run-make/*/*.rs",
|
||||
"!/tests/run-make/*/rmake.rs",
|
||||
|
||||
# do not format submodules
|
||||
# Do not format submodules.
|
||||
# FIXME: sync submodule list with tidy/bootstrap/etc
|
||||
# tidy/src/walk.rs:filter_dirs
|
||||
"library/backtrace",
|
||||
|
@ -43,7 +36,7 @@ ignore = [
|
|||
"src/tools/rustc-perf",
|
||||
"src/tools/rustfmt",
|
||||
|
||||
# these are ignored by a standard cargo fmt run
|
||||
# These are ignored by a standard cargo fmt run.
|
||||
"compiler/rustc_codegen_cranelift/scripts",
|
||||
"compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs", # uses edition 2024
|
||||
]
|
||||
|
|
|
@ -12,8 +12,8 @@ use std::sync::mpsc::SyncSender;
|
|||
|
||||
fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl FnMut(bool) -> bool {
|
||||
let mut cmd = Command::new(rustfmt);
|
||||
// avoid the submodule config paths from coming into play,
|
||||
// we only allow a single global config for the workspace for now
|
||||
// Avoid the submodule config paths from coming into play. We only allow a single global config
|
||||
// for the workspace for now.
|
||||
cmd.arg("--config-path").arg(&src.canonicalize().unwrap());
|
||||
cmd.arg("--edition").arg("2021");
|
||||
cmd.arg("--unstable-features");
|
||||
|
@ -24,7 +24,7 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F
|
|||
cmd.args(paths);
|
||||
let cmd_debug = format!("{cmd:?}");
|
||||
let mut cmd = cmd.spawn().expect("running rustfmt");
|
||||
// poor man's async: return a closure that'll wait for rustfmt's completion
|
||||
// Poor man's async: return a closure that'll wait for rustfmt's completion.
|
||||
move |block: bool| -> bool {
|
||||
if !block {
|
||||
match cmd.try_wait() {
|
||||
|
@ -72,7 +72,7 @@ fn verify_rustfmt_version(build: &Builder<'_>) -> bool {
|
|||
!program_out_of_date(&stamp_file, &version)
|
||||
}
|
||||
|
||||
/// Updates the last rustfmt version used
|
||||
/// Updates the last rustfmt version used.
|
||||
fn update_rustfmt_version(build: &Builder<'_>) {
|
||||
let Some((version, stamp_file)) = get_rustfmt_version(build) else {
|
||||
return;
|
||||
|
@ -115,8 +115,15 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
|
|||
let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
|
||||
let mut fmt_override = ignore::overrides::OverrideBuilder::new(&build.src);
|
||||
for ignore in rustfmt_config.ignore {
|
||||
if let Some(ignore) = ignore.strip_prefix('!') {
|
||||
fmt_override.add(ignore).expect(ignore);
|
||||
if ignore.starts_with('!') {
|
||||
// A `!`-prefixed entry could be added as a whitelisted entry in `fmt_override`, i.e.
|
||||
// strip the `!` prefix. But as soon as whitelisted entries are added, an
|
||||
// `OverrideBuilder` will only traverse those whitelisted entries, and won't traverse
|
||||
// any files that aren't explicitly mentioned. No bueno! Maybe there's a way to combine
|
||||
// explicit whitelisted entries and traversal of unmentioned files, but for now just
|
||||
// forbid such entries.
|
||||
eprintln!("`!`-prefixed entries are not supported in rustfmt.toml, sorry");
|
||||
crate::exit!(1);
|
||||
} else {
|
||||
fmt_override.add(&format!("!{ignore}")).expect(&ignore);
|
||||
}
|
||||
|
@ -168,9 +175,10 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
|
|||
untracked_count += 1;
|
||||
fmt_override.add(&format!("!/{untracked_path}")).expect(untracked_path);
|
||||
}
|
||||
// Only check modified files locally to speed up runtime.
|
||||
// We still check all files in CI to avoid bugs in `get_modified_rs_files` letting regressions slip through;
|
||||
// we also care about CI time less since this is still very fast compared to building the compiler.
|
||||
// Only check modified files locally to speed up runtime. We still check all files in
|
||||
// CI to avoid bugs in `get_modified_rs_files` letting regressions slip through; we
|
||||
// also care about CI time less since this is still very fast compared to building the
|
||||
// compiler.
|
||||
if !CiEnv::is_ci() && paths.is_empty() {
|
||||
match get_modified_rs_files(build) {
|
||||
Ok(Some(files)) => {
|
||||
|
@ -275,21 +283,23 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
|
|||
.overrides(fmt_override)
|
||||
.build_parallel();
|
||||
|
||||
// there is a lot of blocking involved in spawning a child process and reading files to format.
|
||||
// spawn more processes than available concurrency to keep the CPU busy
|
||||
// There is a lot of blocking involved in spawning a child process and reading files to format.
|
||||
// Spawn more processes than available concurrency to keep the CPU busy.
|
||||
let max_processes = build.jobs() as usize * 2;
|
||||
|
||||
// spawn child processes on a separate thread so we can batch entries we have received from ignore
|
||||
// Spawn child processes on a separate thread so we can batch entries we have received from
|
||||
// ignore.
|
||||
let thread = std::thread::spawn(move || {
|
||||
let mut children = VecDeque::new();
|
||||
while let Ok(path) = rx.recv() {
|
||||
// try getting more paths from the channel to amortize the overhead of spawning processes
|
||||
// Try getting more paths from the channel to amortize the overhead of spawning
|
||||
// processes.
|
||||
let paths: Vec<_> = rx.try_iter().take(63).chain(std::iter::once(path)).collect();
|
||||
|
||||
let child = rustfmt(&src, &rustfmt_path, paths.as_slice(), check);
|
||||
children.push_back(child);
|
||||
|
||||
// poll completion before waiting
|
||||
// Poll completion before waiting.
|
||||
for i in (0..children.len()).rev() {
|
||||
if children[i](false) {
|
||||
children.swap_remove_back(i);
|
||||
|
@ -298,12 +308,12 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
|
|||
}
|
||||
|
||||
if children.len() >= max_processes {
|
||||
// await oldest child
|
||||
// Await oldest child.
|
||||
children.pop_front().unwrap()(true);
|
||||
}
|
||||
}
|
||||
|
||||
// await remaining children
|
||||
// Await remaining children.
|
||||
for mut child in children {
|
||||
child(true);
|
||||
}
|
||||
|
|
|
@ -378,7 +378,6 @@ auto:
|
|||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: x86_64-mingw
|
||||
|
@ -390,7 +389,6 @@ auto:
|
|||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: dist-x86_64-msvc
|
||||
|
@ -439,7 +437,6 @@ auto:
|
|||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
CUSTOM_MINGW: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
|
@ -453,7 +450,6 @@ auto:
|
|||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
#!/bin/bash
|
||||
# If we need to download a custom MinGW, do so here and set the path
|
||||
# appropriately.
|
||||
#
|
||||
# Otherwise install MinGW through `pacman`
|
||||
# For mingw builds use a vendored mingw.
|
||||
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
@ -16,19 +13,16 @@ if isWindows && isKnownToBeMingwBuild; then
|
|||
case "${CI_JOB_NAME}" in
|
||||
*i686*)
|
||||
bits=32
|
||||
arch=i686
|
||||
mingw_archive="${MINGW_ARCHIVE_32}"
|
||||
;;
|
||||
*x86_64*)
|
||||
bits=64
|
||||
arch=x86_64
|
||||
mingw_archive="${MINGW_ARCHIVE_64}"
|
||||
;;
|
||||
*aarch64*)
|
||||
# aarch64 is a cross-compiled target. Use the x86_64
|
||||
# mingw, since that's the host architecture.
|
||||
bits=64
|
||||
arch=x86_64
|
||||
mingw_archive="${MINGW_ARCHIVE_64}"
|
||||
;;
|
||||
*)
|
||||
|
@ -38,13 +32,9 @@ if isWindows && isKnownToBeMingwBuild; then
|
|||
;;
|
||||
esac
|
||||
|
||||
if [[ "${CUSTOM_MINGW:-0}" == 0 ]]; then
|
||||
pacman -S --noconfirm --needed mingw-w64-$arch-toolchain
|
||||
else
|
||||
mingw_dir="mingw${bits}"
|
||||
mingw_dir="mingw${bits}"
|
||||
|
||||
curl -o mingw.7z "${MIRRORS_BASE}/${mingw_archive}"
|
||||
7z x -y mingw.7z > /dev/null
|
||||
ciCommandAddPath "$(pwd)/${mingw_dir}/bin"
|
||||
fi
|
||||
curl -o mingw.7z "${MIRRORS_BASE}/${mingw_archive}"
|
||||
7z x -y mingw.7z > /dev/null
|
||||
ciCommandAddPath "$(pwd)/${mingw_dir}/bin"
|
||||
fi
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Clean up and prepare the MSYS2 installation.
|
||||
# MSYS2 is used by the MinGW toolchain for assembling things.
|
||||
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
|
||||
if isWindows; then
|
||||
# Detect the native Python version installed on the agent. On GitHub
|
||||
# Actions, the C:\hostedtoolcache\windows\Python directory contains a
|
||||
# subdirectory for each installed Python version.
|
||||
#
|
||||
# The -V flag of the sort command sorts the input by version number.
|
||||
native_python_version="$(ls /c/hostedtoolcache/windows/Python | sort -Vr | head -n 1)"
|
||||
|
||||
# Make sure we use the native python interpreter instead of some msys equivalent
|
||||
# one way or another. The msys interpreters seem to have weird path conversions
|
||||
# baked in which break LLVM's build system one way or another, so let's use the
|
||||
# native version which keeps everything as native as possible.
|
||||
python_home="/c/hostedtoolcache/windows/Python/${native_python_version}/x64"
|
||||
if ! [[ -f "${python_home}/python3.exe" ]]; then
|
||||
cp "${python_home}/python.exe" "${python_home}/python3.exe"
|
||||
fi
|
||||
ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\${native_python_version}\\x64"
|
||||
ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\${native_python_version}\\x64\\Scripts"
|
||||
fi
|
|
@ -268,6 +268,17 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check that `haystack` does not contain `needle`. Panic otherwise.
|
||||
pub fn assert_not_contains(haystack: &str, needle: &str) {
|
||||
if haystack.contains(needle) {
|
||||
eprintln!("=== HAYSTACK ===");
|
||||
eprintln!("{}", haystack);
|
||||
eprintln!("=== NEEDLE ===");
|
||||
eprintln!("{}", needle);
|
||||
panic!("needle was unexpectedly found in haystack");
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
|
||||
/// containing a `cmd: Command` field and a `output` function. The provided helpers are:
|
||||
///
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
run-make/allocator-shim-circular-deps/Makefile
|
||||
run-make/allow-non-lint-warnings-cmdline/Makefile
|
||||
run-make/allow-warnings-cmdline-stability/Makefile
|
||||
run-make/archive-duplicate-names/Makefile
|
||||
run-make/atomic-lock-free/Makefile
|
||||
run-make/bare-outfile/Makefile
|
||||
|
|
206
tests/assembly/nvptx-c-abi-arg-v7.rs
Normal file
206
tests/assembly/nvptx-c-abi-arg-v7.rs
Normal file
|
@ -0,0 +1,206 @@
|
|||
//@ assembly-output: ptx-linker
|
||||
//@ compile-flags: --crate-type cdylib -C target-cpu=sm_86 -Z unstable-options -Clinker-flavor=llbc
|
||||
//@ only-nvptx64
|
||||
|
||||
// The PTX ABI stability is tied to major versions of the PTX ISA
|
||||
// These tests assume major version 7
|
||||
|
||||
// CHECK: .version 7
|
||||
|
||||
#![feature(abi_ptx, lang_items, no_core)]
|
||||
#![no_core]
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SingleU8 {
|
||||
f: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleU8 {
|
||||
f: u8,
|
||||
g: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleU8 {
|
||||
f: u8,
|
||||
g: u8,
|
||||
h: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleU16 {
|
||||
f: u16,
|
||||
g: u16,
|
||||
h: u16,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct TripleU32 {
|
||||
f: u32,
|
||||
g: u32,
|
||||
h: u32,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct TripleU64 {
|
||||
f: u64,
|
||||
g: u64,
|
||||
h: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleFloat {
|
||||
f: f32,
|
||||
g: f32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleFloat {
|
||||
f: f32,
|
||||
g: f32,
|
||||
h: f32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleDouble {
|
||||
f: f64,
|
||||
g: f64,
|
||||
h: f64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ManyIntegers {
|
||||
f: u8,
|
||||
g: u16,
|
||||
h: u32,
|
||||
i: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ManyNumerics {
|
||||
f: u8,
|
||||
g: u16,
|
||||
h: u32,
|
||||
i: u64,
|
||||
j: f32,
|
||||
k: f64,
|
||||
}
|
||||
|
||||
// CHECK: .visible .func f_u8_arg(
|
||||
// CHECK: .param .b32 f_u8_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_u8_arg(_a: u8) {}
|
||||
|
||||
// CHECK: .visible .func f_u16_arg(
|
||||
// CHECK: .param .b32 f_u16_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_u16_arg(_a: u16) {}
|
||||
|
||||
// CHECK: .visible .func f_u32_arg(
|
||||
// CHECK: .param .b32 f_u32_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_u32_arg(_a: u32) {}
|
||||
|
||||
// CHECK: .visible .func f_u64_arg(
|
||||
// CHECK: .param .b64 f_u64_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_u64_arg(_a: u64) {}
|
||||
|
||||
// CHECK: .visible .func f_u128_arg(
|
||||
// CHECK: .param .align 16 .b8 f_u128_arg_param_0[16]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_u128_arg(_a: u128) {}
|
||||
|
||||
// CHECK: .visible .func f_i8_arg(
|
||||
// CHECK: .param .b32 f_i8_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_i8_arg(_a: i8) {}
|
||||
|
||||
// CHECK: .visible .func f_i16_arg(
|
||||
// CHECK: .param .b32 f_i16_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_i16_arg(_a: i16) {}
|
||||
|
||||
// CHECK: .visible .func f_i32_arg(
|
||||
// CHECK: .param .b32 f_i32_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_i32_arg(_a: i32) {}
|
||||
|
||||
// CHECK: .visible .func f_i64_arg(
|
||||
// CHECK: .param .b64 f_i64_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_i64_arg(_a: i64) {}
|
||||
|
||||
// CHECK: .visible .func f_i128_arg(
|
||||
// CHECK: .param .align 16 .b8 f_i128_arg_param_0[16]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_i128_arg(_a: i128) {}
|
||||
|
||||
// CHECK: .visible .func f_f32_arg(
|
||||
// CHECK: .param .b32 f_f32_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_f32_arg(_a: f32) {}
|
||||
|
||||
// CHECK: .visible .func f_f64_arg(
|
||||
// CHECK: .param .b64 f_f64_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_f64_arg(_a: f64) {}
|
||||
|
||||
// CHECK: .visible .func f_single_u8_arg(
|
||||
// CHECK: .param .align 1 .b8 f_single_u8_arg_param_0[1]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_single_u8_arg(_a: SingleU8) {}
|
||||
|
||||
// CHECK: .visible .func f_double_u8_arg(
|
||||
// CHECK: .param .align 1 .b8 f_double_u8_arg_param_0[2]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_double_u8_arg(_a: DoubleU8) {}
|
||||
|
||||
// CHECK: .visible .func f_triple_u8_arg(
|
||||
// CHECK: .param .align 1 .b8 f_triple_u8_arg_param_0[3]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_u8_arg(_a: TripleU8) {}
|
||||
|
||||
// CHECK: .visible .func f_triple_u16_arg(
|
||||
// CHECK: .param .align 2 .b8 f_triple_u16_arg_param_0[6]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_u16_arg(_a: TripleU16) {}
|
||||
|
||||
// CHECK: .visible .func f_triple_u32_arg(
|
||||
// CHECK: .param .align 4 .b8 f_triple_u32_arg_param_0[12]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_u32_arg(_a: TripleU32) {}
|
||||
|
||||
// CHECK: .visible .func f_triple_u64_arg(
|
||||
// CHECK: .param .align 8 .b8 f_triple_u64_arg_param_0[24]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_u64_arg(_a: TripleU64) {}
|
||||
|
||||
// CHECK: .visible .func f_many_integers_arg(
|
||||
// CHECK: .param .align 8 .b8 f_many_integers_arg_param_0[16]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_many_integers_arg(_a: ManyIntegers) {}
|
||||
|
||||
// CHECK: .visible .func f_double_float_arg(
|
||||
// CHECK: .param .align 4 .b8 f_double_float_arg_param_0[8]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_double_float_arg(_a: DoubleFloat) {}
|
||||
|
||||
// CHECK: .visible .func f_triple_float_arg(
|
||||
// CHECK: .param .align 4 .b8 f_triple_float_arg_param_0[12]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_float_arg(_a: TripleFloat) {}
|
||||
|
||||
// CHECK: .visible .func f_triple_double_arg(
|
||||
// CHECK: .param .align 8 .b8 f_triple_double_arg_param_0[24]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_double_arg(_a: TripleDouble) {}
|
||||
|
||||
// CHECK: .visible .func f_many_numerics_arg(
|
||||
// CHECK: .param .align 8 .b8 f_many_numerics_arg_param_0[32]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_many_numerics_arg(_a: ManyNumerics) {}
|
230
tests/assembly/nvptx-c-abi-ret-v7.rs
Normal file
230
tests/assembly/nvptx-c-abi-ret-v7.rs
Normal file
|
@ -0,0 +1,230 @@
|
|||
//@ assembly-output: ptx-linker
|
||||
//@ compile-flags: --crate-type cdylib -C target-cpu=sm_86 -Z unstable-options -Clinker-flavor=llbc
|
||||
//@ only-nvptx64
|
||||
//@ ignore-nvptx64
|
||||
|
||||
// The PTX ABI stability is tied to major versions of the PTX ISA
|
||||
// These tests assume major version 7
|
||||
|
||||
// CHECK: .version 7
|
||||
|
||||
#![feature(abi_ptx, lang_items, no_core)]
|
||||
#![no_core]
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SingleU8 {
|
||||
f: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleU8 {
|
||||
f: u8,
|
||||
g: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleU8 {
|
||||
f: u8,
|
||||
g: u8,
|
||||
h: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleU16 {
|
||||
f: u16,
|
||||
g: u16,
|
||||
h: u16,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct TripleU32 {
|
||||
f: u32,
|
||||
g: u32,
|
||||
h: u32,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct TripleU64 {
|
||||
f: u64,
|
||||
g: u64,
|
||||
h: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleFloat {
|
||||
f: f32,
|
||||
g: f32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleFloat {
|
||||
f: f32,
|
||||
g: f32,
|
||||
h: f32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleDouble {
|
||||
f: f64,
|
||||
g: f64,
|
||||
h: f64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ManyIntegers {
|
||||
f: u8,
|
||||
g: u16,
|
||||
h: u32,
|
||||
i: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ManyNumerics {
|
||||
f: u8,
|
||||
g: u16,
|
||||
h: u32,
|
||||
i: u64,
|
||||
j: f32,
|
||||
k: f64,
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .b32 func_retval0) f_u8_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_u8_ret() -> u8 {
|
||||
0
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .b32 func_retval0) f_u16_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_u16_ret() -> u16 {
|
||||
1
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .b32 func_retval0) f_u32_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_u32_ret() -> u32 {
|
||||
2
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .b64 func_retval0) f_u64_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_u64_ret() -> u64 {
|
||||
3
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 16 .b8 func_retval0[16]) f_u128_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_u128_ret() -> u128 {
|
||||
4
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .b32 func_retval0) f_i8_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_i8_ret() -> i8 {
|
||||
5
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .b32 func_retval0) f_i16_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_i16_ret() -> i16 {
|
||||
6
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .b32 func_retval0) f_i32_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_i32_ret() -> i32 {
|
||||
7
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .b64 func_retval0) f_i64_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_i64_ret() -> i64 {
|
||||
8
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 16 .b8 func_retval0[16]) f_i128_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_i128_ret() -> i128 {
|
||||
9
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .b32 func_retval0) f_f32_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_f32_ret() -> f32 {
|
||||
10.0
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .b64 func_retval0) f_f64_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_f64_ret() -> f64 {
|
||||
11.0
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 1 .b8 func_retval0[1]) f_single_u8_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_single_u8_ret() -> SingleU8 {
|
||||
SingleU8 { f: 12 }
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 1 .b8 func_retval0[2]) f_double_u8_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_double_u8_ret() -> DoubleU8 {
|
||||
DoubleU8 { f: 13, g: 14 }
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 1 .b8 func_retval0[3]) f_triple_u8_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_u8_ret() -> TripleU8 {
|
||||
TripleU8 { f: 15, g: 16, h: 17 }
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 2 .b8 func_retval0[6]) f_triple_u16_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_u16_ret() -> TripleU16 {
|
||||
TripleU16 { f: 18, g: 19, h: 20 }
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 4 .b8 func_retval0[12]) f_triple_u32_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_u32_ret() -> TripleU32 {
|
||||
TripleU32 { f: 20, g: 21, h: 22 }
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 8 .b8 func_retval0[24]) f_triple_u64_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_u64_ret() -> TripleU64 {
|
||||
TripleU64 { f: 23, g: 24, h: 25 }
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 8 .b8 func_retval0[16]) f_many_integers_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_many_integers_ret() -> ManyIntegers {
|
||||
ManyIntegers { f: 26, g: 27, h: 28, i: 29 }
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 4 .b8 func_retval0[8]) f_double_float_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_double_float_ret() -> DoubleFloat {
|
||||
DoubleFloat { f: 29.0, g: 30.0 }
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 4 .b8 func_retval0[12]) f_triple_float_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_float_ret() -> TripleFloat {
|
||||
TripleFloat { f: 31.0, g: 32.0, h: 33.0 }
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 8 .b8 func_retval0[24]) f_triple_double_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_triple_double_ret() -> TripleDouble {
|
||||
TripleDouble { f: 34.0, g: 35.0, h: 36.0 }
|
||||
}
|
||||
|
||||
// CHECK: .visible .func (.param .align 8 .b8 func_retval0[32]) f_many_numerics_ret(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_many_numerics_ret() -> ManyNumerics {
|
||||
ManyNumerics { f: 37, g: 38, h: 39, i: 40, j: 41.0, k: 43.0 }
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
# ignore-cross-compile
|
||||
include ../tools.mk
|
||||
|
||||
# Test that -A warnings makes the 'empty trait list for derive' warning go away
|
||||
DEP=$(shell $(RUSTC) bar.rs)
|
||||
OUT=$(shell $(RUSTC) foo.rs -A warnings 2>&1 | grep "warning" )
|
||||
|
||||
all: foo bar
|
||||
test -z '$(OUT)'
|
||||
|
||||
# These are just to ensure that the above commands actually work
|
||||
bar:
|
||||
$(RUSTC) bar.rs
|
||||
|
||||
foo: bar
|
||||
$(RUSTC) foo.rs -A warnings
|
11
tests/run-make/allow-warnings-cmdline-stability/rmake.rs
Normal file
11
tests/run-make/allow-warnings-cmdline-stability/rmake.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Test that `-Awarnings` suppresses warnings for unstable APIs.
|
||||
|
||||
use run_make_support::{assert_not_contains, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("bar.rs").run();
|
||||
let output = rustc().input("foo.rs").arg("-Awarnings").run();
|
||||
|
||||
assert_not_contains(&String::from_utf8(output.stdout).unwrap(), "warning");
|
||||
assert_not_contains(&String::from_utf8(output.stderr).unwrap(), "warning");
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue