Make hir::TyKind::TraitObject
use tagged ptr
This commit is contained in:
parent
3cd8fcbf87
commit
0f10ba60ff
20 changed files with 84 additions and 48 deletions
|
@ -28,6 +28,7 @@ use rustc_data_structures::packed::Pu128;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
use rustc_data_structures::tagged_ptr::Tag;
|
||||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
||||||
pub use rustc_span::AttrId;
|
pub use rustc_span::AttrId;
|
||||||
use rustc_span::source_map::{Spanned, respan};
|
use rustc_span::source_map::{Spanned, respan};
|
||||||
|
@ -2269,10 +2270,32 @@ impl TyKind {
|
||||||
|
|
||||||
/// Syntax used to declare a trait object.
|
/// Syntax used to declare a trait object.
|
||||||
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||||
|
#[repr(u8)]
|
||||||
pub enum TraitObjectSyntax {
|
pub enum TraitObjectSyntax {
|
||||||
Dyn,
|
// SAFETY: When adding new variants make sure to update the `Tag` impl.
|
||||||
DynStar,
|
Dyn = 0,
|
||||||
None,
|
DynStar = 1,
|
||||||
|
None = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// SAFETY: `TraitObjectSyntax` only has 3 data-less variants which means
|
||||||
|
/// it can be represented with a `u2`. We use `repr(u8)` to guarantee the
|
||||||
|
/// discriminants of the variants are no greater than `3`.
|
||||||
|
unsafe impl Tag for TraitObjectSyntax {
|
||||||
|
const BITS: u32 = 2;
|
||||||
|
|
||||||
|
fn into_usize(self) -> usize {
|
||||||
|
self as u8 as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn from_usize(tag: usize) -> Self {
|
||||||
|
match tag {
|
||||||
|
0 => TraitObjectSyntax::Dyn,
|
||||||
|
1 => TraitObjectSyntax::DynStar,
|
||||||
|
2 => TraitObjectSyntax::None,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
|
|
@ -48,6 +48,7 @@ use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::sorted_map::SortedMap;
|
use rustc_data_structures::sorted_map::SortedMap;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
use rustc_data_structures::tagged_ptr::TaggedRef;
|
||||||
use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
|
use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
|
||||||
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
|
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
|
||||||
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
|
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
|
||||||
|
@ -1158,7 +1159,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let lifetime_bound = this.elided_dyn_bound(t.span);
|
let lifetime_bound = this.elided_dyn_bound(t.span);
|
||||||
(bounds, lifetime_bound)
|
(bounds, lifetime_bound)
|
||||||
});
|
});
|
||||||
let kind = hir::TyKind::TraitObject(bounds, lifetime_bound, TraitObjectSyntax::None);
|
let kind = hir::TyKind::TraitObject(
|
||||||
|
bounds,
|
||||||
|
TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
|
||||||
|
);
|
||||||
return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
|
return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1309,7 +1313,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
|
lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
|
||||||
(bounds, lifetime_bound)
|
(bounds, lifetime_bound)
|
||||||
});
|
});
|
||||||
hir::TyKind::TraitObject(bounds, lifetime_bound, *kind)
|
hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
|
||||||
}
|
}
|
||||||
TyKind::ImplTrait(def_node_id, bounds) => {
|
TyKind::ImplTrait(def_node_id, bounds) => {
|
||||||
let span = t.span;
|
let span = t.span;
|
||||||
|
@ -2365,8 +2369,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
hir_id = self.next_id();
|
hir_id = self.next_id();
|
||||||
hir::TyKind::TraitObject(
|
hir::TyKind::TraitObject(
|
||||||
arena_vec![self; principal],
|
arena_vec![self; principal],
|
||||||
self.elided_dyn_bound(span),
|
TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
|
||||||
TraitObjectSyntax::None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
|
_ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
|
||||||
|
|
|
@ -887,7 +887,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
if alias_ty.span.desugaring_kind().is_some() {
|
if alias_ty.span.desugaring_kind().is_some() {
|
||||||
// Skip `async` desugaring `impl Future`.
|
// Skip `async` desugaring `impl Future`.
|
||||||
}
|
}
|
||||||
if let TyKind::TraitObject(_, lt, _) = alias_ty.kind {
|
if let TyKind::TraitObject(_, lt) = alias_ty.kind {
|
||||||
if lt.ident.name == kw::Empty {
|
if lt.ident.name == kw::Empty {
|
||||||
spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
|
spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,6 +15,7 @@ pub use rustc_ast::{
|
||||||
};
|
};
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::sorted_map::SortedMap;
|
use rustc_data_structures::sorted_map::SortedMap;
|
||||||
|
use rustc_data_structures::tagged_ptr::TaggedRef;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
|
@ -764,11 +765,8 @@ impl<'hir> Generics<'hir> {
|
||||||
&& let [.., segment] = trait_ref.path.segments
|
&& let [.., segment] = trait_ref.path.segments
|
||||||
&& let Some(ret_ty) = segment.args().paren_sugar_output()
|
&& let Some(ret_ty) = segment.args().paren_sugar_output()
|
||||||
&& let ret_ty = ret_ty.peel_refs()
|
&& let ret_ty = ret_ty.peel_refs()
|
||||||
&& let TyKind::TraitObject(
|
&& let TyKind::TraitObject(_, tagged_ptr) = ret_ty.kind
|
||||||
_,
|
&& let TraitObjectSyntax::Dyn | TraitObjectSyntax::DynStar = tagged_ptr.tag()
|
||||||
_,
|
|
||||||
TraitObjectSyntax::Dyn | TraitObjectSyntax::DynStar,
|
|
||||||
) = ret_ty.kind
|
|
||||||
&& ret_ty.span.can_be_used_for_suggestions()
|
&& ret_ty.span.can_be_used_for_suggestions()
|
||||||
{
|
{
|
||||||
Some(ret_ty.span)
|
Some(ret_ty.span)
|
||||||
|
@ -3230,7 +3228,10 @@ pub enum TyKind<'hir> {
|
||||||
TraitAscription(GenericBounds<'hir>),
|
TraitAscription(GenericBounds<'hir>),
|
||||||
/// A trait object type `Bound1 + Bound2 + Bound3`
|
/// A trait object type `Bound1 + Bound2 + Bound3`
|
||||||
/// where `Bound` is a trait or a lifetime.
|
/// where `Bound` is a trait or a lifetime.
|
||||||
TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
|
///
|
||||||
|
/// We use pointer tagging to represent a `&'hir Lifetime` and `TraitObjectSyntax` pair
|
||||||
|
/// as otherwise this type being `repr(C)` would result in `TyKind` increasing in size.
|
||||||
|
TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>),
|
||||||
/// Unused for now.
|
/// Unused for now.
|
||||||
Typeof(&'hir AnonConst),
|
Typeof(&'hir AnonConst),
|
||||||
/// `TyKind::Infer` means the type should be inferred instead of it having been
|
/// `TyKind::Infer` means the type should be inferred instead of it having been
|
||||||
|
|
|
@ -922,7 +922,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
|
||||||
try_visit!(visitor.visit_ty(ty));
|
try_visit!(visitor.visit_ty(ty));
|
||||||
try_visit!(visitor.visit_const_arg(length));
|
try_visit!(visitor.visit_const_arg(length));
|
||||||
}
|
}
|
||||||
TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
|
TyKind::TraitObject(bounds, ref lifetime) => {
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
try_visit!(visitor.visit_poly_trait_ref(bound));
|
try_visit!(visitor.visit_poly_trait_ref(bound));
|
||||||
}
|
}
|
||||||
|
|
|
@ -810,7 +810,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
intravisit::walk_ty(this, ty);
|
intravisit::walk_ty(this, ty);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
hir::TyKind::TraitObject(bounds, lifetime, _) => {
|
hir::TyKind::TraitObject(bounds, lifetime) => {
|
||||||
|
let lifetime = lifetime.pointer();
|
||||||
|
|
||||||
debug!(?bounds, ?lifetime, "TraitObject");
|
debug!(?bounds, ?lifetime, "TraitObject");
|
||||||
let scope = Scope::TraitRefBoundary { s: self.scope };
|
let scope = Scope::TraitRefBoundary { s: self.scope };
|
||||||
self.with(scope, |this| {
|
self.with(scope, |this| {
|
||||||
|
@ -827,7 +829,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
// use the object lifetime defaulting
|
// use the object lifetime defaulting
|
||||||
// rules. So e.g., `Box<dyn Debug>` becomes
|
// rules. So e.g., `Box<dyn Debug>` becomes
|
||||||
// `Box<dyn Debug + 'static>`.
|
// `Box<dyn Debug + 'static>`.
|
||||||
self.resolve_object_lifetime_default(lifetime)
|
self.resolve_object_lifetime_default(&*lifetime)
|
||||||
}
|
}
|
||||||
LifetimeName::Infer => {
|
LifetimeName::Infer => {
|
||||||
// If the user writes `'_`, we use the *ordinary* elision
|
// If the user writes `'_`, we use the *ordinary* elision
|
||||||
|
@ -838,7 +840,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
LifetimeName::Param(..) | LifetimeName::Static => {
|
LifetimeName::Param(..) | LifetimeName::Static => {
|
||||||
// If the user wrote an explicit name, use that.
|
// If the user wrote an explicit name, use that.
|
||||||
self.visit_lifetime(lifetime);
|
self.visit_lifetime(&*lifetime);
|
||||||
}
|
}
|
||||||
LifetimeName::Error => {}
|
LifetimeName::Error => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
) -> Option<ErrorGuaranteed> {
|
) -> Option<ErrorGuaranteed> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
|
let poly_trait_ref = if let hir::TyKind::TraitObject([poly_trait_ref, ..], tagged_ptr) =
|
||||||
self_ty.kind
|
self_ty.kind
|
||||||
else {
|
&& let TraitObjectSyntax::None = tagged_ptr.tag()
|
||||||
|
{
|
||||||
|
poly_trait_ref
|
||||||
|
} else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -294,7 +297,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let (dyn_str, paren_dyn_str) =
|
let (dyn_str, paren_dyn_str) =
|
||||||
if borrowed { ("dyn ", "(dyn ") } else { ("&dyn ", "&(dyn ") };
|
if borrowed { ("dyn ", "(dyn ") } else { ("&dyn ", "&(dyn ") };
|
||||||
|
|
||||||
let sugg = if let hir::TyKind::TraitObject([_, _, ..], _, _) = self_ty.kind {
|
let sugg = if let hir::TyKind::TraitObject([_, _, ..], _) = self_ty.kind {
|
||||||
// There are more than one trait bound, we need surrounding parentheses.
|
// There are more than one trait bound, we need surrounding parentheses.
|
||||||
vec![
|
vec![
|
||||||
(self_ty.span.shrink_to_lo(), paren_dyn_str.to_string()),
|
(self_ty.span.shrink_to_lo(), paren_dyn_str.to_string()),
|
||||||
|
|
|
@ -2311,7 +2311,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
tcx.late_bound_vars(hir_ty.hir_id),
|
tcx.late_bound_vars(hir_ty.hir_id),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
|
hir::TyKind::TraitObject(bounds, tagged_ptr) => {
|
||||||
|
let lifetime = tagged_ptr.pointer();
|
||||||
|
let repr = tagged_ptr.tag();
|
||||||
|
|
||||||
if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
|
if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
|
||||||
// Don't continue with type analysis if the `dyn` keyword is missing
|
// Don't continue with type analysis if the `dyn` keyword is missing
|
||||||
// It generates confusing errors, especially if the user meant to use another
|
// It generates confusing errors, especially if the user meant to use another
|
||||||
|
|
|
@ -402,7 +402,8 @@ impl<'a> State<'a> {
|
||||||
self.print_bounds("impl", bounds);
|
self.print_bounds("impl", bounds);
|
||||||
}
|
}
|
||||||
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
|
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
|
||||||
hir::TyKind::TraitObject(bounds, lifetime, syntax) => {
|
hir::TyKind::TraitObject(bounds, lifetime) => {
|
||||||
|
let syntax = lifetime.tag();
|
||||||
match syntax {
|
match syntax {
|
||||||
ast::TraitObjectSyntax::Dyn => self.word_nbsp("dyn"),
|
ast::TraitObjectSyntax::Dyn => self.word_nbsp("dyn"),
|
||||||
ast::TraitObjectSyntax::DynStar => self.word_nbsp("dyn*"),
|
ast::TraitObjectSyntax::DynStar => self.word_nbsp("dyn*"),
|
||||||
|
@ -421,7 +422,7 @@ impl<'a> State<'a> {
|
||||||
if !lifetime.is_elided() {
|
if !lifetime.is_elided() {
|
||||||
self.nbsp();
|
self.nbsp();
|
||||||
self.word_space("+");
|
self.word_space("+");
|
||||||
self.print_lifetime(lifetime);
|
self.print_lifetime(lifetime.pointer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::TyKind::Array(ty, ref length) => {
|
hir::TyKind::Array(ty, ref length) => {
|
||||||
|
|
|
@ -111,7 +111,9 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
|
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
|
||||||
let hir::TyKind::TraitObject(bounds, _lifetime, _syntax) = &ty.kind else { return };
|
let hir::TyKind::TraitObject(bounds, _lifetime_and_syntax_pointer) = &ty.kind else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
for bound in &bounds[..] {
|
for bound in &bounds[..] {
|
||||||
let def_id = bound.trait_ref.trait_def_id();
|
let def_id = bound.trait_ref.trait_def_id();
|
||||||
if def_id.is_some_and(|def_id| cx.tcx.is_lang_item(def_id, LangItem::Drop)) {
|
if def_id.is_some_and(|def_id| cx.tcx.is_lang_item(def_id, LangItem::Drop)) {
|
||||||
|
|
|
@ -572,16 +572,16 @@ pub struct TraitObjectVisitor<'tcx>(pub Vec<&'tcx hir::Ty<'tcx>>, pub crate::hir
|
||||||
impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
|
impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
|
||||||
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
|
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
hir::TyKind::TraitObject(
|
hir::TyKind::TraitObject(_, tagged_ptr)
|
||||||
_,
|
if let hir::Lifetime {
|
||||||
hir::Lifetime {
|
|
||||||
res:
|
res:
|
||||||
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static,
|
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static,
|
||||||
..
|
..
|
||||||
},
|
} = tagged_ptr.pointer() =>
|
||||||
_,
|
{
|
||||||
)
|
self.0.push(ty)
|
||||||
| hir::TyKind::OpaqueDef(..) => self.0.push(ty),
|
}
|
||||||
|
hir::TyKind::OpaqueDef(..) => self.0.push(ty),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
hir::intravisit::walk_ty(self, ty);
|
hir::intravisit::walk_ty(self, ty);
|
||||||
|
|
|
@ -374,7 +374,7 @@ pub fn suggest_new_region_bound(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TyKind::TraitObject(_, lt, _) => {
|
TyKind::TraitObject(_, lt) => {
|
||||||
if let LifetimeName::ImplicitObjectLifetimeDefault = lt.res {
|
if let LifetimeName::ImplicitObjectLifetimeDefault = lt.res {
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
fn_return.span.shrink_to_hi(),
|
fn_return.span.shrink_to_hi(),
|
||||||
|
@ -592,11 +592,9 @@ pub struct HirTraitObjectVisitor<'a>(pub &'a mut Vec<Span>, pub DefId);
|
||||||
|
|
||||||
impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
|
impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
|
||||||
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
|
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
|
||||||
if let TyKind::TraitObject(
|
if let TyKind::TraitObject(poly_trait_refs, lifetime_ptr) = t.kind
|
||||||
poly_trait_refs,
|
&& let Lifetime { res: LifetimeName::ImplicitObjectLifetimeDefault, .. } =
|
||||||
Lifetime { res: LifetimeName::ImplicitObjectLifetimeDefault, .. },
|
lifetime_ptr.pointer()
|
||||||
_,
|
|
||||||
) = t.kind
|
|
||||||
{
|
{
|
||||||
for ptr in poly_trait_refs {
|
for ptr in poly_trait_refs {
|
||||||
if Some(self.1) == ptr.trait_ref.trait_def_id() {
|
if Some(self.1) == ptr.trait_ref.trait_def_id() {
|
||||||
|
|
|
@ -580,8 +580,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
self.tcx.hir_node_by_def_id(obligation.cause.body_id)
|
self.tcx.hir_node_by_def_id(obligation.cause.body_id)
|
||||||
&& let hir::ItemKind::Impl(impl_) = item.kind
|
&& let hir::ItemKind::Impl(impl_) = item.kind
|
||||||
&& let None = impl_.of_trait
|
&& let None = impl_.of_trait
|
||||||
&& let hir::TyKind::TraitObject(_, _, syntax) = impl_.self_ty.kind
|
&& let hir::TyKind::TraitObject(_, tagged_ptr) = impl_.self_ty.kind
|
||||||
&& let TraitObjectSyntax::None = syntax
|
&& let TraitObjectSyntax::None = tagged_ptr.tag()
|
||||||
&& impl_.self_ty.span.edition().at_least_rust_2021()
|
&& impl_.self_ty.span.edition().at_least_rust_2021()
|
||||||
{
|
{
|
||||||
// Silence the dyn-compatibility error in favor of the missing dyn on
|
// Silence the dyn-compatibility error in favor of the missing dyn on
|
||||||
|
|
|
@ -3074,7 +3074,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
if let Some(ty) = ty {
|
if let Some(ty) = ty {
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
hir::TyKind::TraitObject(traits, _, _) => {
|
hir::TyKind::TraitObject(traits, _) => {
|
||||||
let (span, kw) = match traits {
|
let (span, kw) = match traits {
|
||||||
[first, ..] if first.span.lo() == ty.span.lo() => {
|
[first, ..] if first.span.lo() == ty.span.lo() => {
|
||||||
// Missing `dyn` in front of trait object.
|
// Missing `dyn` in front of trait object.
|
||||||
|
|
|
@ -1843,10 +1843,10 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
||||||
ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
|
ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
|
||||||
}
|
}
|
||||||
TyKind::Path(_) => clean_qpath(ty, cx),
|
TyKind::Path(_) => clean_qpath(ty, cx),
|
||||||
TyKind::TraitObject(bounds, lifetime, _) => {
|
TyKind::TraitObject(bounds, lifetime) => {
|
||||||
let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect();
|
let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect();
|
||||||
let lifetime =
|
let lifetime =
|
||||||
if !lifetime.is_elided() { Some(clean_lifetime(lifetime, cx)) } else { None };
|
if !lifetime.is_elided() { Some(clean_lifetime(lifetime.pointer(), cx)) } else { None };
|
||||||
DynTrait(bounds, lifetime)
|
DynTrait(bounds, lifetime)
|
||||||
}
|
}
|
||||||
TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
|
TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
|
||||||
|
|
|
@ -433,7 +433,7 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
|
||||||
sub_visitor.visit_fn_decl(decl);
|
sub_visitor.visit_fn_decl(decl);
|
||||||
self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
|
self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
|
||||||
},
|
},
|
||||||
TyKind::TraitObject(bounds, lt, _) => {
|
TyKind::TraitObject(bounds, lt) => {
|
||||||
if !lt.is_elided() {
|
if !lt.is_elided() {
|
||||||
self.unelided_trait_object_lifetime = true;
|
self.unelided_trait_object_lifetime = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
|
||||||
// Originally reported as the issue #3128.
|
// Originally reported as the issue #3128.
|
||||||
let inner_snippet = snippet(cx, inner.span, "..");
|
let inner_snippet = snippet(cx, inner.span, "..");
|
||||||
let suggestion = match &inner.kind {
|
let suggestion = match &inner.kind {
|
||||||
TyKind::TraitObject(bounds, lt_bound, _) if bounds.len() > 1 || !lt_bound.is_elided() => {
|
TyKind::TraitObject(bounds, lt_bound) if bounds.len() > 1 || !lt_bound.is_elided() => {
|
||||||
format!("&{ltopt}({inner_snippet})")
|
format!("&{ltopt}({inner_snippet})")
|
||||||
},
|
},
|
||||||
TyKind::Path(qpath)
|
TyKind::Path(qpath)
|
||||||
|
|
|
@ -52,7 +52,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
|
||||||
// function types bring a lot of overhead
|
// function types bring a lot of overhead
|
||||||
TyKind::BareFn(bare) if bare.abi == Abi::Rust => (50 * self.nest, 1),
|
TyKind::BareFn(bare) if bare.abi == Abi::Rust => (50 * self.nest, 1),
|
||||||
|
|
||||||
TyKind::TraitObject(param_bounds, _, _) => {
|
TyKind::TraitObject(param_bounds, _) => {
|
||||||
let has_lifetime_parameters = param_bounds.iter().any(|bound| {
|
let has_lifetime_parameters = param_bounds.iter().any(|bound| {
|
||||||
bound
|
bound
|
||||||
.bound_generic_params
|
.bound_generic_params
|
||||||
|
|
|
@ -400,7 +400,7 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) {
|
||||||
TyKind::OpaqueDef(..) => (Pat::Str("impl"), Pat::Str("")),
|
TyKind::OpaqueDef(..) => (Pat::Str("impl"), Pat::Str("")),
|
||||||
TyKind::Path(qpath) => qpath_search_pat(&qpath),
|
TyKind::Path(qpath) => qpath_search_pat(&qpath),
|
||||||
TyKind::Infer => (Pat::Str("_"), Pat::Str("_")),
|
TyKind::Infer => (Pat::Str("_"), Pat::Str("_")),
|
||||||
TyKind::TraitObject(_, _, TraitObjectSyntax::Dyn) => (Pat::Str("dyn"), Pat::Str("")),
|
TyKind::TraitObject(_, tagged_ptr) if let TraitObjectSyntax::Dyn = tagged_ptr.tag() => (Pat::Str("dyn"), Pat::Str("")),
|
||||||
// NOTE: `TraitObject` is incomplete. It will always return true then.
|
// NOTE: `TraitObject` is incomplete. It will always return true then.
|
||||||
_ => (Pat::Str(""), Pat::Str("")),
|
_ => (Pat::Str(""), Pat::Str("")),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1281,7 +1281,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TyKind::Path(qpath) => self.hash_qpath(qpath),
|
TyKind::Path(qpath) => self.hash_qpath(qpath),
|
||||||
TyKind::TraitObject(_, lifetime, _) => {
|
TyKind::TraitObject(_, lifetime) => {
|
||||||
self.hash_lifetime(lifetime);
|
self.hash_lifetime(lifetime);
|
||||||
},
|
},
|
||||||
TyKind::Typeof(anon_const) => {
|
TyKind::Typeof(anon_const) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue