Skip to content

Commit 19bd91d

Browse files
committed
Pass list of defineable opaque types into canonical queries
1 parent ea44ce0 commit 19bd91d

30 files changed

+101
-139
lines changed

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
133133

134134
let ty =
135135
infcx.infer_opaque_definition_from_instantiation(opaque_type_key, concrete_type);
136+
137+
// Sometimes, when the hidden type is an inference variable, it can happen that
138+
// the hidden type becomes the opaque type itself. In this case, this was an opaque
139+
// usage of the opaque type and we can ignore it. This check is mirrored in typeck's
140+
// writeback.
141+
// FIXME(-Znext-solver): This should be unnecessary with the new solver.
142+
if let ty::Alias(ty::Opaque, alias_ty) = ty.kind()
143+
&& alias_ty.def_id == opaque_type_key.def_id.to_def_id()
144+
&& alias_ty.args == opaque_type_key.args
145+
{
146+
continue;
147+
}
136148
// Sometimes two opaque types are the same only after we remap the generic parameters
137149
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
138150
// and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ impl<'tcx> InferCtxt<'tcx> {
4545
let param_env = self.tcx.canonical_param_env_cache.get_or_insert(
4646
self.tcx,
4747
param_env,
48+
self.defining_use_anchor,
4849
query_state,
4950
|tcx, param_env, query_state| {
5051
// FIXME(#118965): We don't canonicalize the static lifetimes that appear in the
@@ -540,6 +541,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
540541
max_universe: ty::UniverseIndex::ROOT,
541542
variables: List::empty(),
542543
value: (),
544+
defining_anchor: infcx.map(|i| i.defining_use_anchor).unwrap_or_default(),
543545
};
544546
Canonicalizer::canonicalize_with_base(
545547
base,
@@ -609,7 +611,12 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
609611
.max()
610612
.unwrap_or(ty::UniverseIndex::ROOT);
611613

612-
Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value) }
614+
Canonical {
615+
max_universe,
616+
variables: canonical_variables,
617+
value: (base.value, out_value),
618+
defining_anchor: base.defining_anchor,
619+
}
613620
}
614621

615622
/// Creates a canonical variable replacing `kind` from the input,

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
243243
pub struct InferCtxt<'tcx> {
244244
pub tcx: TyCtxt<'tcx>,
245245

246-
/// The `DefId` of the item in whose context we are performing inference or typeck.
247-
/// It is used to check whether an opaque type use is a defining use.
248-
///
249-
/// If it is `DefiningAnchor::Bubble`, we can't resolve opaque types here and need to bubble up
250-
/// the obligation. This frequently happens for
251-
/// short lived InferCtxt within queries. The opaque type obligations are forwarded
252-
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
246+
/// The `DefIds` of the opaque types that may have their hidden types constrained.
253247
///
254248
/// Its default value is `DefiningAnchor::Bind(&[])`, which means no opaque types may be defined.
255249
/// This way it is easier to catch errors that
@@ -401,6 +395,10 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
401395
fn probe_ct_var(&self, vid: ConstVid) -> Option<ty::Const<'tcx>> {
402396
self.probe_const_var(vid).ok()
403397
}
398+
399+
fn defining_anchor(&self) -> DefiningAnchor<'tcx> {
400+
self.defining_use_anchor
401+
}
404402
}
405403

406404
/// See the `error_reporting` module for more details.
@@ -679,14 +677,14 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
679677
/// the bound values in `C` to their instantiated values in `V`
680678
/// (in other words, `S(C) = V`).
681679
pub fn build_with_canonical<T>(
682-
&mut self,
680+
self,
683681
span: Span,
684682
canonical: &Canonical<'tcx, T>,
685683
) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>)
686684
where
687685
T: TypeFoldable<TyCtxt<'tcx>>,
688686
{
689-
let infcx = self.build();
687+
let infcx = self.with_opaque_type_inference(canonical.defining_anchor).build();
690688
let (value, args) = infcx.instantiate_canonical(span, canonical);
691689
(infcx, value, args)
692690
}

compiler/rustc_infer/src/infer/opaque_types/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ impl<'tcx> InferCtxt<'tcx> {
146146
return None;
147147
}
148148
}
149-
DefiningAnchor::Bubble => {}
150149
}
151150
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
152151
// We could accept this, but there are various ways to handle this situation, and we don't
@@ -373,7 +372,6 @@ impl<'tcx> InferCtxt<'tcx> {
373372
#[instrument(skip(self), level = "trace", ret)]
374373
pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<OpaqueTyOrigin> {
375374
let defined_opaque_types = match self.defining_use_anchor {
376-
DefiningAnchor::Bubble => return None,
377375
DefiningAnchor::Bind(bind) => bind,
378376
};
379377

compiler/rustc_middle/src/infer/canonical.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use std::ops::Index;
3333

3434
use crate::infer::MemberConstraint;
3535
use crate::mir::ConstraintCategory;
36+
use crate::traits::DefiningAnchor;
3637
use crate::ty::GenericArg;
3738
use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt, TypeFlags, TypeVisitableExt};
3839

@@ -153,11 +154,6 @@ pub struct QueryResponse<'tcx, R> {
153154
pub var_values: CanonicalVarValues<'tcx>,
154155
pub region_constraints: QueryRegionConstraints<'tcx>,
155156
pub certainty: Certainty,
156-
/// List of opaque types which we tried to compare to another type.
157-
/// Inside the query we don't know yet whether the opaque type actually
158-
/// should get its hidden type inferred. So we bubble the opaque type
159-
/// and the type it was compared against upwards and let the query caller
160-
/// handle it.
161157
pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
162158
pub value: R,
163159
}
@@ -316,6 +312,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
316312
&self,
317313
tcx: TyCtxt<'tcx>,
318314
key: ty::ParamEnv<'tcx>,
315+
defining_anchor: DefiningAnchor<'tcx>,
319316
state: &mut OriginalQueryValues<'tcx>,
320317
canonicalize_op: fn(
321318
TyCtxt<'tcx>,
@@ -330,6 +327,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
330327
max_universe: ty::UniverseIndex::ROOT,
331328
variables: List::empty(),
332329
value: key,
330+
defining_anchor,
333331
};
334332
}
335333

@@ -344,7 +342,8 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
344342
*canonical
345343
}
346344
Entry::Vacant(e) => {
347-
let canonical = canonicalize_op(tcx, key, state);
345+
let mut canonical = canonicalize_op(tcx, key, state);
346+
canonical.defining_anchor = defining_anchor;
348347
let OriginalQueryValues { var_values, universe_map } = state;
349348
assert_eq!(universe_map.len(), 1);
350349
e.insert((canonical, tcx.arena.alloc_slice(var_values)));

compiler/rustc_middle/src/query/plumbing.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,10 @@ macro_rules! define_callbacks {
338338

339339
pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erase<$V>>;
340340

341-
// Ensure that keys grow no larger than 64 bytes
341+
// Ensure that keys grow no larger than 72 bytes
342342
#[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
343343
const _: () = {
344-
if mem::size_of::<Key<'static>>() > 64 {
344+
if mem::size_of::<Key<'static>>() > 72 {
345345
panic!("{}", concat!(
346346
"the query `",
347347
stringify!($name),
@@ -352,10 +352,10 @@ macro_rules! define_callbacks {
352352
}
353353
};
354354

355-
// Ensure that values grow no larger than 64 bytes
355+
// Ensure that values grow no larger than 72 bytes
356356
#[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
357357
const _: () = {
358-
if mem::size_of::<Value<'static>>() > 64 {
358+
if mem::size_of::<Value<'static>>() > 72 {
359359
panic!("{}", concat!(
360360
"the query `",
361361
stringify!($name),

compiler/rustc_middle/src/traits/mod.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,7 @@ pub enum CodegenObligationError {
10041004
/// opaques are replaced with inference vars eagerly in the old solver (e.g.
10051005
/// in projection, and in the signature during function type-checking).
10061006
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
1007+
#[derive(TyEncodable, TyDecodable)]
10071008
pub enum DefiningAnchor<'tcx> {
10081009
/// Define opaques which are in-scope of the current item being analyzed.
10091010
/// Also, eagerly replace these opaque types in `replace_opaque_types_with_inference_vars`.
@@ -1012,14 +1013,12 @@ pub enum DefiningAnchor<'tcx> {
10121013
/// errors when handling opaque types, and also should be used when we would
10131014
/// otherwise reveal opaques (such as [`Reveal::All`] reveal mode).
10141015
Bind(&'tcx ty::List<LocalDefId>),
1015-
/// In contexts where we don't currently know what opaques are allowed to be
1016-
/// defined, such as (old solver) canonical queries, we will simply allow
1017-
/// opaques to be defined, but "bubble" them up in the canonical response or
1018-
/// otherwise treat them to be handled later.
1019-
///
1020-
/// We do not eagerly replace opaque types in `replace_opaque_types_with_inference_vars`,
1021-
/// which may affect what predicates pass and fail in the old trait solver.
1022-
Bubble,
1016+
}
1017+
1018+
impl Default for DefiningAnchor<'_> {
1019+
fn default() -> Self {
1020+
Self::Bind(ty::List::empty())
1021+
}
10231022
}
10241023

10251024
impl<'tcx> DefiningAnchor<'tcx> {

compiler/rustc_middle/src/traits/solve.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_span::def_id::DefId;
44

55
use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints};
66
use crate::traits::query::NoSolution;
7-
use crate::traits::{Canonical, DefiningAnchor};
7+
use crate::traits::Canonical;
88
use crate::ty::{
99
self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable,
1010
TypeVisitor,
@@ -114,7 +114,6 @@ impl MaybeCause {
114114
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
115115
pub struct QueryInput<'tcx, T> {
116116
pub goal: Goal<'tcx, T>,
117-
pub anchor: DefiningAnchor<'tcx>,
118117
pub predefined_opaques_in_body: PredefinedOpaques<'tcx>,
119118
}
120119

compiler/rustc_middle/src/ty/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ use std::ops::{Bound, Deref};
8484
#[allow(rustc::usage_of_ty_tykind)]
8585
impl<'tcx> Interner for TyCtxt<'tcx> {
8686
type DefId = DefId;
87+
type DefiningAnchor = traits::DefiningAnchor<'tcx>;
8788
type AdtDef = ty::AdtDef<'tcx>;
8889
type GenericArgs = ty::GenericArgsRef<'tcx>;
8990
type GenericArg = ty::GenericArg<'tcx>;

compiler/rustc_next_trait_solver/src/canonicalizer.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
6969

7070
let (max_universe, variables) = canonicalizer.finalize();
7171

72-
Canonical { max_universe, variables, value }
72+
let defining_anchor = infcx.defining_anchor();
73+
Canonical { defining_anchor, max_universe, variables, value }
7374
}
7475

7576
fn finalize(self) -> (ty::UniverseIndex, I::CanonicalVars) {

0 commit comments

Comments
 (0)