Skip to content

Commit 6bdc1bf

Browse files
Stop using translate_args in the new solver
1 parent 434999e commit 6bdc1bf

7 files changed

+131
-23
lines changed

compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs

-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use rustc_middle::bug;
1212
use rustc_middle::traits::solve::{
1313
inspect, CanonicalInput, CanonicalResponse, Certainty, PredefinedOpaquesData, QueryResult,
1414
};
15-
use rustc_middle::traits::specialization_graph;
1615
use rustc_middle::ty::AliasRelationDirection;
1716
use rustc_middle::ty::TypeFolder;
1817
use rustc_middle::ty::{
@@ -900,16 +899,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
900899
args
901900
}
902901

903-
pub(super) fn translate_args(
904-
&self,
905-
param_env: ty::ParamEnv<'tcx>,
906-
source_impl: DefId,
907-
source_args: ty::GenericArgsRef<'tcx>,
908-
target_node: specialization_graph::Node,
909-
) -> ty::GenericArgsRef<'tcx> {
910-
crate::traits::translate_args(self.infcx, param_env, source_impl, source_args, target_node)
911-
}
912-
913902
pub(super) fn register_ty_outlives(&self, ty: Ty<'tcx>, lt: ty::Region<'tcx>) {
914903
self.infcx.register_region_obligation_with_cause(ty, lt, &ObligationCause::dummy());
915904
}

compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs

+42-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::traits::specialization_graph;
1+
use crate::traits::specialization_graph::{self, LeafDef, Node};
22

33
use super::assembly::structural_traits::AsyncCallableRelevantTypes;
44
use super::assembly::{self, structural_traits, Candidate};
@@ -9,7 +9,6 @@ use rustc_infer::infer::InferCtxt;
99
use rustc_infer::traits::query::NoSolution;
1010
use rustc_infer::traits::solve::inspect::ProbeKind;
1111
use rustc_infer::traits::solve::MaybeCause;
12-
use rustc_infer::traits::specialization_graph::LeafDef;
1312
use rustc_infer::traits::Reveal;
1413
use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult};
1514
use rustc_middle::traits::BuiltinImplSource;
@@ -235,16 +234,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
235234
//
236235
// And then map these args to the args of the defining impl of `Assoc`, going
237236
// from `[u32, u64]` to `[u32, i32, u64]`.
238-
let impl_args_with_gat =
239-
goal.predicate.alias.args.rebase_onto(tcx, goal_trait_ref.def_id, impl_args);
240-
let args = ecx.translate_args(
241-
goal.param_env,
242-
impl_def_id,
243-
impl_args_with_gat,
244-
assoc_def.defining_node,
245-
);
237+
let associated_item_args =
238+
translate_args(ecx, &assoc_def, goal, impl_def_id, impl_args, impl_trait_ref)?;
246239

247-
if !tcx.check_args_compatible(assoc_def.item.def_id, args) {
240+
if !tcx.check_args_compatible(assoc_def.item.def_id, associated_item_args) {
248241
return error_response(
249242
ecx,
250243
"associated item has mismatched generic item arguments",
@@ -272,7 +265,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
272265
ty::AssocKind::Fn => unreachable!("we should never project to a fn"),
273266
};
274267

275-
ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, args));
268+
ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, associated_item_args));
276269
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
277270
})
278271
}
@@ -889,6 +882,43 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
889882
}
890883
}
891884

885+
fn translate_args<'tcx>(
886+
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
887+
assoc_def: &LeafDef,
888+
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
889+
impl_def_id: DefId,
890+
impl_args: ty::GenericArgsRef<'tcx>,
891+
impl_trait_ref: rustc_type_ir::TraitRef<TyCtxt<'tcx>>,
892+
) -> Result<ty::GenericArgsRef<'tcx>, NoSolution> {
893+
let tcx = ecx.interner();
894+
Ok(match assoc_def.defining_node {
895+
Node::Trait(_) => goal.predicate.alias.args,
896+
Node::Impl(target_impl_def_id) => {
897+
if target_impl_def_id == impl_def_id {
898+
// Same impl, no need to fully translate, just a rebase from
899+
// the trait is sufficient.
900+
goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, impl_args)
901+
} else {
902+
let target_args = ecx.fresh_args_for_item(target_impl_def_id);
903+
let target_trait_ref =
904+
tcx.impl_trait_ref(target_impl_def_id).unwrap().instantiate(tcx, target_args);
905+
// Relate source impl to target impl by equating trait refs.
906+
ecx.eq(goal.param_env, impl_trait_ref, target_trait_ref)?;
907+
// Also add predicates since they may be needed to constrain the
908+
// target impl's params.
909+
ecx.add_goals(
910+
GoalSource::Misc,
911+
tcx.predicates_of(target_impl_def_id)
912+
.instantiate(tcx, target_args)
913+
.into_iter()
914+
.map(|(pred, _)| goal.with(tcx, pred)),
915+
);
916+
goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, target_args)
917+
}
918+
}
919+
})
920+
}
921+
892922
/// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code.
893923
///
894924
/// FIXME: We should merge these 3 implementations as it's likely that they otherwise
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/source-impl-requires-constraining-predicates-ambig.rs:14:12
3+
|
4+
LL | #![feature(specialization)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: consider using `min_specialization` instead, which is more stable and complete
9+
= note: `#[warn(incomplete_features)]` on by default
10+
11+
warning: 1 warning emitted
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//@ revisions: current next
2+
//@ ignore-compare-mode-next-solver (explicit revisions)
3+
//@[next] compile-flags: -Znext-solver
4+
//@[next] check-pass
5+
//@[current] known-bug: unknown
6+
//@[current] failure-status: 101
7+
//@[current] dont-check-compiler-stderr
8+
9+
// Tests that rebasing from the concrete impl to the default impl also processes the
10+
// `[u32; 0]: IntoIterator<Item = ?U>` predicate to constrain the `?U` impl arg.
11+
// This test also makes sure that we don't do anything weird when rebasing the args
12+
// is ambiguous.
13+
14+
#![feature(specialization)]
15+
//[next]~^ WARN the feature `specialization` is incomplete
16+
17+
trait Spec {
18+
type Assoc;
19+
}
20+
21+
default impl<T, U> Spec for T where T: IntoIterator<Item = U> {
22+
type Assoc = U;
23+
}
24+
25+
impl<T> Spec for [T; 0] {}
26+
27+
fn main() {
28+
let x: <[_; 0] as Spec>::Assoc = 1;
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/source-impl-requires-constraining-predicates.rs:9:12
3+
|
4+
LL | #![feature(specialization)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: consider using `min_specialization` instead, which is more stable and complete
9+
= note: `#[warn(incomplete_features)]` on by default
10+
11+
warning: 1 warning emitted
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/source-impl-requires-constraining-predicates.rs:9:12
3+
|
4+
LL | #![feature(specialization)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: consider using `min_specialization` instead, which is more stable and complete
9+
= note: `#[warn(incomplete_features)]` on by default
10+
11+
warning: 1 warning emitted
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ check-pass
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
5+
6+
// Tests that rebasing from the concrete impl to the default impl also processes the
7+
// `[u32; 0]: IntoIterator<Item = ?U>` predicate to constrain the `?U` impl arg.
8+
9+
#![feature(specialization)]
10+
//~^ WARN the feature `specialization` is incomplete
11+
12+
trait Spec {
13+
type Assoc;
14+
}
15+
16+
default impl<T, U> Spec for T where T: IntoIterator<Item = U> {
17+
type Assoc = U;
18+
}
19+
20+
impl<T> Spec for [T; 0] {}
21+
22+
fn main() {
23+
let x: <[u32; 0] as Spec>::Assoc = 1;
24+
}

0 commit comments

Comments
 (0)