summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/infer/opaque_types.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs53
1 files changed, 29 insertions, 24 deletions
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 8c9ddf866..a982f11f7 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -1,14 +1,16 @@
use crate::errors::OpaqueHiddenTypeDiag;
use crate::infer::{DefiningAnchor, InferCtxt, InferOk};
use crate::traits;
+use hir::def::DefKind;
use hir::def_id::{DefId, LocalDefId};
use hir::{HirId, OpaqueTyOrigin};
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::vec_map::VecMap;
use rustc_hir as hir;
use rustc_middle::traits::ObligationCause;
+use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::BottomUpFolder;
-use rustc_middle::ty::subst::{GenericArgKind, Subst};
+use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::{
self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
TypeVisitable, TypeVisitor,
@@ -40,7 +42,7 @@ pub struct OpaqueTypeDecl<'tcx> {
pub origin: hir::OpaqueTyOrigin,
}
-impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
+impl<'tcx> InferCtxt<'tcx> {
/// This is a backwards compatibility hack to prevent breaking changes from
/// lazy TAIT around RPIT handling.
pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<'tcx>>(
@@ -101,7 +103,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
return Ok(InferOk { value: (), obligations: vec![] });
}
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
- let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
+ let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() {
ty::Opaque(def_id, substs) if def_id.is_local() => {
let def_id = def_id.expect_local();
let origin = match self.defining_use_anchor {
@@ -167,25 +169,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
param_env,
b,
origin,
+ a_is_expected,
))
}
_ => None,
};
- if let Some(res) = process(a, b) {
+ if let Some(res) = process(a, b, true) {
res
- } else if let Some(res) = process(b, a) {
+ } else if let Some(res) = process(b, a, false) {
res
} else {
- // Rerun equality check, but this time error out due to
- // different types.
- match self.at(cause, param_env).define_opaque_types(false).eq(a, b) {
- Ok(_) => span_bug!(
- cause.span,
- "opaque types are never equal to anything but themselves: {:#?}",
- (a.kind(), b.kind())
- ),
- Err(e) => Err(e),
- }
+ let (a, b) = self.resolve_vars_if_possible((a, b));
+ Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
}
}
@@ -518,15 +513,16 @@ impl UseKind {
}
}
-impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
+impl<'tcx> InferCtxt<'tcx> {
#[instrument(skip(self), level = "debug")]
- pub fn register_hidden_type(
+ fn register_hidden_type(
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>,
origin: hir::OpaqueTyOrigin,
+ a_is_expected: bool,
) -> InferResult<'tcx, ()> {
let tcx = self.tcx;
let OpaqueTypeKey { def_id, substs } = opaque_type_key;
@@ -545,21 +541,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
origin,
);
if let Some(prev) = prev {
- obligations = self.at(&cause, param_env).eq(prev, hidden_ty)?.obligations;
+ obligations =
+ self.at(&cause, param_env).eq_exp(a_is_expected, prev, hidden_ty)?.obligations;
}
let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id());
- for predicate in item_bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
- debug!(?predicate);
- let predicate = predicate.subst(tcx, substs);
-
+ for (predicate, _) in item_bounds.subst_iter_copied(tcx, substs) {
let predicate = predicate.fold_with(&mut BottomUpFolder {
tcx,
ty_op: |ty| match *ty.kind() {
// We can't normalize associated types from `rustc_infer`,
// but we can eagerly register inference variables for them.
- ty::Projection(projection_ty) if !projection_ty.has_escaping_bound_vars() => {
+ // FIXME(RPITIT): Don't replace RPITITs with inference vars.
+ ty::Projection(projection_ty)
+ if !projection_ty.has_escaping_bound_vars()
+ && tcx.def_kind(projection_ty.item_def_id)
+ != DefKind::ImplTraitPlaceholder =>
+ {
self.infer_projection(
param_env,
projection_ty,
@@ -575,6 +574,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
{
hidden_ty
}
+ // FIXME(RPITIT): This can go away when we move to associated types
+ ty::Projection(proj)
+ if def_id.to_def_id() == proj.item_def_id && substs == proj.substs =>
+ {
+ hidden_ty
+ }
_ => ty,
},
lt_op: |lt| lt,
@@ -623,7 +628,7 @@ fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hi
let scope = tcx.hir().get_defining_scope(opaque_hir_id);
// We walk up the node tree until we hit the root or the scope of the opaque type.
while hir_id != scope && hir_id != hir::CRATE_HIR_ID {
- hir_id = tcx.hir().local_def_id_to_hir_id(tcx.hir().get_parent_item(hir_id));
+ hir_id = tcx.hir().get_parent_item(hir_id).into();
}
// Syntactically, we are allowed to define the concrete type if:
let res = hir_id == scope;