Auto merge of #126514 - matthiaskrgr:rollup-pnwi8ns, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #126354 (Use `Variance` glob imported variants everywhere) - #126367 (Point out failing never obligation for `DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK`) - #126469 (MIR Shl/Shr: the offset can be computed with rem_euclid) - #126471 (Use a consistent way to filter out bounds instead of splitting it into three places) - #126472 (build `libcxx-version` only when it doesn't exist) - #126497 (delegation: Fix hygiene for `self`) - #126501 (make bors ignore comments in PR template) - #126509 (std: suggest OnceLock over Once) - #126512 (Miri subtree update) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
687a68d679
67 changed files with 1811 additions and 328 deletions
|
@ -328,7 +328,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
|||
if let Some(annotation_index) = constant.user_ty {
|
||||
if let Err(terr) = self.cx.relate_type_and_user_type(
|
||||
constant.const_.ty(),
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
||||
locations,
|
||||
ConstraintCategory::Boring,
|
||||
|
@ -451,7 +451,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
|||
|
||||
if let Err(terr) = self.cx.relate_type_and_user_type(
|
||||
ty,
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
user_ty,
|
||||
Locations::All(*span),
|
||||
ConstraintCategory::TypeAnnotation,
|
||||
|
@ -1095,7 +1095,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
) -> Result<(), NoSolution> {
|
||||
// Use this order of parameters because the sup type is usually the
|
||||
// "expected" type in diagnostics.
|
||||
self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category)
|
||||
self.relate_types(sup, ty::Contravariant, sub, locations, category)
|
||||
}
|
||||
|
||||
#[instrument(skip(self, category), level = "debug")]
|
||||
|
@ -1106,7 +1106,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
locations: Locations,
|
||||
category: ConstraintCategory<'tcx>,
|
||||
) -> Result<(), NoSolution> {
|
||||
self.relate_types(expected, ty::Variance::Invariant, found, locations, category)
|
||||
self.relate_types(expected, ty::Invariant, found, locations, category)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
|
@ -1146,7 +1146,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
trace!(?curr_projected_ty);
|
||||
|
||||
let ty = curr_projected_ty.ty;
|
||||
self.relate_types(ty, v.xform(ty::Variance::Contravariant), a, locations, category)?;
|
||||
self.relate_types(ty, v.xform(ty::Contravariant), a, locations, category)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1248,7 +1248,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
if let Some(annotation_index) = self.rvalue_user_ty(rv) {
|
||||
if let Err(terr) = self.relate_type_and_user_type(
|
||||
rv_ty,
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Boring,
|
||||
|
|
|
@ -50,14 +50,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
locations: Locations,
|
||||
category: ConstraintCategory<'tcx>,
|
||||
) -> Result<(), NoSolution> {
|
||||
NllTypeRelating::new(
|
||||
self,
|
||||
locations,
|
||||
category,
|
||||
UniverseInfo::other(),
|
||||
ty::Variance::Invariant,
|
||||
)
|
||||
.relate(a, b)?;
|
||||
NllTypeRelating::new(self, locations, category, UniverseInfo::other(), ty::Invariant)
|
||||
.relate(a, b)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -106,15 +100,15 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
|
|||
|
||||
fn ambient_covariance(&self) -> bool {
|
||||
match self.ambient_variance {
|
||||
ty::Variance::Covariant | ty::Variance::Invariant => true,
|
||||
ty::Variance::Contravariant | ty::Variance::Bivariant => false,
|
||||
ty::Covariant | ty::Invariant => true,
|
||||
ty::Contravariant | ty::Bivariant => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn ambient_contravariance(&self) -> bool {
|
||||
match self.ambient_variance {
|
||||
ty::Variance::Contravariant | ty::Variance::Invariant => true,
|
||||
ty::Variance::Covariant | ty::Variance::Bivariant => false,
|
||||
ty::Contravariant | ty::Invariant => true,
|
||||
ty::Covariant | ty::Bivariant => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,11 +330,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
|||
|
||||
debug!(?self.ambient_variance);
|
||||
// In a bivariant context this always succeeds.
|
||||
let r = if self.ambient_variance == ty::Variance::Bivariant {
|
||||
Ok(a)
|
||||
} else {
|
||||
self.relate(a, b)
|
||||
};
|
||||
let r = if self.ambient_variance == ty::Bivariant { Ok(a) } else { self.relate(a, b) };
|
||||
|
||||
self.ambient_variance = old_ambient_variance;
|
||||
|
||||
|
@ -474,7 +464,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
|||
}
|
||||
|
||||
match self.ambient_variance {
|
||||
ty::Variance::Covariant => {
|
||||
ty::Covariant => {
|
||||
// Covariance, so we want `for<..> A <: for<..> B` --
|
||||
// therefore we compare any instantiation of A (i.e., A
|
||||
// instantiated with existentials) against every
|
||||
|
@ -489,7 +479,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
|||
})?;
|
||||
}
|
||||
|
||||
ty::Variance::Contravariant => {
|
||||
ty::Contravariant => {
|
||||
// Contravariance, so we want `for<..> A :> for<..> B` --
|
||||
// therefore we compare every instantiation of A (i.e., A
|
||||
// instantiated with universals) against any
|
||||
|
@ -504,7 +494,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
|||
})?;
|
||||
}
|
||||
|
||||
ty::Variance::Invariant => {
|
||||
ty::Invariant => {
|
||||
// Invariant, so we want `for<..> A == for<..> B` --
|
||||
// therefore we want `exists<..> A == for<..> B` and
|
||||
// `exists<..> B == for<..> A`.
|
||||
|
@ -525,7 +515,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
|||
})?;
|
||||
}
|
||||
|
||||
ty::Variance::Bivariant => {}
|
||||
ty::Bivariant => {}
|
||||
}
|
||||
|
||||
Ok(a)
|
||||
|
@ -584,23 +574,23 @@ impl<'bccx, 'tcx> PredicateEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx,
|
|||
|
||||
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
|
||||
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
|
||||
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
|
||||
ty::Covariant => ty::PredicateKind::AliasRelate(
|
||||
a.into(),
|
||||
b.into(),
|
||||
ty::AliasRelationDirection::Subtype,
|
||||
),
|
||||
// a :> b is b <: a
|
||||
ty::Variance::Contravariant => ty::PredicateKind::AliasRelate(
|
||||
ty::Contravariant => ty::PredicateKind::AliasRelate(
|
||||
b.into(),
|
||||
a.into(),
|
||||
ty::AliasRelationDirection::Subtype,
|
||||
),
|
||||
ty::Variance::Invariant => ty::PredicateKind::AliasRelate(
|
||||
ty::Invariant => ty::PredicateKind::AliasRelate(
|
||||
a.into(),
|
||||
b.into(),
|
||||
ty::AliasRelationDirection::Equate,
|
||||
),
|
||||
ty::Variance::Bivariant => {
|
||||
ty::Bivariant => {
|
||||
unreachable!("cannot defer an alias-relate goal with Bivariant variance (yet?)")
|
||||
}
|
||||
})]);
|
||||
|
|
|
@ -112,25 +112,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
|
||||
// Shift ops can have an RHS with a different numeric type.
|
||||
if matches!(bin_op, Shl | ShlUnchecked | Shr | ShrUnchecked) {
|
||||
let size = left.layout.size.bits();
|
||||
let l_bits = left.layout.size.bits();
|
||||
// Compute the equivalent shift modulo `size` that is in the range `0..size`. (This is
|
||||
// the one MIR operator that does *not* directly map to a single LLVM operation.)
|
||||
let (shift_amount, overflow) = if right.layout.abi.is_signed() {
|
||||
let shift_amount = r_signed();
|
||||
let overflow = shift_amount < 0 || shift_amount >= i128::from(size);
|
||||
// Deliberately wrapping `as` casts: shift_amount *can* be negative, but the result
|
||||
// of the `as` will be equal modulo `size` (since it is a power of two).
|
||||
let masked_amount = (shift_amount as u128) % u128::from(size);
|
||||
assert_eq!(overflow, shift_amount != i128::try_from(masked_amount).unwrap());
|
||||
(masked_amount, overflow)
|
||||
let rem = shift_amount.rem_euclid(l_bits.into());
|
||||
// `rem` is guaranteed positive, so the `unwrap` cannot fail
|
||||
(u128::try_from(rem).unwrap(), rem != shift_amount)
|
||||
} else {
|
||||
let shift_amount = r_unsigned();
|
||||
let overflow = shift_amount >= u128::from(size);
|
||||
let masked_amount = shift_amount % u128::from(size);
|
||||
assert_eq!(overflow, shift_amount != masked_amount);
|
||||
(masked_amount, overflow)
|
||||
let rem = shift_amount.rem_euclid(l_bits.into());
|
||||
(rem, rem != shift_amount)
|
||||
};
|
||||
let shift_amount = u32::try_from(shift_amount).unwrap(); // we masked so this will always fit
|
||||
let shift_amount = u32::try_from(shift_amount).unwrap(); // we brought this in the range `0..size` so this will always fit
|
||||
// Compute the shifted result.
|
||||
let result = if left.layout.abi.is_signed() {
|
||||
let l = l_signed();
|
||||
|
|
|
@ -45,6 +45,7 @@ hir_typeck_convert_using_method = try using `{$sugg}` to convert `{$found}` to `
|
|||
hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private
|
||||
|
||||
hir_typeck_dependency_on_unit_never_type_fallback = this function depends on never type fallback being `()`
|
||||
.note = in edition 2024, the requirement `{$obligation}` will fail
|
||||
.help = specify the types explicitly
|
||||
|
||||
hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty`
|
||||
|
|
|
@ -7,7 +7,7 @@ use rustc_errors::{
|
|||
SubdiagMessageOp, Subdiagnostic,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::{
|
||||
edition::{Edition, LATEST_STABLE_EDITION},
|
||||
symbol::Ident,
|
||||
|
@ -186,7 +186,11 @@ pub enum NeverTypeFallbackFlowingIntoUnsafe {
|
|||
#[derive(LintDiagnostic)]
|
||||
#[help]
|
||||
#[diag(hir_typeck_dependency_on_unit_never_type_fallback)]
|
||||
pub struct DependencyOnUnitNeverTypeFallback {}
|
||||
pub struct DependencyOnUnitNeverTypeFallback<'tcx> {
|
||||
#[note]
|
||||
pub obligation_span: Span,
|
||||
pub obligation: ty::Predicate<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
|
|
|
@ -488,7 +488,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
let remaining_errors_if_fallback_to = |fallback| {
|
||||
self.probe(|_| {
|
||||
let obligations = self.fulfillment_cx.borrow().pending_obligations();
|
||||
let ocx = ObligationCtxt::new(&self.infcx);
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&self.infcx);
|
||||
ocx.register_obligations(obligations.iter().cloned());
|
||||
|
||||
for &diverging_vid in diverging_vids {
|
||||
|
@ -506,14 +506,18 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
// then this code will be broken by the never type fallback change.qba
|
||||
let unit_errors = remaining_errors_if_fallback_to(self.tcx.types.unit);
|
||||
if unit_errors.is_empty()
|
||||
&& let never_errors = remaining_errors_if_fallback_to(self.tcx.types.never)
|
||||
&& !never_errors.is_empty()
|
||||
&& let mut never_errors = remaining_errors_if_fallback_to(self.tcx.types.never)
|
||||
&& let [ref mut never_error, ..] = never_errors.as_mut_slice()
|
||||
{
|
||||
self.adjust_fulfillment_error_for_expr_obligation(never_error);
|
||||
self.tcx.emit_node_span_lint(
|
||||
lint::builtin::DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK,
|
||||
self.tcx.local_def_id_to_hir_id(self.body_id),
|
||||
self.tcx.def_span(self.body_id),
|
||||
errors::DependencyOnUnitNeverTypeFallback {},
|
||||
errors::DependencyOnUnitNeverTypeFallback {
|
||||
obligation_span: never_error.obligation.cause.span,
|
||||
obligation: never_error.obligation.predicate,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,16 +212,16 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
|||
T: ToTrace<'tcx>,
|
||||
{
|
||||
match variance {
|
||||
ty::Variance::Covariant => self.sub(define_opaque_types, expected, actual),
|
||||
ty::Variance::Invariant => self.eq(define_opaque_types, expected, actual),
|
||||
ty::Variance::Contravariant => self.sup(define_opaque_types, expected, actual),
|
||||
ty::Covariant => self.sub(define_opaque_types, expected, actual),
|
||||
ty::Invariant => self.eq(define_opaque_types, expected, actual),
|
||||
ty::Contravariant => self.sup(define_opaque_types, expected, actual),
|
||||
|
||||
// We could make this make sense but it's not readily
|
||||
// exposed and I don't feel like dealing with it. Note
|
||||
// that bivariance in general does a bit more than just
|
||||
// *nothing*, it checks that the types are the same
|
||||
// "modulo variance" basically.
|
||||
ty::Variance::Bivariant => panic!("Bivariant given to `relate()`"),
|
||||
ty::Bivariant => panic!("Bivariant given to `relate()`"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
.args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(i, _)| variances[*i] == ty::Variance::Invariant)
|
||||
.filter(|(i, _)| variances[*i] == ty::Invariant)
|
||||
.filter_map(|(_, arg)| match arg.unpack() {
|
||||
GenericArgKind::Lifetime(r) => Some(r),
|
||||
GenericArgKind::Type(_) | GenericArgKind::Const(_) => None,
|
||||
|
@ -441,7 +441,7 @@ where
|
|||
let variances = self.tcx.variances_of(*def_id);
|
||||
|
||||
for (v, s) in std::iter::zip(variances, args.iter()) {
|
||||
if *v != ty::Variance::Bivariant {
|
||||
if *v != ty::Bivariant {
|
||||
s.visit_with(self);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,9 +102,7 @@ where
|
|||
};
|
||||
|
||||
for (idx, s) in args.iter().enumerate() {
|
||||
if variances.map(|variances| variances[idx])
|
||||
!= Some(ty::Variance::Bivariant)
|
||||
{
|
||||
if variances.map(|variances| variances[idx]) != Some(ty::Bivariant) {
|
||||
s.visit_with(self);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,16 +83,16 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// mention `?0`.
|
||||
if self.next_trait_solver() {
|
||||
let (lhs, rhs, direction) = match instantiation_variance {
|
||||
ty::Variance::Invariant => {
|
||||
ty::Invariant => {
|
||||
(generalized_ty.into(), source_ty.into(), AliasRelationDirection::Equate)
|
||||
}
|
||||
ty::Variance::Covariant => {
|
||||
ty::Covariant => {
|
||||
(generalized_ty.into(), source_ty.into(), AliasRelationDirection::Subtype)
|
||||
}
|
||||
ty::Variance::Contravariant => {
|
||||
ty::Contravariant => {
|
||||
(source_ty.into(), generalized_ty.into(), AliasRelationDirection::Subtype)
|
||||
}
|
||||
ty::Variance::Bivariant => unreachable!("bivariant generalization"),
|
||||
ty::Bivariant => unreachable!("bivariant generalization"),
|
||||
};
|
||||
|
||||
relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]);
|
||||
|
@ -192,7 +192,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
relation.span(),
|
||||
relation.structurally_relate_aliases(),
|
||||
target_vid,
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
source_ct,
|
||||
)?;
|
||||
|
||||
|
@ -210,14 +210,14 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// generalized const and the source.
|
||||
if target_is_expected {
|
||||
relation.relate_with_variance(
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
ty::VarianceDiagInfo::default(),
|
||||
generalized_ct,
|
||||
source_ct,
|
||||
)?;
|
||||
} else {
|
||||
relation.relate_with_variance(
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
ty::VarianceDiagInfo::default(),
|
||||
source_ct,
|
||||
generalized_ct,
|
||||
|
@ -411,7 +411,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
|
|||
a_arg: ty::GenericArgsRef<'tcx>,
|
||||
b_arg: ty::GenericArgsRef<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> {
|
||||
if self.ambient_variance == ty::Variance::Invariant {
|
||||
if self.ambient_variance == ty::Invariant {
|
||||
// Avoid fetching the variance if we are in an invariant
|
||||
// context; no need, and it can induce dependency cycles
|
||||
// (e.g., #41849).
|
||||
|
@ -667,7 +667,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
|
|||
// structural.
|
||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
|
||||
let args = self.relate_with_variance(
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
ty::VarianceDiagInfo::default(),
|
||||
args,
|
||||
args,
|
||||
|
|
|
@ -94,12 +94,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> {
|
|||
// When higher-ranked types are involved, computing the GLB is
|
||||
// very challenging, switch to invariance. This is obviously
|
||||
// overly conservative but works ok in practice.
|
||||
self.relate_with_variance(
|
||||
ty::Variance::Invariant,
|
||||
ty::VarianceDiagInfo::default(),
|
||||
a,
|
||||
b,
|
||||
)?;
|
||||
self.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
|
||||
Ok(a)
|
||||
} else {
|
||||
Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
|
||||
|
|
|
@ -94,12 +94,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
|
|||
// When higher-ranked types are involved, computing the LUB is
|
||||
// very challenging, switch to invariance. This is obviously
|
||||
// overly conservative but works ok in practice.
|
||||
self.relate_with_variance(
|
||||
ty::Variance::Invariant,
|
||||
ty::VarianceDiagInfo::default(),
|
||||
a,
|
||||
b,
|
||||
)?;
|
||||
self.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
|
||||
Ok(a)
|
||||
} else {
|
||||
Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
|
||||
|
|
|
@ -42,7 +42,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
|||
a_arg: ty::GenericArgsRef<'tcx>,
|
||||
b_arg: ty::GenericArgsRef<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> {
|
||||
if self.ambient_variance == ty::Variance::Invariant {
|
||||
if self.ambient_variance == ty::Invariant {
|
||||
// Avoid fetching the variance if we are in an invariant
|
||||
// context; no need, and it can induce dependency cycles
|
||||
// (e.g., #41849).
|
||||
|
@ -325,23 +325,23 @@ impl<'tcx> PredicateEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
|
|||
|
||||
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
|
||||
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
|
||||
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
|
||||
ty::Covariant => ty::PredicateKind::AliasRelate(
|
||||
a.into(),
|
||||
b.into(),
|
||||
ty::AliasRelationDirection::Subtype,
|
||||
),
|
||||
// a :> b is b <: a
|
||||
ty::Variance::Contravariant => ty::PredicateKind::AliasRelate(
|
||||
ty::Contravariant => ty::PredicateKind::AliasRelate(
|
||||
b.into(),
|
||||
a.into(),
|
||||
ty::AliasRelationDirection::Subtype,
|
||||
),
|
||||
ty::Variance::Invariant => ty::PredicateKind::AliasRelate(
|
||||
ty::Invariant => ty::PredicateKind::AliasRelate(
|
||||
a.into(),
|
||||
b.into(),
|
||||
ty::AliasRelationDirection::Equate,
|
||||
),
|
||||
ty::Variance::Bivariant => {
|
||||
ty::Bivariant => {
|
||||
unreachable!("Expected bivariance to be handled in relate_with_variance")
|
||||
}
|
||||
})]);
|
||||
|
|
|
@ -1490,7 +1490,8 @@ pub enum BinOp {
|
|||
BitOr,
|
||||
/// The `<<` operator (shift left)
|
||||
///
|
||||
/// The offset is (uniquely) determined as follows:
|
||||
/// The offset is given by `RHS.rem_euclid(LHS::BITS)`.
|
||||
/// In other words, it is (uniquely) determined as follows:
|
||||
/// - it is "equal modulo LHS::BITS" to the RHS
|
||||
/// - it is in the range `0..LHS::BITS`
|
||||
Shl,
|
||||
|
@ -1498,7 +1499,8 @@ pub enum BinOp {
|
|||
ShlUnchecked,
|
||||
/// The `>>` operator (shift right)
|
||||
///
|
||||
/// The offset is (uniquely) determined as follows:
|
||||
/// The offset is given by `RHS.rem_euclid(LHS::BITS)`.
|
||||
/// In other words, it is (uniquely) determined as follows:
|
||||
/// - it is "equal modulo LHS::BITS" to the RHS
|
||||
/// - it is in the range `0..LHS::BITS`
|
||||
///
|
||||
|
|
|
@ -16,7 +16,6 @@ pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeV
|
|||
pub use self::AssocItemContainer::*;
|
||||
pub use self::BorrowKind::*;
|
||||
pub use self::IntVarValue::*;
|
||||
pub use self::Variance::*;
|
||||
use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
|
||||
use crate::metadata::ModChild;
|
||||
use crate::middle::privacy::EffectiveVisibilities;
|
||||
|
|
|
@ -142,7 +142,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for &[ty::Variance] {
|
|||
&& let Some(def_id) = frame.query.def_id
|
||||
{
|
||||
let n = tcx.generics_of(def_id).own_params.len();
|
||||
vec![ty::Variance::Bivariant; n].leak()
|
||||
vec![ty::Bivariant; n].leak()
|
||||
} else {
|
||||
span_bug!(
|
||||
cycle_error.usage.as_ref().unwrap().0,
|
||||
|
|
|
@ -699,7 +699,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// exactly `T` (i.e., with invariance). The variance field, in
|
||||
// contrast, is intended to be used to relate `T` to the type of
|
||||
// `<expr>`.
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
),
|
||||
},
|
||||
);
|
||||
|
|
|
@ -92,7 +92,7 @@ impl<'tcx> Cx<'tcx> {
|
|||
kind: PatKind::AscribeUserType {
|
||||
ascription: Ascription {
|
||||
annotation,
|
||||
variance: ty::Variance::Covariant,
|
||||
variance: ty::Covariant,
|
||||
},
|
||||
subpattern: pattern,
|
||||
},
|
||||
|
|
|
@ -525,7 +525,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
};
|
||||
kind = PatKind::AscribeUserType {
|
||||
subpattern: Box::new(Pat { span, ty, kind }),
|
||||
ascription: Ascription { annotation, variance: ty::Variance::Covariant },
|
||||
ascription: Ascription { annotation, variance: ty::Covariant },
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -612,7 +612,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
annotation,
|
||||
// Note that use `Contravariant` here. See the
|
||||
// `variance` field documentation for details.
|
||||
variance: ty::Variance::Contravariant,
|
||||
variance: ty::Contravariant,
|
||||
},
|
||||
},
|
||||
ty: const_.ty(),
|
||||
|
|
|
@ -225,13 +225,8 @@ impl<'tcx> Inliner<'tcx> {
|
|||
// Normally, this shouldn't be required, but trait normalization failure can create a
|
||||
// validation ICE.
|
||||
let output_type = callee_body.return_ty();
|
||||
if !util::relate_types(
|
||||
self.tcx,
|
||||
self.param_env,
|
||||
ty::Variance::Covariant,
|
||||
output_type,
|
||||
destination_ty,
|
||||
) {
|
||||
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, output_type, destination_ty)
|
||||
{
|
||||
trace!(?output_type, ?destination_ty);
|
||||
return Err("failed to normalize return type");
|
||||
}
|
||||
|
@ -261,13 +256,8 @@ impl<'tcx> Inliner<'tcx> {
|
|||
self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
|
||||
{
|
||||
let input_type = callee_body.local_decls[input].ty;
|
||||
if !util::relate_types(
|
||||
self.tcx,
|
||||
self.param_env,
|
||||
ty::Variance::Covariant,
|
||||
input_type,
|
||||
arg_ty,
|
||||
) {
|
||||
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty)
|
||||
{
|
||||
trace!(?arg_ty, ?input_type);
|
||||
return Err("failed to normalize tuple argument type");
|
||||
}
|
||||
|
@ -276,13 +266,8 @@ impl<'tcx> Inliner<'tcx> {
|
|||
for (arg, input) in args.iter().zip(callee_body.args_iter()) {
|
||||
let input_type = callee_body.local_decls[input].ty;
|
||||
let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx);
|
||||
if !util::relate_types(
|
||||
self.tcx,
|
||||
self.param_env,
|
||||
ty::Variance::Covariant,
|
||||
input_type,
|
||||
arg_ty,
|
||||
) {
|
||||
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty)
|
||||
{
|
||||
trace!(?arg_ty, ?input_type);
|
||||
return Err("failed to normalize argument type");
|
||||
}
|
||||
|
|
|
@ -3281,17 +3281,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||
}
|
||||
self.visit_path(&delegation.path, delegation.id);
|
||||
if let Some(body) = &delegation.body {
|
||||
// `PatBoundCtx` is not necessary in this context
|
||||
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
|
||||
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
|
||||
// `PatBoundCtx` is not necessary in this context
|
||||
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
|
||||
|
||||
let span = delegation.path.segments.last().unwrap().ident.span;
|
||||
self.fresh_binding(
|
||||
Ident::new(kw::SelfLower, span),
|
||||
delegation.id,
|
||||
PatternSource::FnParam,
|
||||
&mut bindings,
|
||||
);
|
||||
self.visit_block(body);
|
||||
let span = delegation.path.segments.last().unwrap().ident.span;
|
||||
this.fresh_binding(
|
||||
Ident::new(kw::SelfLower, span),
|
||||
delegation.id,
|
||||
PatternSource::FnParam,
|
||||
&mut bindings,
|
||||
);
|
||||
this.visit_block(body);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1021,12 +1021,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
|||
},
|
||||
);
|
||||
let is_assoc_fn = self.self_type_is_available();
|
||||
let self_from_macro = "a `self` parameter, but a macro invocation can only \
|
||||
access identifiers it receives from parameters";
|
||||
if let Some((fn_kind, span)) = &self.diag_metadata.current_function {
|
||||
// The current function has a `self` parameter, but we were unable to resolve
|
||||
// a reference to `self`. This can only happen if the `self` identifier we
|
||||
// are resolving came from a different hygiene context.
|
||||
if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) {
|
||||
err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
|
||||
err.span_label(*span, format!("this function has {self_from_macro}"));
|
||||
} else {
|
||||
let doesnt = if is_assoc_fn {
|
||||
let (span, sugg) = fn_kind
|
||||
|
@ -1068,14 +1070,18 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
|||
}
|
||||
}
|
||||
} else if let Some(item_kind) = self.diag_metadata.current_item {
|
||||
err.span_label(
|
||||
item_kind.ident.span,
|
||||
format!(
|
||||
"`self` not allowed in {} {}",
|
||||
item_kind.kind.article(),
|
||||
item_kind.kind.descr()
|
||||
),
|
||||
);
|
||||
if matches!(item_kind.kind, ItemKind::Delegation(..)) {
|
||||
err.span_label(item_kind.span, format!("delegation supports {self_from_macro}"));
|
||||
} else {
|
||||
err.span_label(
|
||||
item_kind.ident.span,
|
||||
format!(
|
||||
"`self` not allowed in {} {}",
|
||||
item_kind.kind.article(),
|
||||
item_kind.kind.descr()
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
|
@ -866,10 +866,10 @@ impl<'tcx> Stable<'tcx> for ty::Variance {
|
|||
type T = stable_mir::mir::Variance;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
match self {
|
||||
ty::Variance::Bivariant => stable_mir::mir::Variance::Bivariant,
|
||||
ty::Variance::Contravariant => stable_mir::mir::Variance::Contravariant,
|
||||
ty::Variance::Covariant => stable_mir::mir::Variance::Covariant,
|
||||
ty::Variance::Invariant => stable_mir::mir::Variance::Invariant,
|
||||
ty::Bivariant => stable_mir::mir::Variance::Bivariant,
|
||||
ty::Contravariant => stable_mir::mir::Variance::Contravariant,
|
||||
ty::Covariant => stable_mir::mir::Variance::Covariant,
|
||||
ty::Invariant => stable_mir::mir::Variance::Invariant,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
trace!(?lhs, ?rhs);
|
||||
|
||||
let variance = match direction {
|
||||
ty::AliasRelationDirection::Equate => ty::Variance::Invariant,
|
||||
ty::AliasRelationDirection::Subtype => ty::Variance::Covariant,
|
||||
ty::AliasRelationDirection::Equate => ty::Invariant,
|
||||
ty::AliasRelationDirection::Subtype => ty::Covariant,
|
||||
};
|
||||
match (lhs.to_alias_term(), rhs.to_alias_term()) {
|
||||
(None, None) => {
|
||||
|
@ -78,7 +78,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
self.relate_rigid_alias_non_alias(
|
||||
param_env,
|
||||
alias,
|
||||
variance.xform(ty::Variance::Contravariant),
|
||||
variance.xform(ty::Contravariant),
|
||||
lhs,
|
||||
)?;
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
|
|
|
@ -40,7 +40,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||
Ok(res) => Ok(res),
|
||||
Err(NoSolution) => {
|
||||
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
|
||||
self.relate_rigid_alias_non_alias(param_env, alias, ty::Variance::Invariant, term)?;
|
||||
self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -239,24 +239,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let all_bounds = stack
|
||||
let bounds = stack
|
||||
.obligation
|
||||
.param_env
|
||||
.caller_bounds()
|
||||
.iter()
|
||||
.filter(|p| !p.references_error())
|
||||
.filter_map(|p| p.as_trait_clause());
|
||||
|
||||
// Micro-optimization: filter out predicates relating to different traits.
|
||||
let matching_bounds =
|
||||
all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id());
|
||||
.filter_map(|p| p.as_trait_clause())
|
||||
// Micro-optimization: filter out predicates relating to different traits.
|
||||
.filter(|p| p.def_id() == stack.obligation.predicate.def_id())
|
||||
.filter(|p| p.polarity() == stack.obligation.predicate.polarity());
|
||||
|
||||
// Keep only those bounds which may apply, and propagate overflow if it occurs.
|
||||
for bound in matching_bounds {
|
||||
if bound.skip_binder().polarity != stack.obligation.predicate.skip_binder().polarity {
|
||||
continue;
|
||||
}
|
||||
|
||||
for bound in bounds {
|
||||
// FIXME(oli-obk): it is suspicious that we are dropping the constness and
|
||||
// polarity here.
|
||||
let wc = self.where_clause_may_apply(stack, bound.map_bound(|t| t.trait_ref))?;
|
||||
|
|
|
@ -74,6 +74,7 @@ pub use DynKind::*;
|
|||
pub use InferTy::*;
|
||||
pub use RegionKind::*;
|
||||
pub use TyKind::*;
|
||||
pub use Variance::*;
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// A [De Bruijn index][dbi] is a standard means of representing
|
||||
|
|
|
@ -128,7 +128,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>(
|
|||
b_arg: I::GenericArgs,
|
||||
) -> RelateResult<I, I::GenericArgs> {
|
||||
relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| {
|
||||
relation.relate_with_variance(ty::Variance::Invariant, VarianceDiagInfo::default(), a, b)
|
||||
relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b)
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>(
|
|||
let mut cached_ty = None;
|
||||
let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| {
|
||||
let variance = variances[i];
|
||||
let variance_info = if variance == ty::Variance::Invariant && fetch_ty_for_diag {
|
||||
let variance_info = if variance == ty::Invariant && fetch_ty_for_diag {
|
||||
let ty =
|
||||
*cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, &a_arg));
|
||||
VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
|
||||
|
@ -191,7 +191,7 @@ impl<I: Interner> Relate<I> for ty::FnSig<I> {
|
|||
relation.relate(a, b)
|
||||
} else {
|
||||
relation.relate_with_variance(
|
||||
ty::Variance::Contravariant,
|
||||
ty::Contravariant,
|
||||
VarianceDiagInfo::default(),
|
||||
a,
|
||||
b,
|
||||
|
@ -311,13 +311,13 @@ impl<I: Interner> Relate<I> for ty::ExistentialProjection<I> {
|
|||
}))
|
||||
} else {
|
||||
let term = relation.relate_with_variance(
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
VarianceDiagInfo::default(),
|
||||
a.term,
|
||||
b.term,
|
||||
)?;
|
||||
let args = relation.relate_with_variance(
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
VarianceDiagInfo::default(),
|
||||
a.args,
|
||||
b.args,
|
||||
|
@ -466,9 +466,9 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
|
|||
}
|
||||
|
||||
let (variance, info) = match a_mutbl {
|
||||
Mutability::Not => (ty::Variance::Covariant, VarianceDiagInfo::None),
|
||||
Mutability::Not => (ty::Covariant, VarianceDiagInfo::None),
|
||||
Mutability::Mut => {
|
||||
(ty::Variance::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
|
||||
(ty::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -483,9 +483,9 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
|
|||
}
|
||||
|
||||
let (variance, info) = match a_mutbl {
|
||||
Mutability::Not => (ty::Variance::Covariant, VarianceDiagInfo::None),
|
||||
Mutability::Not => (ty::Covariant, VarianceDiagInfo::None),
|
||||
Mutability::Mut => {
|
||||
(ty::Variance::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
|
||||
(ty::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -612,7 +612,7 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
|
|||
}
|
||||
|
||||
let args = relation.relate_with_variance(
|
||||
ty::Variance::Invariant,
|
||||
ty::Invariant,
|
||||
VarianceDiagInfo::default(),
|
||||
au.args,
|
||||
bu.args,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue