summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/variance
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src/variance')
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/variance/terms.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/variance/test.rs15
4 files changed, 33 insertions, 20 deletions
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index 8a40509d7..61d9c989e 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -6,7 +6,7 @@
use hir::def_id::{DefId, LocalDefId};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use super::terms::VarianceTerm::*;
@@ -78,9 +78,7 @@ pub fn add_constraints_from_crate<'a, 'tcx>(
}
}
DefKind::Fn | DefKind::AssocFn => constraint_cx.build_constraints_for_item(def_id),
- DefKind::TyAlias { lazy }
- if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
- {
+ DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
constraint_cx.build_constraints_for_item(def_id)
}
_ => {}
@@ -110,8 +108,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
// 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.
- if let DefKind::TyAlias { lazy } = tcx.def_kind(def_id)
- && (lazy || ty.has_opaque_types())
+ if let DefKind::TyAlias = tcx.def_kind(def_id)
+ && tcx.type_alias_is_lazy(def_id)
{
self.add_constraints_from_ty(current_item, ty, self.covariant);
return;
@@ -314,11 +312,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
// types, where we use Error as the Self type
}
- ty::Placeholder(..)
- | ty::GeneratorWitness(..)
- | ty::GeneratorWitnessMIR(..)
- | ty::Bound(..)
- | ty::Infer(..) => {
+ ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Bound(..) | ty::Infer(..) => {
bug!("unexpected type encountered in variance inference: {}", ty);
}
}
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index d91d9fcbc..85e0000ab 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -8,7 +8,7 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt};
-use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
+use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
use std::ops::ControlFlow;
/// Defines the `TermsContext` basically houses an arena where we can
@@ -56,9 +56,7 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
let crate_map = tcx.crate_variances(());
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
}
- DefKind::TyAlias { lazy }
- if lazy || tcx.type_of(item_def_id).instantiate_identity().has_opaque_types() =>
- {
+ DefKind::TyAlias if tcx.type_alias_is_lazy(item_def_id) => {
// These are inferred.
let crate_map = tcx.crate_variances(());
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
@@ -129,7 +127,15 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
// By default, RPIT are invariant wrt type and const generics, but they are bivariant wrt
// lifetime generics.
- let mut variances: Vec<_> = std::iter::repeat(ty::Invariant).take(generics.count()).collect();
+ let variances = std::iter::repeat(ty::Invariant).take(generics.count());
+
+ let mut variances: Vec<_> = match tcx.opaque_type_origin(item_def_id) {
+ rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {
+ variances.collect()
+ }
+ // But TAIT are invariant for all generics
+ rustc_hir::OpaqueTyOrigin::TyAlias { .. } => return tcx.arena.alloc_from_iter(variances),
+ };
// Mark all lifetimes from parent generics as unused (Bivariant).
// This will be overridden later if required.
diff --git a/compiler/rustc_hir_analysis/src/variance/terms.rs b/compiler/rustc_hir_analysis/src/variance/terms.rs
index 1a8ec5f08..275df2495 100644
--- a/compiler/rustc_hir_analysis/src/variance/terms.rs
+++ b/compiler/rustc_hir_analysis/src/variance/terms.rs
@@ -12,7 +12,7 @@
use rustc_arena::DroplessArena;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{LocalDefId, LocalDefIdMap};
-use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, TyCtxt};
use std::fmt;
use self::VarianceTerm::*;
@@ -97,9 +97,7 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
}
}
DefKind::Fn | DefKind::AssocFn => terms_cx.add_inferreds_for_item(def_id),
- DefKind::TyAlias { lazy }
- if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
- {
+ DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
terms_cx.add_inferreds_for_item(def_id)
}
_ => {}
diff --git a/compiler/rustc_hir_analysis/src/variance/test.rs b/compiler/rustc_hir_analysis/src/variance/test.rs
index d57d05d76..d98dc0e6b 100644
--- a/compiler/rustc_hir_analysis/src/variance/test.rs
+++ b/compiler/rustc_hir_analysis/src/variance/test.rs
@@ -1,9 +1,24 @@
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym;
use crate::errors;
pub fn test_variance(tcx: TyCtxt<'_>) {
+ if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
+ for id in tcx.hir().items() {
+ if matches!(tcx.def_kind(id.owner_id), DefKind::OpaqueTy) {
+ let variances_of = tcx.variances_of(id.owner_id);
+
+ tcx.sess.emit_err(errors::VariancesOf {
+ span: tcx.def_span(id.owner_id),
+ variances_of: format!("{variances_of:?}"),
+ });
+ }
+ }
+ }
+
// For unit testing: check for a special "rustc_variance"
// attribute and report an error with various results if found.
for id in tcx.hir().items() {