move ty var instantiation into the generalize module
This commit is contained in:
parent
f65e743748
commit
88a559fa9f
10 changed files with 243 additions and 221 deletions
|
@ -23,19 +23,18 @@
|
||||||
//! this should be correctly updated.
|
//! this should be correctly updated.
|
||||||
|
|
||||||
use super::equate::Equate;
|
use super::equate::Equate;
|
||||||
use super::generalize::{self, CombineDelegate, Generalization};
|
|
||||||
use super::glb::Glb;
|
use super::glb::Glb;
|
||||||
use super::lub::Lub;
|
use super::lub::Lub;
|
||||||
use super::sub::Sub;
|
use super::sub::Sub;
|
||||||
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
|
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
|
||||||
use crate::traits::{Obligation, PredicateObligations};
|
use crate::traits::{Obligation, PredicateObligations};
|
||||||
use rustc_middle::infer::canonical::OriginalQueryValues;
|
use rustc_middle::infer::canonical::OriginalQueryValues;
|
||||||
use rustc_middle::infer::unify_key::{ConstVariableValue, EffectVarValue};
|
use rustc_middle::infer::unify_key::EffectVarValue;
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
|
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
|
||||||
use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_middle::ty::{AliasRelationDirection, TyVar};
|
|
||||||
use rustc_middle::ty::{IntType, UintType};
|
use rustc_middle::ty::{IntType, UintType};
|
||||||
|
use rustc_span::Span;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CombineFields<'infcx, 'tcx> {
|
pub struct CombineFields<'infcx, 'tcx> {
|
||||||
|
@ -221,11 +220,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
|
(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
|
||||||
return self.unify_const_variable(vid, b);
|
return self.instantiate_const_var(vid, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
|
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
|
||||||
return self.unify_const_variable(vid, a);
|
return self.instantiate_const_var(vid, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
(ty::ConstKind::Infer(InferConst::EffectVar(vid)), _) => {
|
(ty::ConstKind::Infer(InferConst::EffectVar(vid)), _) => {
|
||||||
|
@ -259,73 +258,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
ty::relate::structurally_relate_consts(relation, a, b)
|
ty::relate::structurally_relate_consts(relation, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unifies the const variable `target_vid` with the given constant.
|
|
||||||
///
|
|
||||||
/// This also tests if the given const `ct` contains an inference variable which was previously
|
|
||||||
/// unioned with `target_vid`. If this is the case, inferring `target_vid` to `ct`
|
|
||||||
/// would result in an infinite type as we continuously replace an inference variable
|
|
||||||
/// in `ct` with `ct` itself.
|
|
||||||
///
|
|
||||||
/// This is especially important as unevaluated consts use their parents generics.
|
|
||||||
/// They therefore often contain unused args, making these errors far more likely.
|
|
||||||
///
|
|
||||||
/// A good example of this is the following:
|
|
||||||
///
|
|
||||||
/// ```compile_fail,E0308
|
|
||||||
/// #![feature(generic_const_exprs)]
|
|
||||||
///
|
|
||||||
/// fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] {
|
|
||||||
/// todo!()
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn main() {
|
|
||||||
/// let mut arr = Default::default();
|
|
||||||
/// arr = bind(arr);
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Here `3 + 4` ends up as `ConstKind::Unevaluated` which uses the generics
|
|
||||||
/// of `fn bind` (meaning that its args contain `N`).
|
|
||||||
///
|
|
||||||
/// `bind(arr)` now infers that the type of `arr` must be `[u8; N]`.
|
|
||||||
/// The assignment `arr = bind(arr)` now tries to equate `N` with `3 + 4`.
|
|
||||||
///
|
|
||||||
/// As `3 + 4` contains `N` in its args, this must not succeed.
|
|
||||||
///
|
|
||||||
/// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant.
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
|
||||||
fn unify_const_variable(
|
|
||||||
&self,
|
|
||||||
target_vid: ty::ConstVid,
|
|
||||||
ct: ty::Const<'tcx>,
|
|
||||||
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
|
||||||
let span = match self.inner.borrow_mut().const_unification_table().probe_value(target_vid) {
|
|
||||||
ConstVariableValue::Known { value } => {
|
|
||||||
bug!("instantiating a known const var: {target_vid:?} {value} {ct}")
|
|
||||||
}
|
|
||||||
ConstVariableValue::Unknown { origin, universe: _ } => origin.span,
|
|
||||||
};
|
|
||||||
// FIXME(generic_const_exprs): Occurs check failures for unevaluated
|
|
||||||
// constants and generic expressions are not yet handled correctly.
|
|
||||||
let Generalization { value_may_be_infer: value, has_unconstrained_ty_var } =
|
|
||||||
generalize::generalize(
|
|
||||||
self,
|
|
||||||
&mut CombineDelegate { infcx: self, span },
|
|
||||||
ct,
|
|
||||||
target_vid,
|
|
||||||
ty::Variance::Invariant,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
if has_unconstrained_ty_var {
|
|
||||||
span_bug!(span, "unconstrained ty var when generalizing `{ct:?}`");
|
|
||||||
}
|
|
||||||
self.inner
|
|
||||||
.borrow_mut()
|
|
||||||
.const_unification_table()
|
|
||||||
.union_value(target_vid, ConstVariableValue::Known { value });
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unify_integral_variable(
|
fn unify_integral_variable(
|
||||||
&self,
|
&self,
|
||||||
vid_is_expected: bool,
|
vid_is_expected: bool,
|
||||||
|
@ -387,132 +319,6 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
|
||||||
Glb::new(self, a_is_expected)
|
Glb::new(self, a_is_expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Here, `dir` is either `EqTo`, `SubtypeOf`, or `SupertypeOf`.
|
|
||||||
/// The idea is that we should ensure that the type `a_ty` is equal
|
|
||||||
/// to, a subtype of, or a supertype of (respectively) the type
|
|
||||||
/// to which `b_vid` is bound.
|
|
||||||
///
|
|
||||||
/// Since `b_vid` has not yet been instantiated with a type, we
|
|
||||||
/// will first instantiate `b_vid` with a *generalized* version
|
|
||||||
/// of `a_ty`. Generalization introduces other inference
|
|
||||||
/// variables wherever subtyping could occur.
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
|
||||||
pub fn instantiate(
|
|
||||||
&mut self,
|
|
||||||
a_ty: Ty<'tcx>,
|
|
||||||
ambient_variance: ty::Variance,
|
|
||||||
b_vid: ty::TyVid,
|
|
||||||
a_is_expected: bool,
|
|
||||||
) -> RelateResult<'tcx, ()> {
|
|
||||||
// Get the actual variable that b_vid has been inferred to
|
|
||||||
debug_assert!(self.infcx.inner.borrow_mut().type_variables().probe(b_vid).is_unknown());
|
|
||||||
|
|
||||||
// Generalize type of `a_ty` appropriately depending on the
|
|
||||||
// direction. As an example, assume:
|
|
||||||
//
|
|
||||||
// - `a_ty == &'x ?1`, where `'x` is some free region and `?1` is an
|
|
||||||
// inference variable,
|
|
||||||
// - and `dir` == `SubtypeOf`.
|
|
||||||
//
|
|
||||||
// Then the generalized form `b_ty` would be `&'?2 ?3`, where
|
|
||||||
// `'?2` and `?3` are fresh region/type inference
|
|
||||||
// variables. (Down below, we will relate `a_ty <: b_ty`,
|
|
||||||
// adding constraints like `'x: '?2` and `?1 <: ?3`.)
|
|
||||||
let Generalization { value_may_be_infer: b_ty, has_unconstrained_ty_var } =
|
|
||||||
generalize::generalize(
|
|
||||||
self.infcx,
|
|
||||||
&mut CombineDelegate { infcx: self.infcx, span: self.trace.span() },
|
|
||||||
a_ty,
|
|
||||||
b_vid,
|
|
||||||
ambient_variance,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Constrain `b_vid` to the generalized type `b_ty`.
|
|
||||||
if let &ty::Infer(TyVar(b_ty_vid)) = b_ty.kind() {
|
|
||||||
self.infcx.inner.borrow_mut().type_variables().equate(b_vid, b_ty_vid);
|
|
||||||
} else {
|
|
||||||
self.infcx.inner.borrow_mut().type_variables().instantiate(b_vid, b_ty);
|
|
||||||
}
|
|
||||||
|
|
||||||
if has_unconstrained_ty_var {
|
|
||||||
self.obligations.push(Obligation::new(
|
|
||||||
self.tcx(),
|
|
||||||
self.trace.cause.clone(),
|
|
||||||
self.param_env,
|
|
||||||
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
|
|
||||||
b_ty.into(),
|
|
||||||
))),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, relate `b_ty` to `a_ty`, as described in previous comment.
|
|
||||||
//
|
|
||||||
// FIXME(#16847): This code is non-ideal because all these subtype
|
|
||||||
// relations wind up attributed to the same spans. We need
|
|
||||||
// to associate causes/spans with each of the relations in
|
|
||||||
// the stack to get this right.
|
|
||||||
if b_ty.is_ty_var() {
|
|
||||||
// This happens for cases like `<?0 as Trait>::Assoc == ?0`.
|
|
||||||
// We can't instantiate `?0` here as that would result in a
|
|
||||||
// cyclic type. We instead delay the unification in case
|
|
||||||
// the alias can be normalized to something which does not
|
|
||||||
// mention `?0`.
|
|
||||||
if self.infcx.next_trait_solver() {
|
|
||||||
let (lhs, rhs, direction) = match ambient_variance {
|
|
||||||
ty::Variance::Invariant => {
|
|
||||||
(a_ty.into(), b_ty.into(), AliasRelationDirection::Equate)
|
|
||||||
}
|
|
||||||
ty::Variance::Covariant => {
|
|
||||||
(a_ty.into(), b_ty.into(), AliasRelationDirection::Subtype)
|
|
||||||
}
|
|
||||||
ty::Variance::Contravariant => {
|
|
||||||
(b_ty.into(), a_ty.into(), AliasRelationDirection::Subtype)
|
|
||||||
}
|
|
||||||
ty::Variance::Bivariant => unreachable!("bivariant generalization"),
|
|
||||||
};
|
|
||||||
self.obligations.push(Obligation::new(
|
|
||||||
self.tcx(),
|
|
||||||
self.trace.cause.clone(),
|
|
||||||
self.param_env,
|
|
||||||
ty::PredicateKind::AliasRelate(lhs, rhs, direction),
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
match a_ty.kind() {
|
|
||||||
&ty::Alias(ty::Projection, data) => {
|
|
||||||
// FIXME: This does not handle subtyping correctly, we could
|
|
||||||
// instead create a new inference variable for `a_ty`, emitting
|
|
||||||
// `Projection(a_ty, a_infer)` and `a_infer <: b_ty`.
|
|
||||||
self.obligations.push(Obligation::new(
|
|
||||||
self.tcx(),
|
|
||||||
self.trace.cause.clone(),
|
|
||||||
self.param_env,
|
|
||||||
ty::ProjectionPredicate { projection_ty: data, term: b_ty.into() },
|
|
||||||
))
|
|
||||||
}
|
|
||||||
// The old solver only accepts projection predicates for associated types.
|
|
||||||
ty::Alias(ty::Inherent | ty::Weak | ty::Opaque, _) => {
|
|
||||||
return Err(TypeError::CyclicTy(a_ty));
|
|
||||||
}
|
|
||||||
_ => bug!("generalizated `{a_ty:?} to infer, not an alias"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
match ambient_variance {
|
|
||||||
ty::Variance::Invariant => self.equate(a_is_expected).relate(a_ty, b_ty),
|
|
||||||
ty::Variance::Covariant => self.sub(a_is_expected).relate(a_ty, b_ty),
|
|
||||||
ty::Variance::Contravariant => self.sub(a_is_expected).relate_with_variance(
|
|
||||||
ty::Contravariant,
|
|
||||||
ty::VarianceDiagInfo::default(),
|
|
||||||
a_ty,
|
|
||||||
b_ty,
|
|
||||||
),
|
|
||||||
ty::Variance::Bivariant => unreachable!("bivariant generalization"),
|
|
||||||
}?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
||||||
self.obligations.extend(obligations);
|
self.obligations.extend(obligations);
|
||||||
}
|
}
|
||||||
|
@ -525,6 +331,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
|
pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
|
||||||
|
fn span(&self) -> Span;
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx>;
|
fn param_env(&self) -> ty::ParamEnv<'tcx>;
|
||||||
|
|
||||||
/// Register obligations that must hold in order for this relation to hold
|
/// Register obligations that must hold in order for this relation to hold
|
||||||
|
|
|
@ -8,6 +8,7 @@ use rustc_middle::ty::TyVar;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
||||||
|
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
use rustc_span::Span;
|
||||||
|
|
||||||
/// Ensures `a` is made equal to `b`. Returns `a` on success.
|
/// Ensures `a` is made equal to `b`. Returns `a` on success.
|
||||||
pub struct Equate<'combine, 'infcx, 'tcx> {
|
pub struct Equate<'combine, 'infcx, 'tcx> {
|
||||||
|
@ -81,12 +82,12 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
|
||||||
infcx.inner.borrow_mut().type_variables().equate(a_id, b_id);
|
infcx.inner.borrow_mut().type_variables().equate(a_id, b_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::Infer(TyVar(a_id)), _) => {
|
(&ty::Infer(TyVar(a_vid)), _) => {
|
||||||
self.fields.instantiate(b, ty::Invariant, a_id, self.a_is_expected)?;
|
infcx.instantiate_ty_var(self, self.a_is_expected, a_vid, ty::Invariant, b)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
(_, &ty::Infer(TyVar(b_id))) => {
|
(_, &ty::Infer(TyVar(b_vid))) => {
|
||||||
self.fields.instantiate(a, ty::Invariant, b_id, self.a_is_expected)?;
|
infcx.instantiate_ty_var(self, !self.a_is_expected, b_vid, ty::Invariant, a)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -170,6 +171,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ObligationEmittingRelation<'tcx> for Equate<'_, '_, 'tcx> {
|
impl<'tcx> ObligationEmittingRelation<'tcx> for Equate<'_, '_, 'tcx> {
|
||||||
|
fn span(&self) -> Span {
|
||||||
|
self.fields.trace.span()
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.fields.param_env
|
self.fields.param_env
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
use crate::infer::nll_relate::TypeRelatingDelegate;
|
||||||
|
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind, TypeVariableValue};
|
||||||
|
use crate::infer::{InferCtxt, ObligationEmittingRelation, RegionVariableOrigin};
|
||||||
use rustc_data_structures::sso::SsoHashMap;
|
use rustc_data_structures::sso::SsoHashMap;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
@ -7,17 +10,204 @@ use rustc_middle::infer::unify_key::ConstVariableValue;
|
||||||
use rustc_middle::ty::error::TypeError;
|
use rustc_middle::ty::error::TypeError;
|
||||||
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||||
use rustc_middle::ty::visit::MaxUniverse;
|
use rustc_middle::ty::visit::MaxUniverse;
|
||||||
use rustc_middle::ty::{self, InferConst, Term, Ty, TyCtxt, TypeVisitable, TypeVisitableExt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
|
use rustc_middle::ty::{AliasRelationDirection, InferConst, Term, TypeVisitable, TypeVisitableExt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use crate::infer::nll_relate::TypeRelatingDelegate;
|
impl<'tcx> InferCtxt<'tcx> {
|
||||||
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind, TypeVariableValue};
|
/// The idea is that we should ensure that the type variable `target_vid`
|
||||||
use crate::infer::{InferCtxt, RegionVariableOrigin};
|
/// is equal to, a subtype of, or a supertype of `source_ty`.
|
||||||
|
///
|
||||||
|
/// For this, we will instantiate `target_vid` with a *generalized* version
|
||||||
|
/// of `source_ty`. Generalization introduces other inference variables wherever
|
||||||
|
/// subtyping could occur. This also does the occurs checks, detecting whether
|
||||||
|
/// instantiating `target_vid` would result in a cyclic type. We eagerly error
|
||||||
|
/// in this case.
|
||||||
|
#[instrument(skip(self, relation, target_is_expected), level = "debug")]
|
||||||
|
pub(super) fn instantiate_ty_var<R: ObligationEmittingRelation<'tcx>>(
|
||||||
|
&self,
|
||||||
|
relation: &mut R,
|
||||||
|
target_is_expected: bool,
|
||||||
|
target_vid: ty::TyVid,
|
||||||
|
ambient_variance: ty::Variance,
|
||||||
|
source_ty: Ty<'tcx>,
|
||||||
|
) -> RelateResult<'tcx, ()> {
|
||||||
|
debug_assert!(self.inner.borrow_mut().type_variables().probe(target_vid).is_unknown());
|
||||||
|
|
||||||
|
// Generalize `source_ty` depending on the current variance. As an example, assume
|
||||||
|
// `?target <: &'x ?1`, where `'x` is some free region and `?1` is an inference
|
||||||
|
// variable.
|
||||||
|
//
|
||||||
|
// Then the `generalized_ty` would be `&'?2 ?3`, where `'?2` and `?3` are fresh
|
||||||
|
// region/type inference variables.
|
||||||
|
//
|
||||||
|
// We then relate `generalized_ty <: source_ty`,adding constraints like `'x: '?2` and `?1 <: ?3`.
|
||||||
|
let Generalization { value_may_be_infer: generalized_ty, has_unconstrained_ty_var } =
|
||||||
|
generalize(
|
||||||
|
self,
|
||||||
|
&mut CombineDelegate { infcx: self, span: relation.span() },
|
||||||
|
source_ty,
|
||||||
|
target_vid,
|
||||||
|
ambient_variance,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Constrain `b_vid` to the generalized type `generalized_ty`.
|
||||||
|
if let &ty::Infer(ty::TyVar(generalized_vid)) = generalized_ty.kind() {
|
||||||
|
self.inner.borrow_mut().type_variables().equate(target_vid, generalized_vid);
|
||||||
|
} else {
|
||||||
|
self.inner.borrow_mut().type_variables().instantiate(target_vid, generalized_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// See the comment on `Generalization::has_unconstrained_ty_var`.
|
||||||
|
if has_unconstrained_ty_var {
|
||||||
|
relation.register_predicates([ty::ClauseKind::WellFormed(generalized_ty.into())]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, relate `generalized_ty` to `source_ty`, as described in previous comment.
|
||||||
|
//
|
||||||
|
// FIXME(#16847): This code is non-ideal because all these subtype
|
||||||
|
// relations wind up attributed to the same spans. We need
|
||||||
|
// to associate causes/spans with each of the relations in
|
||||||
|
// the stack to get this right.
|
||||||
|
if generalized_ty.is_ty_var() {
|
||||||
|
// This happens for cases like `<?0 as Trait>::Assoc == ?0`.
|
||||||
|
// We can't instantiate `?0` here as that would result in a
|
||||||
|
// cyclic type. We instead delay the unification in case
|
||||||
|
// the alias can be normalized to something which does not
|
||||||
|
// mention `?0`.
|
||||||
|
if self.next_trait_solver() {
|
||||||
|
let (lhs, rhs, direction) = match ambient_variance {
|
||||||
|
ty::Variance::Invariant => {
|
||||||
|
(generalized_ty.into(), source_ty.into(), AliasRelationDirection::Equate)
|
||||||
|
}
|
||||||
|
ty::Variance::Covariant => {
|
||||||
|
(generalized_ty.into(), source_ty.into(), AliasRelationDirection::Subtype)
|
||||||
|
}
|
||||||
|
ty::Variance::Contravariant => {
|
||||||
|
(source_ty.into(), generalized_ty.into(), AliasRelationDirection::Subtype)
|
||||||
|
}
|
||||||
|
ty::Variance::Bivariant => unreachable!("bivariant generalization"),
|
||||||
|
};
|
||||||
|
|
||||||
|
relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]);
|
||||||
|
} else {
|
||||||
|
match source_ty.kind() {
|
||||||
|
&ty::Alias(ty::Projection, data) => {
|
||||||
|
// FIXME: This does not handle subtyping correctly, we could
|
||||||
|
// instead create a new inference variable `?normalized_source`, emitting
|
||||||
|
// `Projection(normalized_source, ?ty_normalized)` and `?normalized_source <: generalized_ty`.
|
||||||
|
relation.register_predicates([ty::ProjectionPredicate {
|
||||||
|
projection_ty: data,
|
||||||
|
term: generalized_ty.into(),
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
// The old solver only accepts projection predicates for associated types.
|
||||||
|
ty::Alias(ty::Inherent | ty::Weak | ty::Opaque, _) => {
|
||||||
|
return Err(TypeError::CyclicTy(source_ty));
|
||||||
|
}
|
||||||
|
_ => bug!("generalized `{source_ty:?} to infer, not an alias"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// HACK: make sure that we `a_is_expected` continues to be
|
||||||
|
// correct when relating the generalized type with the source.
|
||||||
|
if target_is_expected == relation.a_is_expected() {
|
||||||
|
relation.relate_with_variance(
|
||||||
|
ambient_variance,
|
||||||
|
ty::VarianceDiagInfo::default(),
|
||||||
|
generalized_ty,
|
||||||
|
source_ty,
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
relation.relate_with_variance(
|
||||||
|
ambient_variance.xform(ty::Contravariant),
|
||||||
|
ty::VarianceDiagInfo::default(),
|
||||||
|
source_ty,
|
||||||
|
generalized_ty,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Instantiates the const variable `target_vid` with the given constant.
|
||||||
|
///
|
||||||
|
/// This also tests if the given const `ct` contains an inference variable which was previously
|
||||||
|
/// unioned with `target_vid`. If this is the case, inferring `target_vid` to `ct`
|
||||||
|
/// would result in an infinite type as we continuously replace an inference variable
|
||||||
|
/// in `ct` with `ct` itself.
|
||||||
|
///
|
||||||
|
/// This is especially important as unevaluated consts use their parents generics.
|
||||||
|
/// They therefore often contain unused args, making these errors far more likely.
|
||||||
|
///
|
||||||
|
/// A good example of this is the following:
|
||||||
|
///
|
||||||
|
/// ```compile_fail,E0308
|
||||||
|
/// #![feature(generic_const_exprs)]
|
||||||
|
///
|
||||||
|
/// fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] {
|
||||||
|
/// todo!()
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let mut arr = Default::default();
|
||||||
|
/// arr = bind(arr);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Here `3 + 4` ends up as `ConstKind::Unevaluated` which uses the generics
|
||||||
|
/// of `fn bind` (meaning that its args contain `N`).
|
||||||
|
///
|
||||||
|
/// `bind(arr)` now infers that the type of `arr` must be `[u8; N]`.
|
||||||
|
/// The assignment `arr = bind(arr)` now tries to equate `N` with `3 + 4`.
|
||||||
|
///
|
||||||
|
/// As `3 + 4` contains `N` in its args, this must not succeed.
|
||||||
|
///
|
||||||
|
/// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant.
|
||||||
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
pub(super) fn instantiate_const_var(
|
||||||
|
&self,
|
||||||
|
target_vid: ty::ConstVid,
|
||||||
|
source_ct: ty::Const<'tcx>,
|
||||||
|
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
||||||
|
let span = match self.inner.borrow_mut().const_unification_table().probe_value(target_vid) {
|
||||||
|
ConstVariableValue::Known { value } => {
|
||||||
|
bug!("instantiating a known const var: {target_vid:?} {value} {source_ct}")
|
||||||
|
}
|
||||||
|
ConstVariableValue::Unknown { origin, universe: _ } => origin.span,
|
||||||
|
};
|
||||||
|
// FIXME(generic_const_exprs): Occurs check failures for unevaluated
|
||||||
|
// constants and generic expressions are not yet handled correctly.
|
||||||
|
let Generalization { value_may_be_infer: generalized_ct, has_unconstrained_ty_var } =
|
||||||
|
generalize(
|
||||||
|
self,
|
||||||
|
&mut CombineDelegate { infcx: self, span },
|
||||||
|
source_ct,
|
||||||
|
target_vid,
|
||||||
|
ty::Variance::Invariant,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
debug_assert!(!generalized_ct.is_ct_infer());
|
||||||
|
if has_unconstrained_ty_var {
|
||||||
|
span_bug!(span, "unconstrained ty var when generalizing `{source_ct:?}`");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.inner
|
||||||
|
.borrow_mut()
|
||||||
|
.const_unification_table()
|
||||||
|
.union_value(target_vid, ConstVariableValue::Known { value: generalized_ct });
|
||||||
|
|
||||||
|
// FIXME(generic_const_exprs): We have to make sure we actually equate
|
||||||
|
// `generalized_ct` and `source_ct` here.`
|
||||||
|
Ok(generalized_ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempts to generalize `term` for the type variable `for_vid`.
|
/// Attempts to generalize `term` for the type variable `for_vid`.
|
||||||
/// This checks for cycles -- that is, whether the type `term`
|
/// This checks for cycles -- that is, whether the type `term`
|
||||||
/// references `for_vid`.
|
/// references `for_vid`.
|
||||||
pub fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>(
|
pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>(
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
delegate: &mut D,
|
delegate: &mut D,
|
||||||
term: T,
|
term: T,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
|
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
||||||
|
use rustc_span::Span;
|
||||||
|
|
||||||
use super::combine::{CombineFields, ObligationEmittingRelation};
|
use super::combine::{CombineFields, ObligationEmittingRelation};
|
||||||
use super::lattice::{self, LatticeDir};
|
use super::lattice::{self, LatticeDir};
|
||||||
|
@ -134,6 +135,10 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
|
impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
|
||||||
|
fn span(&self) -> Span {
|
||||||
|
self.fields.trace.span()
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.fields.param_env
|
self.fields.param_env
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::traits::{ObligationCause, PredicateObligations};
|
||||||
|
|
||||||
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
|
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
||||||
|
use rustc_span::Span;
|
||||||
|
|
||||||
/// "Least upper bound" (common supertype)
|
/// "Least upper bound" (common supertype)
|
||||||
pub struct Lub<'combine, 'infcx, 'tcx> {
|
pub struct Lub<'combine, 'infcx, 'tcx> {
|
||||||
|
@ -134,6 +135,10 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
|
impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
|
||||||
|
fn span(&self) -> Span {
|
||||||
|
self.fields.trace.span()
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.fields.param_env
|
self.fields.param_env
|
||||||
}
|
}
|
||||||
|
|
|
@ -670,6 +670,10 @@ impl<'tcx, D> ObligationEmittingRelation<'tcx> for TypeRelating<'_, 'tcx, D>
|
||||||
where
|
where
|
||||||
D: TypeRelatingDelegate<'tcx>,
|
D: TypeRelatingDelegate<'tcx>,
|
||||||
{
|
{
|
||||||
|
fn span(&self) -> Span {
|
||||||
|
self.delegate.span()
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.delegate.param_env()
|
self.delegate.param_env()
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
|
||||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::TyVar;
|
use rustc_middle::ty::TyVar;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
|
use rustc_span::Span;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
/// Ensures `a` is made a subtype of `b`. Returns `a` on success.
|
/// Ensures `a` is made a subtype of `b`. Returns `a` on success.
|
||||||
|
@ -103,12 +104,12 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
||||||
|
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}
|
}
|
||||||
(&ty::Infer(TyVar(a_id)), _) => {
|
(&ty::Infer(TyVar(a_vid)), _) => {
|
||||||
self.fields.instantiate(b, ty::Contravariant, a_id, !self.a_is_expected)?;
|
infcx.instantiate_ty_var(self, self.a_is_expected, a_vid, ty::Covariant, b)?;
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}
|
}
|
||||||
(_, &ty::Infer(TyVar(b_id))) => {
|
(_, &ty::Infer(TyVar(b_vid))) => {
|
||||||
self.fields.instantiate(a, ty::Covariant, b_id, self.a_is_expected)?;
|
infcx.instantiate_ty_var(self, !self.a_is_expected, b_vid, ty::Contravariant, a)?;
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,6 +200,10 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ObligationEmittingRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
impl<'tcx> ObligationEmittingRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
||||||
|
fn span(&self) -> Span {
|
||||||
|
self.fields.trace.span()
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.fields.param_env
|
self.fields.param_env
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
|
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
|
||||||
--> $DIR/associated-type.rs:31:1
|
--> $DIR/associated-type.rs:31:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
|
||||||
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)`
|
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)`
|
||||||
--> $DIR/associated-type.rs:31:1
|
--> $DIR/associated-type.rs:31:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0284]: type annotations needed: cannot satisfy `<<T as Id<_>>::Id as Unnormalizable>::Assoc == _`
|
error[E0284]: type annotations needed: cannot satisfy `_ == <<T as Id<_>>::Id as Unnormalizable>::Assoc`
|
||||||
--> $DIR/occurs-check-nested-alias.rs:36:9
|
--> $DIR/occurs-check-nested-alias.rs:36:9
|
||||||
|
|
|
|
||||||
LL | x = y;
|
LL | x = y;
|
||||||
| ^ cannot satisfy `<<T as Id<_>>::Id as Unnormalizable>::Assoc == _`
|
| ^ cannot satisfy `_ == <<T as Id<_>>::Id as Unnormalizable>::Assoc`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue