use rustc::traits::query::{Fallible, NoSolution};
use rustc::traits::{ObligationCause, PredicateObligations};
use rustc::ty::fold::TypeFoldable;
-use rustc::ty::subst::{Subst, Substs, UnpackedKind, UserSelfTy, UserSubsts};
+use rustc::ty::subst::{Subst, Substs, UnpackedKind};
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
use std::rc::Rc;
use std::{fmt, iter};
locations: Locations,
category: ConstraintCategory,
) -> Fallible<()> {
- let tcx = self.tcx();
-
debug!(
- "relate_type_and_user_type(a={:?}, v={:?}, b={:?}, locations={:?})",
- a, v, user_ty, locations
+ "relate_type_and_user_type(a={:?}, v={:?}, user_ty={:?}, locations={:?})",
+ a, v, user_ty, locations,
);
- // The `TypeRelating` code assumes that "unresolved inference
- // variables" appear in the "a" side, so flip `Contravariant`
- // ambient variance to get the right relationship.
- let v1 = ty::Contravariant.xform(v);
-
match user_ty {
UserTypeAnnotation::Ty(canonical_ty) => {
let (ty, _) = self.infcx
.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_ty);
- self.relate_types(ty, v1, a, locations, category)?;
+ // The `TypeRelating` code assumes that "unresolved inference
+ // variables" appear in the "a" side, so flip `Contravariant`
+ // ambient variance to get the right relationship.
+ let v1 = ty::Contravariant.xform(v);
- self.prove_predicate(ty::Predicate::WellFormed(ty), locations, category);
+ self.relate_types(ty, v1, a, locations, category)?;
}
UserTypeAnnotation::TypeOf(def_id, canonical_substs) => {
let (
- UserSubsts {
- substs,
- user_self_ty,
- },
+ user_substs,
_,
) = self.infcx
.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_substs);
- let ty = self.tcx().type_of(def_id);
- let ty = ty.subst(tcx, substs);
- debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
- let ty = self.normalize(ty, locations);
-
- self.relate_types(ty, v1, a, locations, category)?;
-
- if let Some(UserSelfTy {
- impl_def_id,
- self_ty,
- }) = user_self_ty
- {
- let impl_self_ty = tcx.type_of(impl_def_id);
- let impl_self_ty = impl_self_ty.subst(tcx, &substs);
- let impl_self_ty = self.normalize(impl_self_ty, locations);
-
- // There may be type variables in `substs` and hence
- // in `impl_self_ty`, but they should all have been
- // resolved to some fixed value during the first call
- // to `relate`, above. Therefore, if we use
- // `resolve_type_vars_if_possible` we should get to
- // something without type variables. This is important
- // because the `b` type in `relate_with_variance`
- // below is not permitted to have inference variables.
- let impl_self_ty = self.infcx.resolve_type_vars_if_possible(&impl_self_ty);
- assert!(!impl_self_ty.has_infer_types());
-
- self.eq_types(self_ty, impl_self_ty, locations, category)?;
-
- self.prove_predicate(
- ty::Predicate::WellFormed(impl_self_ty),
- locations,
- category,
- );
- }
-
- // Prove the predicates coming along with `def_id`.
- //
- // Also, normalize the `instantiated_predicates`
- // because otherwise we wind up with duplicate "type
- // outlives" error messages.
- let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
- let instantiated_predicates = self.fold_to_region_vid(instantiated_predicates);
- self.normalize_and_prove_instantiated_predicates(
- instantiated_predicates,
+ self.fully_perform_op(
locations,
- );
-
- // In addition to proving the predicates, we have to
- // prove that `ty` is well-formed -- this is because
- // the WF of `ty` is predicated on the substs being
- // well-formed, and we haven't proven *that*. We don't
- // want to prove the WF of types from `substs` directly because they
- // haven't been normalized.
- //
- // FIXME(nmatsakis): Well, perhaps we should normalize
- // them? This would only be relevant if some input
- // type were ill-formed but did not appear in `ty`,
- // which...could happen with normalization...
- self.prove_predicate(ty::Predicate::WellFormed(ty), locations, category);
+ category,
+ self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
+ a, v, def_id, user_substs,
+ )),
+ )?;
}
}
Ok(())
}
- /// Replace all free regions in `value` with their NLL `RegionVid`
- /// equivalents; if not in NLL, does nothing. This is never
- /// particularly necessary -- we'll do it lazilly as we process
- /// the value anyway -- but in some specific cases it is useful to
- /// normalize so we can suppress duplicate error messages.
- fn fold_to_region_vid<T>(&self, value: T) -> T
- where
- T: TypeFoldable<'tcx>,
- {
- if let Some(borrowck_context) = &self.borrowck_context {
- self.tcx().fold_regions(&value, &mut false, |r, _debruijn| {
- if r.has_free_regions() {
- self.tcx().mk_region(ty::RegionKind::ReVar(
- borrowck_context.universal_regions.to_region_vid(r),
- ))
- } else {
- r
- }
- })
- } else {
- value
- }
- }
-
fn eq_opaque_type_and_type(
&mut self,
revealed_ty: Ty<'tcx>,