summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty/sty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty/sty.rs')
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs71
1 files changed, 39 insertions, 32 deletions
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index cf420bafe..9cbda95a4 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -17,9 +17,11 @@ use rustc_data_structures::captures::Captures;
use rustc_data_structures::intern::Interned;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
+use rustc_hir::LangItem;
use rustc_index::vec::Idx;
use rustc_macros::HashStable;
use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::Span;
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi;
use std::borrow::Cow;
@@ -58,7 +60,7 @@ pub struct FreeRegion {
#[derive(HashStable)]
pub enum BoundRegionKind {
/// An anonymous region parameter for a given fn (&T)
- BrAnon(u32),
+ BrAnon(u32, Option<Span>),
/// Named region parameters for functions (a in &'a T)
///
@@ -81,7 +83,9 @@ pub struct BoundRegion {
impl BoundRegionKind {
pub fn is_named(&self) -> bool {
match *self {
- BoundRegionKind::BrNamed(_, name) => name != kw::UnderscoreLifetime,
+ BoundRegionKind::BrNamed(_, name) => {
+ name != kw::UnderscoreLifetime && name != kw::Empty
+ }
_ => false,
}
}
@@ -702,7 +706,9 @@ impl<'tcx> ExistentialPredicate<'tcx> {
}
}
-impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> {
+pub type PolyExistentialPredicate<'tcx> = Binder<'tcx, ExistentialPredicate<'tcx>>;
+
+impl<'tcx> PolyExistentialPredicate<'tcx> {
/// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`),
/// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self`
/// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example).
@@ -716,17 +722,23 @@ impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> {
self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
}
ExistentialPredicate::AutoTrait(did) => {
- let trait_ref = self.rebind(ty::TraitRef {
- def_id: did,
- substs: tcx.mk_substs_trait(self_ty, &[]),
- });
- trait_ref.without_const().to_predicate(tcx)
+ let generics = tcx.generics_of(did);
+ let trait_ref = if generics.params.len() == 1 {
+ tcx.mk_trait_ref(did, [self_ty])
+ } else {
+ // If this is an ill-formed auto trait, then synthesize
+ // new error substs for the missing generics.
+ let err_substs =
+ ty::InternalSubsts::extend_with_error(tcx, did, &[self_ty.into()]);
+ tcx.mk_trait_ref(did, err_substs)
+ };
+ self.rebind(trait_ref).without_const().to_predicate(tcx)
}
}
}
}
-impl<'tcx> List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
+impl<'tcx> List<ty::PolyExistentialPredicate<'tcx>> {
/// Returns the "principal `DefId`" of this set of existential predicates.
///
/// A Rust trait object type consists (in addition to a lifetime bound)
@@ -811,6 +823,13 @@ impl<'tcx> TraitRef<'tcx> {
TraitRef { def_id, substs }
}
+ pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
+ tcx.mk_trait_ref(
+ self.def_id,
+ [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)),
+ )
+ }
+
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
/// are the parameters defined on trait.
pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> {
@@ -845,23 +864,6 @@ impl<'tcx> PolyTraitRef<'tcx> {
pub fn def_id(&self) -> DefId {
self.skip_binder().def_id
}
-
- pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
- self.map_bound(|trait_ref| ty::TraitPredicate {
- trait_ref,
- constness: ty::BoundConstness::NotConst,
- polarity: ty::ImplPolarity::Positive,
- })
- }
-
- /// Same as [`PolyTraitRef::to_poly_trait_predicate`] but sets a negative polarity instead.
- pub fn to_poly_trait_predicate_negative_polarity(&self) -> ty::PolyTraitPredicate<'tcx> {
- self.map_bound(|trait_ref| ty::TraitPredicate {
- trait_ref,
- constness: ty::BoundConstness::NotConst,
- polarity: ty::ImplPolarity::Negative,
- })
- }
}
impl rustc_errors::IntoDiagnosticArg for PolyTraitRef<'_> {
@@ -906,7 +908,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
// otherwise the escaping vars would be captured by the binder
// debug_assert!(!self_ty.has_escaping_bound_vars());
- ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) }
+ tcx.mk_trait_ref(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter()))
}
}
@@ -1282,6 +1284,12 @@ impl<'tcx> ParamTy {
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
tcx.mk_ty_param(self.index, self.name)
}
+
+ pub fn span_from_generics(&self, tcx: TyCtxt<'tcx>, item_with_generics: DefId) -> Span {
+ let generics = tcx.generics_of(item_with_generics);
+ let type_param = generics.type_param(self, tcx);
+ tcx.def_span(type_param.def_id)
+ }
}
#[derive(Copy, Clone, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)]
@@ -1603,7 +1611,7 @@ impl<'tcx> Region<'tcx> {
impl<'tcx> Ty<'tcx> {
#[inline(always)]
pub fn kind(self) -> &'tcx TyKind<'tcx> {
- &self.0.0.kind
+ &self.0.0
}
#[inline(always)]
@@ -2095,7 +2103,7 @@ impl<'tcx> Ty<'tcx> {
ty::Str | ty::Slice(_) => (tcx.types.usize, false),
ty::Dynamic(..) => {
- let dyn_metadata = tcx.lang_items().dyn_metadata().unwrap();
+ let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None);
(tcx.bound_type_of(dyn_metadata).subst(tcx, &[tail.into()]), false)
},
@@ -2117,8 +2125,7 @@ impl<'tcx> Ty<'tcx> {
/// parameter. This is kind of a phantom type, except that the
/// most convenient thing for us to are the integral types. This
/// function converts such a special type into the closure
- /// kind. To go the other way, use
- /// `tcx.closure_kind_ty(closure_kind)`.
+ /// kind. To go the other way, use `closure_kind.to_ty(tcx)`.
///
/// Note that during type checking, we use an inference variable
/// to represent the closure kind, because it has not yet been
@@ -2244,7 +2251,7 @@ impl<'tcx> Ty<'tcx> {
}
}
- // If `self` is a primitive, return its [`Symbol`].
+ /// If `self` is a primitive, return its [`Symbol`].
pub fn primitive_symbol(self) -> Option<Symbol> {
match self.kind() {
ty::Bool => Some(sym::bool),