use borrow_check::nll::type_check::free_region_relations::{
CreateResult, UniversalRegionRelations,
};
-use borrow_check::nll::universal_regions::UniversalRegions;
+use borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions};
use borrow_check::nll::ToRegionVid;
use dataflow::move_paths::MoveData;
use dataflow::FlowAtLocation;
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};
let mut constraints = MirTypeckRegionConstraints {
liveness_constraints: LivenessValues::new(elements),
outlives_constraints: ConstraintSet::default(),
- closure_bounds_mapping: FxHashMap(),
+ closure_bounds_mapping: Default::default(),
type_tests: Vec::default(),
};
let mut placeholder_indices = PlaceholderIndices::default();
region_bound_pairs,
implicit_region_bound,
borrowck_context,
- reported_errors: FxHashSet(),
+ reported_errors: Default::default(),
universal_region_relations,
}
}
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);
- 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)?;
- }
-
- // 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>,
// of lowering. Assignments to other sorts of places *are* interesting
// though.
let category = match *place {
- Place::Local(RETURN_PLACE) => ConstraintCategory::Return,
+ Place::Local(RETURN_PLACE) => if let Some(BorrowCheckContext {
+ universal_regions:
+ UniversalRegions {
+ defining_ty: DefiningTy::Const(def_id, _),
+ ..
+ },
+ ..
+ }) = self.borrowck_context
+ {
+ if tcx.is_static(*def_id).is_some() {
+ ConstraintCategory::UseAsStatic
+ } else {
+ ConstraintCategory::UseAsConst
+ }
+ } else {
+ ConstraintCategory::Return
+ },
Place::Local(l) if !mir.local_decls[l].is_user_variable.is_some() => {
ConstraintCategory::Boring
}
ref func,
ref args,
ref destination,
+ from_hir_call,
..
} => {
let func_ty = func.ty(mir, tcx);
}
}
- self.check_call_inputs(mir, term, &sig, args, term_location);
+ self.check_call_inputs(mir, term, &sig, args, term_location, from_hir_call);
}
TerminatorKind::Assert {
ref cond, ref msg, ..
Some((ref dest, _target_block)) => {
let dest_ty = dest.ty(mir, tcx).to_ty(tcx);
let category = match *dest {
- Place::Local(RETURN_PLACE) => ConstraintCategory::Return,
+ Place::Local(RETURN_PLACE) => {
+ if let Some(BorrowCheckContext {
+ universal_regions:
+ UniversalRegions {
+ defining_ty: DefiningTy::Const(def_id, _),
+ ..
+ },
+ ..
+ }) = self.borrowck_context
+ {
+ if tcx.is_static(*def_id).is_some() {
+ ConstraintCategory::UseAsStatic
+ } else {
+ ConstraintCategory::UseAsConst
+ }
+ } else {
+ ConstraintCategory::Return
+ }
+ }
Place::Local(l) if !mir.local_decls[l].is_user_variable.is_some() => {
ConstraintCategory::Boring
}
sig: &ty::FnSig<'tcx>,
args: &[Operand<'tcx>],
term_location: Location,
+ from_hir_call: bool,
) {
debug!("check_call_inputs({:?}, {:?})", sig, args);
if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.variadic) {
}
for (n, (fn_arg, op_arg)) in sig.inputs().iter().zip(args).enumerate() {
let op_arg_ty = op_arg.ty(mir, self.tcx());
- if let Err(terr) = self.sub_types(
- op_arg_ty,
- fn_arg,
- term_location.to_locations(),
- ConstraintCategory::CallArgument,
- ) {
+ let category = if from_hir_call {
+ ConstraintCategory::CallArgument
+ } else {
+ ConstraintCategory::Boring
+ };
+ if let Err(terr) =
+ self.sub_types(op_arg_ty, fn_arg, term_location.to_locations(), category)
+ {
span_mirbug!(
self,
term,