2016-02-03 16:37:23 +00:00
|
|
|
//! Constraint construction and representation
|
|
|
|
//!
|
|
|
|
//! The second pass over the AST determines the set of constraints.
|
|
|
|
//! We walk the set of items and, for each member, generate new constraints.
|
|
|
|
|
2020-04-12 12:45:41 +00:00
|
|
|
use hir::def_id::{DefId, LocalDefId};
|
2020-01-05 01:37:57 +00:00
|
|
|
use rustc_hir as hir;
|
2022-04-27 21:22:58 +00:00
|
|
|
use rustc_hir::def::DefKind;
|
2023-09-26 02:15:32 +00:00
|
|
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
2023-07-11 21:35:29 +00:00
|
|
|
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
2016-02-03 16:37:23 +00:00
|
|
|
|
|
|
|
use super::terms::VarianceTerm::*;
|
|
|
|
use super::terms::*;
|
|
|
|
|
2019-06-14 16:39:39 +00:00
|
|
|
pub struct ConstraintContext<'a, 'tcx> {
|
2016-02-03 16:37:23 +00:00
|
|
|
pub terms_cx: TermsContext<'a, 'tcx>,
|
|
|
|
|
|
|
|
// These are pointers to common `ConstantTerm` instances
|
|
|
|
covariant: VarianceTermPtr<'a>,
|
|
|
|
contravariant: VarianceTermPtr<'a>,
|
|
|
|
invariant: VarianceTermPtr<'a>,
|
|
|
|
bivariant: VarianceTermPtr<'a>,
|
|
|
|
|
2016-09-26 03:14:41 +00:00
|
|
|
pub constraints: Vec<Constraint<'a>>,
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Declares that the variable `decl_id` appears in a location with
|
|
|
|
/// variance `variance`.
|
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
pub struct Constraint<'a> {
|
|
|
|
pub inferred: InferredIndex,
|
|
|
|
pub variance: &'a VarianceTerm<'a>,
|
|
|
|
}
|
|
|
|
|
2017-08-10 22:16:18 +00:00
|
|
|
/// To build constraints, we visit one item (type, trait) at a time
|
2018-11-27 02:59:49 +00:00
|
|
|
/// and look at its contents. So e.g., if we have
|
2022-04-15 22:04:34 +00:00
|
|
|
/// ```ignore (illustrative)
|
|
|
|
/// struct Foo<T> {
|
|
|
|
/// b: Bar<T>
|
|
|
|
/// }
|
|
|
|
/// ```
|
2017-04-23 09:44:02 +00:00
|
|
|
/// then while we are visiting `Bar<T>`, the `CurrentItem` would have
|
2019-02-08 13:53:55 +00:00
|
|
|
/// the `DefId` and the start of `Foo`'s inferreds.
|
2017-06-02 19:05:41 +00:00
|
|
|
pub struct CurrentItem {
|
|
|
|
inferred_start: InferredIndex,
|
2017-04-23 09:44:02 +00:00
|
|
|
}
|
|
|
|
|
2016-02-03 21:00:23 +00:00
|
|
|
pub fn add_constraints_from_crate<'a, 'tcx>(
|
|
|
|
terms_cx: TermsContext<'a, 'tcx>,
|
2016-09-26 03:14:41 +00:00
|
|
|
) -> ConstraintContext<'a, 'tcx> {
|
2016-02-03 21:00:23 +00:00
|
|
|
let tcx = terms_cx.tcx;
|
2016-02-03 16:37:23 +00:00
|
|
|
let covariant = terms_cx.arena.alloc(ConstantTerm(ty::Covariant));
|
|
|
|
let contravariant = terms_cx.arena.alloc(ConstantTerm(ty::Contravariant));
|
|
|
|
let invariant = terms_cx.arena.alloc(ConstantTerm(ty::Invariant));
|
|
|
|
let bivariant = terms_cx.arena.alloc(ConstantTerm(ty::Bivariant));
|
|
|
|
let mut constraint_cx = ConstraintContext {
|
2017-08-07 05:54:09 +00:00
|
|
|
terms_cx,
|
|
|
|
covariant,
|
|
|
|
contravariant,
|
|
|
|
invariant,
|
|
|
|
bivariant,
|
2016-02-03 16:37:23 +00:00
|
|
|
constraints: Vec::new(),
|
|
|
|
};
|
2016-02-03 21:00:23 +00:00
|
|
|
|
2022-04-27 21:22:58 +00:00
|
|
|
let crate_items = tcx.hir_crate_items(());
|
|
|
|
|
2022-06-25 13:30:38 +00:00
|
|
|
for def_id in crate_items.definitions() {
|
|
|
|
let def_kind = tcx.def_kind(def_id);
|
2022-04-27 21:22:58 +00:00
|
|
|
match def_kind {
|
2022-06-25 13:30:38 +00:00
|
|
|
DefKind::Struct | DefKind::Union | DefKind::Enum => {
|
|
|
|
constraint_cx.build_constraints_for_item(def_id);
|
2022-04-27 21:22:58 +00:00
|
|
|
|
2022-06-25 13:30:38 +00:00
|
|
|
let adt = tcx.adt_def(def_id);
|
|
|
|
for variant in adt.variants() {
|
2022-10-25 16:15:15 +00:00
|
|
|
if let Some(ctor_def_id) = variant.ctor_def_id() {
|
|
|
|
constraint_cx.build_constraints_for_item(ctor_def_id.expect_local());
|
2022-04-27 21:22:58 +00:00
|
|
|
}
|
2017-06-02 19:05:41 +00:00
|
|
|
}
|
|
|
|
}
|
2022-06-25 13:30:38 +00:00
|
|
|
DefKind::Fn | DefKind::AssocFn => constraint_cx.build_constraints_for_item(def_id),
|
2023-09-26 02:15:32 +00:00
|
|
|
DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
|
2023-08-02 23:03:31 +00:00
|
|
|
constraint_cx.build_constraints_for_item(def_id)
|
|
|
|
}
|
2017-06-02 19:05:41 +00:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-25 13:30:38 +00:00
|
|
|
constraint_cx
|
|
|
|
}
|
2017-04-24 15:15:12 +00:00
|
|
|
|
2022-06-25 13:30:38 +00:00
|
|
|
impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
2019-06-13 21:48:52 +00:00
|
|
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
2017-04-24 15:15:12 +00:00
|
|
|
self.terms_cx.tcx
|
|
|
|
}
|
|
|
|
|
2020-04-12 12:45:41 +00:00
|
|
|
fn build_constraints_for_item(&mut self, def_id: LocalDefId) {
|
2017-04-24 15:15:12 +00:00
|
|
|
let tcx = self.tcx();
|
2023-02-16 09:25:11 +00:00
|
|
|
debug!("build_constraints_for_item({})", tcx.def_path_str(def_id));
|
2016-02-03 16:37:23 +00:00
|
|
|
|
2017-06-02 19:05:41 +00:00
|
|
|
// Skip items with no generics - there's nothing to infer in them.
|
|
|
|
if tcx.generics_of(def_id).count() == 0 {
|
|
|
|
return;
|
|
|
|
}
|
2016-02-03 16:37:23 +00:00
|
|
|
|
2022-06-25 13:30:38 +00:00
|
|
|
let inferred_start = self.terms_cx.inferred_starts[&def_id];
|
2017-10-23 15:47:07 +00:00
|
|
|
let current_item = &CurrentItem { inferred_start };
|
2023-08-02 23:03:31 +00:00
|
|
|
let ty = tcx.type_of(def_id).instantiate_identity();
|
|
|
|
|
|
|
|
// The type as returned by `type_of` is the underlying type and generally not a weak projection.
|
|
|
|
// Therefore we need to check the `DefKind` first.
|
2023-09-26 02:15:32 +00:00
|
|
|
if let DefKind::TyAlias = tcx.def_kind(def_id)
|
|
|
|
&& tcx.type_alias_is_lazy(def_id)
|
2023-08-02 23:03:31 +00:00
|
|
|
{
|
|
|
|
self.add_constraints_from_ty(current_item, ty, self.covariant);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
match ty.kind() {
|
2018-08-22 00:35:02 +00:00
|
|
|
ty::Adt(def, _) => {
|
2016-02-03 16:37:23 +00:00
|
|
|
// Not entirely obvious: constraints on structs/enums do not
|
|
|
|
// affect the variance of their type parameters. See discussion
|
|
|
|
// in comment at top of module.
|
|
|
|
//
|
2016-11-10 14:49:53 +00:00
|
|
|
// self.add_constraints_from_generics(generics);
|
2016-02-03 16:37:23 +00:00
|
|
|
|
2017-06-02 19:05:41 +00:00
|
|
|
for field in def.all_fields() {
|
2017-04-23 09:44:02 +00:00
|
|
|
self.add_constraints_from_ty(
|
|
|
|
current_item,
|
2023-07-11 21:35:29 +00:00
|
|
|
tcx.type_of(field.did).instantiate_identity(),
|
2016-02-03 16:37:23 +00:00
|
|
|
self.covariant,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-22 00:35:02 +00:00
|
|
|
ty::FnDef(..) => {
|
2023-01-18 22:43:20 +00:00
|
|
|
self.add_constraints_from_sig(
|
|
|
|
current_item,
|
2023-07-11 21:35:29 +00:00
|
|
|
tcx.fn_sig(def_id).instantiate_identity(),
|
2023-01-18 22:43:20 +00:00
|
|
|
self.covariant,
|
|
|
|
);
|
2017-04-24 15:15:12 +00:00
|
|
|
}
|
2016-02-03 16:37:23 +00:00
|
|
|
|
2020-07-31 21:33:55 +00:00
|
|
|
ty::Error(_) => {}
|
2023-08-02 23:03:31 +00:00
|
|
|
|
2020-07-31 21:33:55 +00:00
|
|
|
_ => {
|
|
|
|
span_bug!(
|
|
|
|
tcx.def_span(def_id),
|
|
|
|
"`build_constraints_for_item` unsupported for this item"
|
|
|
|
);
|
|
|
|
}
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_constraint(&mut self, current: &CurrentItem, index: u32, variance: VarianceTermPtr<'a>) {
|
2016-09-26 03:14:41 +00:00
|
|
|
debug!("add_constraint(index={}, variance={:?})", index, variance);
|
|
|
|
self.constraints.push(Constraint {
|
2017-06-02 19:05:41 +00:00
|
|
|
inferred: InferredIndex(current.inferred_start.0 + index as usize),
|
2017-08-07 05:54:09 +00:00
|
|
|
variance,
|
2016-09-26 03:14:41 +00:00
|
|
|
});
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 03:14:41 +00:00
|
|
|
fn contravariant(&mut self, variance: VarianceTermPtr<'a>) -> VarianceTermPtr<'a> {
|
2016-02-03 16:37:23 +00:00
|
|
|
self.xform(variance, self.contravariant)
|
|
|
|
}
|
|
|
|
|
2016-09-26 03:14:41 +00:00
|
|
|
fn invariant(&mut self, variance: VarianceTermPtr<'a>) -> VarianceTermPtr<'a> {
|
2016-02-03 16:37:23 +00:00
|
|
|
self.xform(variance, self.invariant)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn constant_term(&self, v: ty::Variance) -> VarianceTermPtr<'a> {
|
|
|
|
match v {
|
|
|
|
ty::Covariant => self.covariant,
|
|
|
|
ty::Invariant => self.invariant,
|
|
|
|
ty::Contravariant => self.contravariant,
|
|
|
|
ty::Bivariant => self.bivariant,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-26 03:14:41 +00:00
|
|
|
fn xform(&mut self, v1: VarianceTermPtr<'a>, v2: VarianceTermPtr<'a>) -> VarianceTermPtr<'a> {
|
2016-02-03 16:37:23 +00:00
|
|
|
match (*v1, *v2) {
|
|
|
|
(_, ConstantTerm(ty::Covariant)) => {
|
|
|
|
// Applying a "covariant" transform is always a no-op
|
|
|
|
v1
|
|
|
|
}
|
|
|
|
|
2016-09-26 03:14:41 +00:00
|
|
|
(ConstantTerm(c1), ConstantTerm(c2)) => self.constant_term(c1.xform(c2)),
|
2016-02-03 16:37:23 +00:00
|
|
|
|
2016-09-26 03:14:41 +00:00
|
|
|
_ => &*self.terms_cx.arena.alloc(TransformTerm(v1, v2)),
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-24 00:00:00 +00:00
|
|
|
#[instrument(level = "debug", skip(self, current))]
|
2023-07-11 21:35:29 +00:00
|
|
|
fn add_constraints_from_invariant_args(
|
2017-06-02 19:05:41 +00:00
|
|
|
&mut self,
|
|
|
|
current: &CurrentItem,
|
2023-07-11 21:35:29 +00:00
|
|
|
args: GenericArgsRef<'tcx>,
|
2017-06-02 19:05:41 +00:00
|
|
|
variance: VarianceTermPtr<'a>,
|
|
|
|
) {
|
|
|
|
// Trait are always invariant so we can take advantage of that.
|
|
|
|
let variance_i = self.invariant(variance);
|
|
|
|
|
2023-07-11 21:35:29 +00:00
|
|
|
for k in args {
|
2019-02-20 01:13:19 +00:00
|
|
|
match k.unpack() {
|
2019-09-25 15:39:44 +00:00
|
|
|
GenericArgKind::Lifetime(lt) => {
|
2019-02-20 01:13:19 +00:00
|
|
|
self.add_constraints_from_region(current, lt, variance_i)
|
|
|
|
}
|
|
|
|
GenericArgKind::Type(ty) => self.add_constraints_from_ty(current, ty, variance_i),
|
2021-10-07 21:14:33 +00:00
|
|
|
GenericArgKind::Const(val) => {
|
|
|
|
self.add_constraints_from_const(current, val, variance_i)
|
2019-02-20 01:13:19 +00:00
|
|
|
}
|
|
|
|
}
|
2017-06-02 19:05:41 +00:00
|
|
|
}
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Adds constraints appropriate for an instance of `ty` appearing
|
|
|
|
/// in a context with the generics defined in `generics` and
|
|
|
|
/// ambient variance `variance`
|
|
|
|
fn add_constraints_from_ty(
|
|
|
|
&mut self,
|
2017-04-23 09:44:02 +00:00
|
|
|
current: &CurrentItem,
|
2016-02-03 16:37:23 +00:00
|
|
|
ty: Ty<'tcx>,
|
|
|
|
variance: VarianceTermPtr<'a>,
|
|
|
|
) {
|
|
|
|
debug!("add_constraints_from_ty(ty={:?}, variance={:?})", ty, variance);
|
|
|
|
|
2020-08-02 22:49:11 +00:00
|
|
|
match *ty.kind() {
|
2018-08-22 00:35:55 +00:00
|
|
|
ty::Bool
|
|
|
|
| ty::Char
|
|
|
|
| ty::Int(_)
|
|
|
|
| ty::Uint(_)
|
|
|
|
| ty::Float(_)
|
|
|
|
| ty::Str
|
|
|
|
| ty::Never
|
|
|
|
| ty::Foreign(..) => {
|
2016-09-26 03:14:41 +00:00
|
|
|
// leaf type -- noop
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2024-01-24 18:01:56 +00:00
|
|
|
ty::FnDef(..) | ty::Coroutine(..) | ty::Closure(..) | ty::CoroutineClosure(..) => {
|
|
|
|
bug!("Unexpected coroutine/closure type in variance computation");
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2018-08-22 00:35:02 +00:00
|
|
|
ty::Ref(region, ty, mutbl) => {
|
2023-01-26 23:23:08 +00:00
|
|
|
self.add_constraints_from_region(current, region, variance);
|
2018-05-02 13:21:05 +00:00
|
|
|
self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2021-10-07 21:14:33 +00:00
|
|
|
ty::Array(typ, len) => {
|
|
|
|
self.add_constraints_from_const(current, len, variance);
|
2019-02-20 01:13:19 +00:00
|
|
|
self.add_constraints_from_ty(current, typ, variance);
|
|
|
|
}
|
|
|
|
|
2018-08-22 00:35:02 +00:00
|
|
|
ty::Slice(typ) => {
|
2017-04-23 09:44:02 +00:00
|
|
|
self.add_constraints_from_ty(current, typ, variance);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2018-08-22 00:35:02 +00:00
|
|
|
ty::RawPtr(ref mt) => {
|
2017-04-23 09:44:02 +00:00
|
|
|
self.add_constraints_from_mt(current, mt, variance);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2018-08-22 00:35:02 +00:00
|
|
|
ty::Tuple(subtys) => {
|
2020-05-23 09:49:24 +00:00
|
|
|
for subty in subtys {
|
2022-02-07 15:06:31 +00:00
|
|
|
self.add_constraints_from_ty(current, subty, variance);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-11 21:35:29 +00:00
|
|
|
ty::Adt(def, args) => {
|
|
|
|
self.add_constraints_from_args(current, def.did(), args, variance);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2023-08-02 23:03:31 +00:00
|
|
|
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, ref data) => {
|
2023-07-11 21:35:29 +00:00
|
|
|
self.add_constraints_from_invariant_args(current, data.args, variance);
|
2017-06-02 19:05:41 +00:00
|
|
|
}
|
|
|
|
|
2023-08-02 23:03:31 +00:00
|
|
|
ty::Alias(ty::Weak, ref data) => {
|
|
|
|
self.add_constraints_from_args(current, data.def_id, data.args, variance);
|
|
|
|
}
|
|
|
|
|
2022-04-13 23:11:28 +00:00
|
|
|
ty::Dynamic(data, r, _) => {
|
2023-01-27 09:43:29 +00:00
|
|
|
// The type `dyn Trait<T> +'a` is covariant w/r/t `'a`:
|
2023-01-26 23:23:08 +00:00
|
|
|
self.add_constraints_from_region(current, r, variance);
|
2016-02-03 16:37:23 +00:00
|
|
|
|
2018-12-04 11:28:06 +00:00
|
|
|
if let Some(poly_trait_ref) = data.principal() {
|
2023-07-11 21:35:29 +00:00
|
|
|
self.add_constraints_from_invariant_args(
|
2018-12-04 11:28:06 +00:00
|
|
|
current,
|
2023-07-11 21:35:29 +00:00
|
|
|
poly_trait_ref.skip_binder().args,
|
2018-12-04 11:28:06 +00:00
|
|
|
variance,
|
|
|
|
);
|
|
|
|
}
|
2016-02-03 16:37:23 +00:00
|
|
|
|
2016-11-16 16:21:49 +00:00
|
|
|
for projection in data.projection_bounds() {
|
2022-09-05 04:03:53 +00:00
|
|
|
match projection.skip_binder().term.unpack() {
|
|
|
|
ty::TermKind::Ty(ty) => {
|
2022-01-13 07:39:58 +00:00
|
|
|
self.add_constraints_from_ty(current, ty, self.invariant);
|
|
|
|
}
|
2022-09-05 04:03:53 +00:00
|
|
|
ty::TermKind::Const(c) => {
|
2022-01-13 07:39:58 +00:00
|
|
|
self.add_constraints_from_const(current, c, self.invariant)
|
|
|
|
}
|
|
|
|
}
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-22 00:35:29 +00:00
|
|
|
ty::Param(ref data) => {
|
2019-05-06 12:12:04 +00:00
|
|
|
self.add_constraint(current, data.index, variance);
|
2017-07-14 23:37:43 +00:00
|
|
|
}
|
2016-02-03 16:37:23 +00:00
|
|
|
|
2018-08-22 00:35:02 +00:00
|
|
|
ty::FnPtr(sig) => {
|
2017-04-23 09:44:02 +00:00
|
|
|
self.add_constraints_from_sig(current, sig, variance);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2020-05-06 04:02:09 +00:00
|
|
|
ty::Error(_) => {
|
2016-02-03 16:37:23 +00:00
|
|
|
// we encounter this when walking the trait references for object
|
2018-08-22 00:35:02 +00:00
|
|
|
// types, where we use Error as the Self type
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2023-10-19 16:06:43 +00:00
|
|
|
ty::Placeholder(..) | ty::CoroutineWitness(..) | ty::Bound(..) | ty::Infer(..) => {
|
2022-10-01 12:56:24 +00:00
|
|
|
bug!("unexpected type encountered in variance inference: {}", ty);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Adds constraints appropriate for a nominal type (enum, struct,
|
|
|
|
/// object, etc) appearing in a context with ambient variance `variance`
|
2023-07-11 21:35:29 +00:00
|
|
|
fn add_constraints_from_args(
|
2016-02-03 16:37:23 +00:00
|
|
|
&mut self,
|
2017-04-23 09:44:02 +00:00
|
|
|
current: &CurrentItem,
|
2016-02-03 16:37:23 +00:00
|
|
|
def_id: DefId,
|
2023-07-11 21:35:29 +00:00
|
|
|
args: GenericArgsRef<'tcx>,
|
2016-02-03 16:37:23 +00:00
|
|
|
variance: VarianceTermPtr<'a>,
|
|
|
|
) {
|
|
|
|
debug!(
|
2023-07-11 21:35:29 +00:00
|
|
|
"add_constraints_from_args(def_id={:?}, args={:?}, variance={:?})",
|
|
|
|
def_id, args, variance
|
2016-02-03 16:37:23 +00:00
|
|
|
);
|
|
|
|
|
2017-06-02 19:05:41 +00:00
|
|
|
// We don't record `inferred_starts` entries for empty generics.
|
2023-07-11 21:35:29 +00:00
|
|
|
if args.is_empty() {
|
2017-06-02 19:05:41 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-23 19:48:40 +00:00
|
|
|
let (local, remote) = if let Some(def_id) = def_id.as_local() {
|
2022-06-25 13:30:38 +00:00
|
|
|
(Some(self.terms_cx.inferred_starts[&def_id]), None)
|
2017-06-02 19:05:41 +00:00
|
|
|
} else {
|
|
|
|
(None, Some(self.tcx().variances_of(def_id)))
|
|
|
|
};
|
|
|
|
|
2023-07-11 21:35:29 +00:00
|
|
|
for (i, k) in args.iter().enumerate() {
|
2017-06-02 19:05:41 +00:00
|
|
|
let variance_decl = if let Some(InferredIndex(start)) = local {
|
|
|
|
// Parameter on an item defined within current crate:
|
|
|
|
// variance not yet inferred, so return a symbolic
|
|
|
|
// variance.
|
|
|
|
self.terms_cx.inferred_terms[start + i]
|
|
|
|
} else {
|
|
|
|
// Parameter on an item defined within another crate:
|
|
|
|
// variance already inferred, just look it up.
|
|
|
|
self.constant_term(remote.as_ref().unwrap()[i])
|
|
|
|
};
|
2016-02-03 16:37:23 +00:00
|
|
|
let variance_i = self.xform(variance, variance_decl);
|
|
|
|
debug!(
|
2023-07-11 21:35:29 +00:00
|
|
|
"add_constraints_from_args: variance_decl={:?} variance_i={:?}",
|
2016-09-26 03:14:41 +00:00
|
|
|
variance_decl, variance_i
|
|
|
|
);
|
2018-02-23 01:13:54 +00:00
|
|
|
match k.unpack() {
|
2019-09-25 15:39:44 +00:00
|
|
|
GenericArgKind::Lifetime(lt) => {
|
2018-02-23 01:13:54 +00:00
|
|
|
self.add_constraints_from_region(current, lt, variance_i)
|
|
|
|
}
|
|
|
|
GenericArgKind::Type(ty) => self.add_constraints_from_ty(current, ty, variance_i),
|
2021-10-07 21:14:33 +00:00
|
|
|
GenericArgKind::Const(val) => {
|
|
|
|
self.add_constraints_from_const(current, val, variance)
|
2019-02-20 01:13:19 +00:00
|
|
|
}
|
2017-07-14 23:37:43 +00:00
|
|
|
}
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-07 21:14:33 +00:00
|
|
|
/// Adds constraints appropriate for a const expression `val`
|
|
|
|
/// in a context with ambient variance `variance`
|
|
|
|
fn add_constraints_from_const(
|
|
|
|
&mut self,
|
|
|
|
current: &CurrentItem,
|
2022-06-10 01:18:06 +00:00
|
|
|
c: ty::Const<'tcx>,
|
2021-10-07 21:14:33 +00:00
|
|
|
variance: VarianceTermPtr<'a>,
|
|
|
|
) {
|
2022-06-10 01:18:06 +00:00
|
|
|
debug!("add_constraints_from_const(c={:?}, variance={:?})", c, variance);
|
2021-10-07 21:14:33 +00:00
|
|
|
|
2022-06-10 01:18:06 +00:00
|
|
|
match &c.kind() {
|
2021-10-07 21:14:33 +00:00
|
|
|
ty::ConstKind::Unevaluated(uv) => {
|
2023-07-11 21:35:29 +00:00
|
|
|
self.add_constraints_from_invariant_args(current, uv.args, variance);
|
2021-10-07 21:14:33 +00:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-03 16:37:23 +00:00
|
|
|
/// Adds constraints appropriate for a function with signature
|
|
|
|
/// `sig` appearing in a context with ambient variance `variance`
|
|
|
|
fn add_constraints_from_sig(
|
|
|
|
&mut self,
|
2017-04-23 09:44:02 +00:00
|
|
|
current: &CurrentItem,
|
2017-02-13 08:51:06 +00:00
|
|
|
sig: ty::PolyFnSig<'tcx>,
|
2016-02-03 16:37:23 +00:00
|
|
|
variance: VarianceTermPtr<'a>,
|
|
|
|
) {
|
|
|
|
let contra = self.contravariant(variance);
|
2018-04-25 02:45:49 +00:00
|
|
|
for &input in sig.skip_binder().inputs() {
|
2017-04-23 09:44:02 +00:00
|
|
|
self.add_constraints_from_ty(current, input, contra);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
2018-04-25 02:45:49 +00:00
|
|
|
self.add_constraints_from_ty(current, sig.skip_binder().output(), variance);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Adds constraints appropriate for a region appearing in a
|
|
|
|
/// context with ambient variance `variance`
|
|
|
|
fn add_constraints_from_region(
|
|
|
|
&mut self,
|
2017-04-23 09:44:02 +00:00
|
|
|
current: &CurrentItem,
|
2017-04-20 08:45:53 +00:00
|
|
|
region: ty::Region<'tcx>,
|
2016-02-03 16:37:23 +00:00
|
|
|
variance: VarianceTermPtr<'a>,
|
|
|
|
) {
|
2016-08-25 20:58:52 +00:00
|
|
|
match *region {
|
2023-11-14 13:13:27 +00:00
|
|
|
ty::ReEarlyParam(ref data) => {
|
2017-06-02 19:05:41 +00:00
|
|
|
self.add_constraint(current, data.index, variance);
|
2017-07-14 23:37:43 +00:00
|
|
|
}
|
2016-02-03 16:37:23 +00:00
|
|
|
|
2016-09-26 03:14:41 +00:00
|
|
|
ty::ReStatic => {}
|
2016-02-03 16:37:23 +00:00
|
|
|
|
2023-11-13 14:00:05 +00:00
|
|
|
ty::ReBound(..) => {
|
|
|
|
// Either a higher-ranked region inside of a type or a
|
|
|
|
// late-bound function parameter.
|
|
|
|
//
|
|
|
|
// We do not compute constraints for either of these.
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2023-02-07 14:55:16 +00:00
|
|
|
ty::ReError(_) => {}
|
2023-02-03 23:21:56 +00:00
|
|
|
|
2023-11-14 13:13:27 +00:00
|
|
|
ty::ReLateParam(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => {
|
2016-02-03 16:37:23 +00:00
|
|
|
// We don't expect to see anything but 'static or bound
|
|
|
|
// regions when visiting member types or method types.
|
2016-03-28 22:06:35 +00:00
|
|
|
bug!(
|
|
|
|
"unexpected region encountered in variance \
|
|
|
|
inference: {:?}",
|
|
|
|
region
|
|
|
|
);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Adds constraints appropriate for a mutability-type pair
|
|
|
|
/// appearing in a context with ambient variance `variance`
|
|
|
|
fn add_constraints_from_mt(
|
|
|
|
&mut self,
|
2017-04-23 09:44:02 +00:00
|
|
|
current: &CurrentItem,
|
2016-02-03 16:37:23 +00:00
|
|
|
mt: &ty::TypeAndMut<'tcx>,
|
|
|
|
variance: VarianceTermPtr<'a>,
|
|
|
|
) {
|
|
|
|
match mt.mutbl {
|
2019-12-16 16:28:40 +00:00
|
|
|
hir::Mutability::Mut => {
|
2016-02-03 16:37:23 +00:00
|
|
|
let invar = self.invariant(variance);
|
2017-04-23 09:44:02 +00:00
|
|
|
self.add_constraints_from_ty(current, mt.ty, invar);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 16:28:40 +00:00
|
|
|
hir::Mutability::Not => {
|
2017-04-23 09:44:02 +00:00
|
|
|
self.add_constraints_from_ty(current, mt.ty, variance);
|
2016-02-03 16:37:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|