pub use adt::*;
pub use assoc::*;
pub use generics::*;
-use hir::OpaqueTyOrigin;
use rustc_ast as ast;
use rustc_ast::node_id::NodeMap;
use rustc_attr as attr;
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, LifetimeRes, Res};
-use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap};
+use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
use rustc_hir::Node;
use rustc_index::vec::IndexVec;
use rustc_macros::HashStable;
/// For each item with generics, maps to a vector of the variance
/// of its generics. If an item has no generics, it will have no
/// entry.
- pub variances: FxHashMap<DefId, &'tcx [ty::Variance]>,
+ pub variances: DefIdMap<&'tcx [ty::Variance]>,
}
// Contains information needed to resolve types and (in the future) look up
pub fn is_empty(&self) -> bool {
self.predicates.is_empty()
}
+
+ pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter {
+ (&self).into_iter()
+ }
+}
+
+impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> {
+ type Item = (Predicate<'tcx>, Span);
+
+ type IntoIter = std::iter::Zip<std::vec::IntoIter<Predicate<'tcx>>, std::vec::IntoIter<Span>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ debug_assert_eq!(self.predicates.len(), self.spans.len());
+ std::iter::zip(self.predicates, self.spans)
+ }
+}
+
+impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
+ type Item = (Predicate<'tcx>, Span);
+
+ type IntoIter = std::iter::Zip<
+ std::iter::Copied<std::slice::Iter<'a, Predicate<'tcx>>>,
+ std::iter::Copied<std::slice::Iter<'a, Span>>,
+ >;
+
+ fn into_iter(self) -> Self::IntoIter {
+ debug_assert_eq!(self.predicates.len(), self.spans.len());
+ std::iter::zip(self.predicates.iter().copied(), self.spans.iter().copied())
+ }
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable, Lift)]
tcx: TyCtxt<'tcx>,
// typeck errors have subpar spans for opaque types, so delay error reporting until borrowck.
ignore_errors: bool,
- origin: OpaqueTyOrigin,
) -> Self {
let OpaqueTypeKey { def_id, substs } = opaque_type_key;
// This zip may have several times the same lifetime in `substs` paired with a different
// lifetime from `id_substs`. Simply `collect`ing the iterator is the correct behaviour:
// it will pick the last one, which is the one we introduced in the impl-trait desugaring.
- let map = substs.iter().zip(id_substs);
-
- let map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>> = match origin {
- // HACK: The HIR lowering for async fn does not generate
- // any `+ Captures<'x>` bounds for the `impl Future<...>`, so all async fns with lifetimes
- // would now fail to compile. We should probably just make hir lowering fill this in properly.
- OpaqueTyOrigin::AsyncFn(_) => map.collect(),
- OpaqueTyOrigin::FnReturn(_) | OpaqueTyOrigin::TyAlias => {
- // Opaque types may only use regions that are bound. So for
- // ```rust
- // type Foo<'a, 'b, 'c> = impl Trait<'a> + 'b;
- // ```
- // we may not use `'c` in the hidden type.
- let variances = tcx.variances_of(def_id);
- debug!(?variances);
-
- map.filter(|(_, v)| {
- let ty::GenericArgKind::Lifetime(lt) = v.unpack() else { return true };
- let ty::ReEarlyBound(ebr) = lt.kind() else { bug!() };
- variances[ebr.index as usize] == ty::Variance::Invariant
- })
- .collect()
- }
- };
+ let map = substs.iter().zip(id_substs).collect();
debug!("map = {:#?}", map);
// Convert the type from the function into a type valid outside
) -> Option<ImplOverlapKind> {
// If either trait impl references an error, they're allowed to overlap,
// as one of them essentially doesn't exist.
- if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error())
- || self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error())
+ if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.subst_identity().references_error())
+ || self
+ .impl_trait_ref(def_id2)
+ .map_or(false, |tr| tr.subst_identity().references_error())
{
return Some(ImplOverlapKind::Permitted { marker: false });
}
let is_marker_overlap = {
let is_marker_impl = |def_id: DefId| -> bool {
let trait_ref = self.impl_trait_ref(def_id);
- trait_ref.map_or(false, |tr| self.trait_def(tr.def_id).is_marker)
+ trait_ref.map_or(false, |tr| self.trait_def(tr.skip_binder().def_id).is_marker)
};
is_marker_impl(def_id1) && is_marker_impl(def_id2)
};
self.trait_def(trait_def_id).has_auto_impl
}
+ /// Returns `true` if this is a trait alias.
+ pub fn trait_is_alias(self, trait_def_id: DefId) -> bool {
+ self.def_kind(trait_def_id) == DefKind::TraitAlias
+ }
+
pub fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
self.trait_is_auto(trait_def_id) || self.lang_items().sized_trait() == Some(trait_def_id)
}
/// Given the `DefId` of an impl, returns the `DefId` of the trait it implements.
/// If it implements no trait, returns `None`.
pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> {
- self.impl_trait_ref(def_id).map(|tr| tr.def_id)
+ self.impl_trait_ref(def_id).map(|tr| tr.skip_binder().def_id)
}
/// If the given `DefId` describes an item belonging to a trait,
}
#[derive(Debug, Default, Copy, Clone)]
-pub struct FoundRelationships {
+pub struct InferVarInfo {
/// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo`
/// obligation, where:
///