diff options
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 71 |
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), |