Skip to content

Commit 3799568

Browse files
More comments
1 parent f49b0dc commit 3799568

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

compiler/rustc_trait_selection/src/solve/alias_relate.rs

+26-9
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,29 @@
22
//! Doing this via a separate goal is called "deferred alias relation" and part
33
//! of our more general approach to "lazy normalization".
44
//!
5-
//! This goal, e.g. `A alias-relate B`, may be satisfied by one of three branches:
6-
//! * normalizes-to: If `A` is a projection, we can prove the equivalent
7-
//! projection predicate with B as the right-hand side of the projection.
8-
//! This goal is computed in both directions, if both are aliases.
9-
//! * subst-relate: Equate `A` and `B` by their substs, if they're both
10-
//! aliases with the same def-id.
11-
//! * bidirectional-normalizes-to: If `A` and `B` are both projections, and both
12-
//! may apply, then we can compute the "intersection" of both normalizes-to by
13-
//! performing them together. This is used specifically to resolve ambiguities.
5+
//! This is done by first normalizing both sides of the goal, ending up in
6+
//! either a concrete type, rigid projection, opaque, or an infer variable.
7+
//! These are related further according to the rules below:
8+
//!
9+
//! (1.) If we end up with a rigid projection and a rigid projection, then we
10+
//! relate those projections structurally.
11+
//!
12+
//! (2.) If we end up with a rigid projection and an alias, then the opaque will
13+
//! have its hidden type defined to be that rigid projection.
14+
//!
15+
//! (3.) If we end up with an opaque and an opaque, then we assemble two
16+
//! candidates, one defining the LHS to be the hidden type of the RHS, and vice
17+
//! versa.
18+
//!
19+
//! (4.) If we end up with an infer var and an opaque or rigid projection, then
20+
//! we assign the alias to the infer var.
21+
//!
22+
//! (5.) If we end up with an opaque and a rigid (non-projection) type, then we
23+
//! define the hidden type of the opaque to be the rigid type.
24+
//!
25+
//! (6.) Otherwise, if we end with two rigid (non-projection) or infer types,
26+
//! relate them structurally.
27+
1428
use super::{EvalCtxt, GoalSource};
1529
use rustc_infer::infer::DefineOpaqueTypes;
1630
use rustc_infer::traits::query::NoSolution;
@@ -50,6 +64,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
5064
self.relate(param_env, lhs, variance, rhs)?;
5165
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
5266
} else if alias.is_opaque(tcx) {
67+
// FIXME: This doesn't account for variance.
5368
self.define_opaque(param_env, alias, rhs)
5469
} else {
5570
Err(NoSolution)
@@ -60,6 +75,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
6075
self.relate(param_env, lhs, variance, rhs)?;
6176
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
6277
} else if alias.is_opaque(tcx) {
78+
// FIXME: This doesn't account for variance.
6379
self.define_opaque(param_env, alias, lhs)
6480
} else {
6581
Err(NoSolution)
@@ -72,6 +88,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
7288
}
7389
}
7490

91+
// FIXME: This needs a name that reflects that it's okay to bottom-out with an inference var.
7592
/// Normalize the `term` to equate it later. This does not define opaque types.
7693
#[instrument(level = "debug", skip(self, param_env), ret)]
7794
fn try_normalize_term(

compiler/rustc_trait_selection/src/solve/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
317317
return Some(ty);
318318
};
319319

320-
// We do no always define opaque types eagerly to allow non-defining uses in the defining scope.
320+
// We do no always define opaque types eagerly to allow non-defining uses
321+
// in the defining scope. However, if we can unify this opaque to an existing
322+
// opaque, then we should attempt to eagerly reveal the opaque, and we fall
323+
// through.
321324
if let DefineOpaqueTypes::No = define_opaque_types
322325
&& let Reveal::UserFacing = param_env.reveal()
323326
&& let ty::Opaque = kind

0 commit comments

Comments
 (0)