1use rustc_ast::TraitObjectSyntax;
2use rustc_attr_ir::lang_items::LangItem;
3use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
4use rustc_errors::codes::*;
5use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, Level, struct_span_code_err};
6use rustc_hir::def::{DefKind, Res};
7use rustc_hir::def_id::DefId;
8use rustc_hir::{self as hir, HirId};
9use rustc_lint_defs::builtin::{BARE_TRAIT_OBJECTS, UNUSED_ASSOCIATED_TYPE_BOUNDS};
10use rustc_middle::ty::elaborate::ClauseWithSupertraitSpan;
11use rustc_middle::ty::{
12 self, BottomUpFolder, ExistentialPredicateStableCmpExt as _, IncludeSizedImplicitBounds, Ty,
13 TyCtxt, TypeFoldable, TypeVisitableExt, Upcast,
14};
15use rustc_span::edit_distance::find_best_match_for_name;
16use rustc_span::{ErrorGuaranteed, Span};
17use rustc_trait_selection::diagnostics::AssocTypeWithSameName;
18use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
19use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName;
20use rustc_trait_selection::traits;
21use smallvec::{SmallVec, smallvec};
22use tracing::{debug, instrument};
23
24use super::HirTyLowerer;
25use crate::diagnostics::DynTraitAssocItemBindingMentionsSelf;
26use crate::hir_ty_lowering::{
27 GenericArgCountMismatch, ImpliedBoundsContext, OverlappingAsssocItemConstraints,
28 PredicateFilter, RegionInferReason,
29};
30
31impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
32 {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("lower_trait_object_ty",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(33u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&[],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{ meta.fields().value_set_all(&[]) })
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Ty<'tcx> = loop {};
return __tracing_attr_fake_return;
}
{
let tcx = self.tcx();
let dummy_self = tcx.types.trait_object_dummy_self;
match syntax {
TraitObjectSyntax::Dyn => {}
TraitObjectSyntax::None => {
match self.prohibit_or_lint_bare_trait_object_ty(span,
hir_id, hir_bounds) {
Some(guar) => return Ty::new_error(tcx, guar),
None => {}
}
}
}
let mut user_written_bounds = Vec::new();
let mut potential_assoc_items = Vec::new();
for poly_trait_ref in hir_bounds.iter() {
let result =
self.lower_poly_trait_ref(poly_trait_ref, dummy_self,
&mut user_written_bounds, PredicateFilter::SelfOnly,
OverlappingAsssocItemConstraints::Forbidden);
if let Err(GenericArgCountMismatch { invalid_args, .. }) =
result.correct {
potential_assoc_items.extend(invalid_args);
}
}
self.add_implicit_bounds(&mut user_written_bounds,
dummy_self,
&hir_bounds.iter().map(|&trait_ref|
hir::GenericBound::Trait(trait_ref)).collect::<Vec<_>>(),
ImpliedBoundsContext::AssociatedTypeOrImplTrait, span,
IncludeSizedImplicitBounds::No);
let (mut elaborated_trait_bounds,
elaborated_projection_bounds) =
traits::expand_trait_aliases(tcx,
user_written_bounds.iter().copied());
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:94",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(94u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("user_written_bounds")
}> =
::tracing::__macro_support::FieldName::new("user_written_bounds");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("elaborated_trait_bounds")
}> =
::tracing::__macro_support::FieldName::new("elaborated_trait_bounds");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&user_written_bounds)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&elaborated_trait_bounds)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let meta_sized_did =
tcx.require_lang_item(LangItem::MetaSized, span);
if user_written_bounds.iter().all(|(clause, _)|
clause.as_trait_clause().map(|p| p.def_id()) !=
Some(meta_sized_did)) {
elaborated_trait_bounds.retain(|(pred, _)|
pred.def_id() != meta_sized_did);
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:104",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(104u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("user_written_bounds")
}> =
::tracing::__macro_support::FieldName::new("user_written_bounds");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("elaborated_trait_bounds")
}> =
::tracing::__macro_support::FieldName::new("elaborated_trait_bounds");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&user_written_bounds)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&elaborated_trait_bounds)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) =
elaborated_trait_bounds.into_iter().partition(|(trait_ref,
_)| !tcx.trait_is_auto(trait_ref.def_id()));
if regular_traits.is_empty() && auto_traits.is_empty() {
let guar =
self.report_trait_object_with_no_traits(span,
user_written_bounds.iter().copied());
return Ty::new_error(tcx, guar);
}
if regular_traits.len() > 1 {
let guar =
self.report_trait_object_addition_traits(®ular_traits);
return Ty::new_error(tcx, guar);
}
if let Err(guar) = regular_traits.error_reported() {
return Ty::new_error(tcx, guar);
}
for (clause, span) in user_written_bounds {
if let Some(trait_pred) = clause.as_trait_clause() {
let violations =
self.dyn_compatibility_violations(trait_pred.def_id());
if !violations.is_empty() {
let reported =
report_dyn_incompatibility(tcx, span, Some(hir_id),
trait_pred.def_id(), &violations).emit_err();
return Ty::new_error(tcx, reported);
}
}
}
let mut projection_bounds = FxIndexMap::default();
for (proj, proj_span) in elaborated_projection_bounds {
let item_def_id = proj.item_def_id();
let proj =
proj.map_bound(|mut proj|
{
let references_self =
proj.term.walk().any(|arg| arg == dummy_self.into());
if references_self {
let guar =
self.dcx().emit_err(DynTraitAssocItemBindingMentionsSelf {
span,
kind: tcx.def_descr(item_def_id),
binding: proj_span,
});
proj.term =
replace_dummy_self_with_error(tcx, proj.term, guar);
}
proj
});
let key =
(item_def_id,
tcx.anonymize_bound_vars(proj.map_bound(|proj|
proj.projection_term.trait_ref(tcx))));
if let Some((old_proj, old_proj_span)) =
projection_bounds.insert(key, (proj, proj_span)) &&
tcx.anonymize_bound_vars(proj) !=
tcx.anonymize_bound_vars(old_proj) {
let kind = tcx.def_descr(item_def_id);
let name = tcx.item_name(item_def_id);
self.dcx().struct_span_err(span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("conflicting {0} bindings for `{1}`",
kind, name))
})).with_span_label(old_proj_span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{1}` is specified to be `{0}` here",
old_proj.term(), name))
})).with_span_label(proj_span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{1}` is specified to be `{0}` here",
proj.term(), name))
})).emit();
}
}
let principal_trait = regular_traits.into_iter().next();
let mut ordered_associated_items = ::alloc::vec::Vec::new();
if let Some((principal_trait, ref spans)) = principal_trait
{
let principal_trait =
principal_trait.map_bound(|trait_pred|
{
{
match (&trait_pred.polarity, &ty::ClausePolarity::Positive)
{
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
trait_pred.trait_ref
});
for ClauseWithSupertraitSpan { clause, supertrait_span } in
traits::elaborate(tcx,
[ClauseWithSupertraitSpan::new(ty::TraitRef::identity(tcx,
principal_trait.def_id()).upcast(tcx),
*spans.last().unwrap())]).filter_only_self() {
let clause =
clause.instantiate_supertrait(tcx, principal_trait);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:223",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(223u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("observing object predicate `{0:?}`",
clause) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let bound_predicate = clause.kind();
match bound_predicate.skip_binder() {
ty::ClauseKind::Trait(pred) => {
let trait_ref =
tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
ordered_associated_items.extend(tcx.associated_items(pred.trait_ref.def_id).in_definition_order().filter(|item|
item.can_have_equality_constraint(tcx)).filter(|item|
!item.is_impl_trait_in_trait()).map(|item|
(item.def_id, trait_ref)));
}
ty::ClauseKind::Projection(pred) => {
let pred = bound_predicate.rebind(pred);
let references_self =
pred.skip_binder().term.walk().any(|arg|
arg == dummy_self.into());
if !references_self {
let key =
(pred.item_def_id(),
tcx.anonymize_bound_vars(pred.map_bound(|proj|
proj.projection_term.trait_ref(tcx))));
if !projection_bounds.contains_key(&key) {
projection_bounds.insert(key, (pred, supertrait_span));
}
}
self.check_elaborated_projection_mentions_input_lifetimes(pred,
*spans.first().unwrap(), supertrait_span);
}
_ => (),
}
}
}
for &(projection_bound, span) in projection_bounds.values()
{
let def_id = projection_bound.item_def_id();
if tcx.generics_require_sized_self(def_id) {
tcx.emit_node_span_lint(UNUSED_ASSOCIATED_TYPE_BOUNDS,
hir_id, span,
crate::diagnostics::UnusedAssociatedTypeBounds { span });
}
}
let mut missing_assoc_items = FxIndexSet::default();
let projection_bounds: Vec<_> =
ordered_associated_items.into_iter().filter_map(|key @
(def_id, _)|
{
if let Some(&assoc) = projection_bounds.get(&key) {
return Some(assoc);
}
if !tcx.generics_require_sized_self(def_id) {
missing_assoc_items.insert(key);
}
None
}).collect();
if let Err(guar) =
self.check_for_required_assoc_items(principal_trait.as_ref().map_or(::smallvec::SmallVec::new(),
|(_, spans)| spans.clone()), missing_assoc_items,
potential_assoc_items, hir_bounds) {
return Ty::new_error(tcx, guar);
}
let mut duplicates = FxHashSet::default();
auto_traits.retain(|(trait_pred, _)|
duplicates.insert(trait_pred.def_id()));
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:345",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(345u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("principal_trait")
}> =
::tracing::__macro_support::FieldName::new("principal_trait");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&principal_trait)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:346",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(346u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("auto_traits")
}> =
::tracing::__macro_support::FieldName::new("auto_traits");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&auto_traits)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let principal_trait_ref =
principal_trait.map(|(trait_pred, spans)|
{
trait_pred.map_bound(|trait_pred|
{
let trait_ref = trait_pred.trait_ref;
{
match (&trait_pred.polarity, &ty::ClausePolarity::Positive)
{
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
{
match (&trait_ref.self_ty(), &dummy_self) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
let span = *spans.first().unwrap();
let mut missing_generic_params = Vec::new();
let generics = tcx.generics_of(trait_ref.def_id);
let args: Vec<_> =
trait_ref.args.iter().enumerate().skip(1).map(|(index, arg)|
{
if arg.walk().any(|arg| arg == dummy_self.into()) {
let param = &generics.own_params[index];
missing_generic_params.push((param.name,
param.kind.clone()));
param.to_error(tcx)
} else { arg }
}).collect();
let empty_generic_args =
hir_bounds.iter().any(|hir_bound|
{
hir_bound.trait_ref.path.res ==
Res::Def(DefKind::Trait, trait_ref.def_id) &&
hir_bound.span.contains(span)
});
self.report_missing_generic_params(missing_generic_params,
trait_ref.def_id, span, empty_generic_args);
ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::new(tcx,
trait_ref.def_id, args))
})
});
let existential_projections =
projection_bounds.into_iter().map(|(bound, _)|
{
bound.map_bound(|mut b|
{
{
match (&b.projection_term.self_ty(), &dummy_self) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
let references_self =
b.projection_term.args.iter().skip(1).any(|arg|
arg.walk().any(|arg| arg == dummy_self.into()));
if references_self {
let guar =
tcx.dcx().span_delayed_bug(span,
"trait object projection bounds reference `Self`");
b.projection_term =
replace_dummy_self_with_error(tcx, b.projection_term, guar);
}
ty::ExistentialPredicate::Projection(ty::ExistentialProjection::erase_self_ty(tcx,
b))
})
});
let mut auto_trait_predicates: Vec<_> =
auto_traits.into_iter().map(|(trait_pred, _)|
{
{
match (&trait_pred.polarity(),
&ty::ClausePolarity::Positive) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
{
match (&trait_pred.self_ty().skip_binder(), &dummy_self) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id()))
}).collect();
auto_trait_predicates.dedup();
let mut predicates =
principal_trait_ref.into_iter().chain(existential_projections).chain(auto_trait_predicates).collect::<SmallVec<[_; 8]>>();
predicates.sort_by(|a, b|
a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
let predicates =
tcx.mk_poly_existential_predicates(&predicates);
let region_bound =
self.lower_trait_object_lifetime(lifetime, predicates,
span);
Ty::new_dynamic(tcx, predicates, region_bound)
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:33",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(33u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "debug", skip_all, ret)]
34 pub(super) fn lower_trait_object_ty(
35 &self,
36 span: Span,
37 hir_id: hir::HirId,
38 hir_bounds: &[hir::PolyTraitRef<'_>],
39 lifetime: &hir::Lifetime,
40 syntax: TraitObjectSyntax,
41 ) -> Ty<'tcx> {
42 let tcx = self.tcx();
43 let dummy_self = tcx.types.trait_object_dummy_self;
44
45 match syntax {
46 TraitObjectSyntax::Dyn => {}
47 TraitObjectSyntax::None => {
48 match self.prohibit_or_lint_bare_trait_object_ty(span, hir_id, hir_bounds) {
49 Some(guar) => return Ty::new_error(tcx, guar),
53 None => {}
54 }
55 }
56 }
57
58 let mut user_written_bounds = Vec::new();
59 let mut potential_assoc_items = Vec::new();
60 for poly_trait_ref in hir_bounds.iter() {
61 let result = self.lower_poly_trait_ref(
67 poly_trait_ref,
68 dummy_self,
69 &mut user_written_bounds,
70 PredicateFilter::SelfOnly,
71 OverlappingAsssocItemConstraints::Forbidden,
72 );
73 if let Err(GenericArgCountMismatch { invalid_args, .. }) = result.correct {
74 potential_assoc_items.extend(invalid_args);
75 }
76 }
77
78 self.add_implicit_bounds(
79 &mut user_written_bounds,
80 dummy_self,
81 &hir_bounds
82 .iter()
83 .map(|&trait_ref| hir::GenericBound::Trait(trait_ref))
84 .collect::<Vec<_>>(),
85 ImpliedBoundsContext::AssociatedTypeOrImplTrait,
86 span,
87 IncludeSizedImplicitBounds::No,
88 );
89
90 let (mut elaborated_trait_bounds, elaborated_projection_bounds) =
91 traits::expand_trait_aliases(tcx, user_written_bounds.iter().copied());
92
93 debug!(?user_written_bounds, ?elaborated_trait_bounds);
95 let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span);
96 if user_written_bounds
99 .iter()
100 .all(|(clause, _)| clause.as_trait_clause().map(|p| p.def_id()) != Some(meta_sized_did))
101 {
102 elaborated_trait_bounds.retain(|(pred, _)| pred.def_id() != meta_sized_did);
103 }
104 debug!(?user_written_bounds, ?elaborated_trait_bounds);
105
106 let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = elaborated_trait_bounds
107 .into_iter()
108 .partition(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
109
110 if regular_traits.is_empty() && auto_traits.is_empty() {
112 let guar =
113 self.report_trait_object_with_no_traits(span, user_written_bounds.iter().copied());
114 return Ty::new_error(tcx, guar);
115 }
116 if regular_traits.len() > 1 {
118 let guar = self.report_trait_object_addition_traits(®ular_traits);
119 return Ty::new_error(tcx, guar);
120 }
121 if let Err(guar) = regular_traits.error_reported() {
123 return Ty::new_error(tcx, guar);
124 }
125
126 for (clause, span) in user_written_bounds {
130 if let Some(trait_pred) = clause.as_trait_clause() {
131 let violations = self.dyn_compatibility_violations(trait_pred.def_id());
132 if !violations.is_empty() {
133 let reported = report_dyn_incompatibility(
134 tcx,
135 span,
136 Some(hir_id),
137 trait_pred.def_id(),
138 &violations,
139 )
140 .emit_err();
141 return Ty::new_error(tcx, reported);
142 }
143 }
144 }
145
146 let mut projection_bounds = FxIndexMap::default();
156 for (proj, proj_span) in elaborated_projection_bounds {
157 let item_def_id = proj.item_def_id();
158
159 let proj = proj.map_bound(|mut proj| {
160 let references_self = proj.term.walk().any(|arg| arg == dummy_self.into());
161 if references_self {
162 let guar = self.dcx().emit_err(DynTraitAssocItemBindingMentionsSelf {
163 span,
164 kind: tcx.def_descr(item_def_id),
165 binding: proj_span,
166 });
167 proj.term = replace_dummy_self_with_error(tcx, proj.term, guar);
168 }
169 proj
170 });
171
172 let key = (
173 item_def_id,
174 tcx.anonymize_bound_vars(
175 proj.map_bound(|proj| proj.projection_term.trait_ref(tcx)),
176 ),
177 );
178 if let Some((old_proj, old_proj_span)) =
179 projection_bounds.insert(key, (proj, proj_span))
180 && tcx.anonymize_bound_vars(proj) != tcx.anonymize_bound_vars(old_proj)
181 {
182 let kind = tcx.def_descr(item_def_id);
183 let name = tcx.item_name(item_def_id);
184 self.dcx()
185 .struct_span_err(span, format!("conflicting {kind} bindings for `{name}`"))
186 .with_span_label(
187 old_proj_span,
188 format!("`{name}` is specified to be `{}` here", old_proj.term()),
189 )
190 .with_span_label(
191 proj_span,
192 format!("`{name}` is specified to be `{}` here", proj.term()),
193 )
194 .emit();
195 }
196 }
197
198 let principal_trait = regular_traits.into_iter().next();
199
200 let mut ordered_associated_items = vec![];
206
207 if let Some((principal_trait, ref spans)) = principal_trait {
208 let principal_trait = principal_trait.map_bound(|trait_pred| {
209 assert_eq!(trait_pred.polarity, ty::ClausePolarity::Positive);
210 trait_pred.trait_ref
211 });
212
213 for ClauseWithSupertraitSpan { clause, supertrait_span } in traits::elaborate(
214 tcx,
215 [ClauseWithSupertraitSpan::new(
216 ty::TraitRef::identity(tcx, principal_trait.def_id()).upcast(tcx),
217 *spans.last().unwrap(),
218 )],
219 )
220 .filter_only_self()
221 {
222 let clause = clause.instantiate_supertrait(tcx, principal_trait);
223 debug!("observing object predicate `{clause:?}`");
224
225 let bound_predicate = clause.kind();
226 match bound_predicate.skip_binder() {
227 ty::ClauseKind::Trait(pred) => {
228 let trait_ref =
230 tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
231 ordered_associated_items.extend(
232 tcx.associated_items(pred.trait_ref.def_id)
233 .in_definition_order()
234 .filter(|item| item.can_have_equality_constraint(tcx))
235 .filter(|item| !item.is_impl_trait_in_trait())
237 .map(|item| (item.def_id, trait_ref)),
238 );
239 }
240 ty::ClauseKind::Projection(pred) => {
241 let pred = bound_predicate.rebind(pred);
242 let references_self =
245 pred.skip_binder().term.walk().any(|arg| arg == dummy_self.into());
246
247 if !references_self {
265 let key = (
266 pred.item_def_id(),
267 tcx.anonymize_bound_vars(
268 pred.map_bound(|proj| proj.projection_term.trait_ref(tcx)),
269 ),
270 );
271 if !projection_bounds.contains_key(&key) {
272 projection_bounds.insert(key, (pred, supertrait_span));
273 }
274 }
275
276 self.check_elaborated_projection_mentions_input_lifetimes(
277 pred,
278 *spans.first().unwrap(),
279 supertrait_span,
280 );
281 }
282 _ => (),
283 }
284 }
285 }
286
287 for &(projection_bound, span) in projection_bounds.values() {
289 let def_id = projection_bound.item_def_id();
290 if tcx.generics_require_sized_self(def_id) {
291 tcx.emit_node_span_lint(
295 UNUSED_ASSOCIATED_TYPE_BOUNDS,
296 hir_id,
297 span,
298 crate::diagnostics::UnusedAssociatedTypeBounds { span },
299 );
300 }
301 }
302
303 let mut missing_assoc_items = FxIndexSet::default();
315 let projection_bounds: Vec<_> = ordered_associated_items
316 .into_iter()
317 .filter_map(|key @ (def_id, _)| {
318 if let Some(&assoc) = projection_bounds.get(&key) {
319 return Some(assoc);
320 }
321 if !tcx.generics_require_sized_self(def_id) {
322 missing_assoc_items.insert(key);
323 }
324 None
325 })
326 .collect();
327
328 if let Err(guar) = self.check_for_required_assoc_items(
330 principal_trait.as_ref().map_or(smallvec![], |(_, spans)| spans.clone()),
331 missing_assoc_items,
332 potential_assoc_items,
333 hir_bounds,
334 ) {
335 return Ty::new_error(tcx, guar);
336 }
337
338 let mut duplicates = FxHashSet::default();
343 auto_traits.retain(|(trait_pred, _)| duplicates.insert(trait_pred.def_id()));
344
345 debug!(?principal_trait);
346 debug!(?auto_traits);
347
348 let principal_trait_ref = principal_trait.map(|(trait_pred, spans)| {
350 trait_pred.map_bound(|trait_pred| {
351 let trait_ref = trait_pred.trait_ref;
352 assert_eq!(trait_pred.polarity, ty::ClausePolarity::Positive);
353 assert_eq!(trait_ref.self_ty(), dummy_self);
354
355 let span = *spans.first().unwrap();
356
357 let mut missing_generic_params = Vec::new();
360 let generics = tcx.generics_of(trait_ref.def_id);
361 let args: Vec<_> = trait_ref
362 .args
363 .iter()
364 .enumerate()
365 .skip(1)
367 .map(|(index, arg)| {
368 if arg.walk().any(|arg| arg == dummy_self.into()) {
369 let param = &generics.own_params[index];
370 missing_generic_params.push((param.name, param.kind.clone()));
371 param.to_error(tcx)
372 } else {
373 arg
374 }
375 })
376 .collect();
377
378 let empty_generic_args = hir_bounds.iter().any(|hir_bound| {
379 hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
380 && hir_bound.span.contains(span)
381 });
382 self.report_missing_generic_params(
383 missing_generic_params,
384 trait_ref.def_id,
385 span,
386 empty_generic_args,
387 );
388
389 ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::new(
390 tcx,
391 trait_ref.def_id,
392 args,
393 ))
394 })
395 });
396
397 let existential_projections = projection_bounds.into_iter().map(|(bound, _)| {
398 bound.map_bound(|mut b| {
399 assert_eq!(b.projection_term.self_ty(), dummy_self);
400
401 let references_self = b
404 .projection_term
405 .args
406 .iter()
407 .skip(1)
408 .any(|arg| arg.walk().any(|arg| arg == dummy_self.into()));
409 if references_self {
410 let guar = tcx
411 .dcx()
412 .span_delayed_bug(span, "trait object projection bounds reference `Self`");
413 b.projection_term = replace_dummy_self_with_error(tcx, b.projection_term, guar);
414 }
415
416 ty::ExistentialPredicate::Projection(ty::ExistentialProjection::erase_self_ty(
417 tcx, b,
418 ))
419 })
420 });
421
422 let mut auto_trait_predicates: Vec<_> = auto_traits
423 .into_iter()
424 .map(|(trait_pred, _)| {
425 assert_eq!(trait_pred.polarity(), ty::ClausePolarity::Positive);
426 assert_eq!(trait_pred.self_ty().skip_binder(), dummy_self);
427
428 ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id()))
429 })
430 .collect();
431 auto_trait_predicates.dedup();
432
433 let mut predicates = principal_trait_ref
436 .into_iter()
437 .chain(existential_projections)
438 .chain(auto_trait_predicates)
439 .collect::<SmallVec<[_; 8]>>();
440 predicates.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
441 let predicates = tcx.mk_poly_existential_predicates(&predicates);
442
443 let region_bound = self.lower_trait_object_lifetime(lifetime, predicates, span);
444
445 Ty::new_dynamic(tcx, predicates, region_bound)
446 }
447
448 fn lower_trait_object_lifetime(
449 &self,
450 lifetime: &hir::Lifetime,
451 predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
452 span: Span,
453 ) -> ty::Region<'tcx> {
454 if let hir::LifetimeKind::ImplicitObjectLifetimeDefault | hir::LifetimeKind::Infer =
457 lifetime.kind
458 && let Some(region) = self.compute_object_lifetime_bound(span, predicates)
459 {
460 return region;
461 }
462
463 let reason = if let hir::LifetimeKind::ImplicitObjectLifetimeDefault = lifetime.kind {
464 RegionInferReason::ObjectLifetimeDefault(span.shrink_to_hi())
465 } else {
466 RegionInferReason::ExplicitObjectLifetime
467 };
468
469 self.lower_lifetime(lifetime, reason)
470 }
471
472 fn check_elaborated_projection_mentions_input_lifetimes(
477 &self,
478 pred: ty::PolyProjectionClause<'tcx>,
479 span: Span,
480 supertrait_span: Span,
481 ) {
482 let tcx = self.tcx();
483
484 let late_bound_in_projection_term =
492 tcx.collect_constrained_late_bound_regions(pred.map_bound(|pred| pred.projection_term));
493 let late_bound_in_term =
494 tcx.collect_referenced_late_bound_regions(pred.map_bound(|pred| pred.term));
495 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:495",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(495u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("late_bound_in_projection_term")
}> =
::tracing::__macro_support::FieldName::new("late_bound_in_projection_term");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&late_bound_in_projection_term)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?late_bound_in_projection_term);
496 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:496",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(496u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("late_bound_in_term")
}> =
::tracing::__macro_support::FieldName::new("late_bound_in_term");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&late_bound_in_term)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?late_bound_in_term);
497
498 self.validate_late_bound_regions(
503 late_bound_in_projection_term,
504 late_bound_in_term,
505 |br_name| {
506 let item_name = tcx.item_name(pred.item_def_id());
507 {
self.dcx().struct_span_err(span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("binding for associated type `{0}` references {1}, which does not appear in the trait input types",
item_name, br_name))
})).with_code(E0582)
}struct_span_code_err!(
508 self.dcx(),
509 span,
510 E0582,
511 "binding for associated type `{}` references {}, \
512 which does not appear in the trait input types",
513 item_name,
514 br_name
515 )
516 .with_span_label(supertrait_span, "due to this supertrait")
517 },
518 );
519 }
520
521 {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("compute_object_lifetime_bound",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(528u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("existential_predicates")
}> =
::tracing::__macro_support::FieldName::new("existential_predicates");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&existential_predicates)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Option<ty::Region<'tcx>> =
loop {};
return __tracing_attr_fake_return;
}
{
let tcx = self.tcx();
let derived_region_bounds =
traits::wf::object_region_bounds(tcx,
existential_predicates);
if derived_region_bounds.is_empty() { return None; }
if derived_region_bounds.iter().any(|r| r.is_static()) {
return Some(tcx.lifetimes.re_static);
}
let r = derived_region_bounds[0];
if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
self.dcx().emit_err(crate::diagnostics::AmbiguousLifetimeBound {
span,
});
}
Some(r)
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs:528",
"rustc_hir_analysis::hir_ty_lowering::dyn_trait",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs"),
::tracing_core::__macro_support::Option::Some(528u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::hir_ty_lowering::dyn_trait"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "debug", skip(self, span), ret)]
529 fn compute_object_lifetime_bound(
530 &self,
531 span: Span,
532 existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
533 ) -> Option<ty::Region<'tcx>> {
535 let tcx = self.tcx();
536
537 let derived_region_bounds = traits::wf::object_region_bounds(tcx, existential_predicates);
540
541 if derived_region_bounds.is_empty() {
544 return None;
545 }
546
547 if derived_region_bounds.iter().any(|r| r.is_static()) {
550 return Some(tcx.lifetimes.re_static);
551 }
552
553 let r = derived_region_bounds[0];
557 if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
558 self.dcx().emit_err(crate::diagnostics::AmbiguousLifetimeBound { span });
559 }
560 Some(r)
561 }
562
563 fn prohibit_or_lint_bare_trait_object_ty(
568 &self,
569 span: Span,
570 hir_id: hir::HirId,
571 hir_bounds: &[hir::PolyTraitRef<'_>],
572 ) -> Option<ErrorGuaranteed> {
573 struct TraitObjectWithoutDyn<'a, 'tcx> {
574 span: Span,
575 hir_id: HirId,
576 sugg: Vec<(Span, String)>,
577 this: &'a dyn HirTyLowerer<'tcx>,
578 }
579
580 impl<'a, 'b, 'tcx> Diagnostic<'a> for TraitObjectWithoutDyn<'b, 'tcx> {
581 fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a> {
582 let Self { span, hir_id, sugg, this } = self;
583 let mut lint =
584 Diag::new(dcx, level, "trait objects without an explicit `dyn` are deprecated");
585 if span.can_be_used_for_suggestions() {
586 lint.multipart_suggestion(
587 "if this is a dyn-compatible trait, use `dyn`",
588 sugg,
589 Applicability::MachineApplicable,
590 );
591 }
592 this.maybe_suggest_blanket_trait_impl(span, hir_id, &mut lint);
593 lint
594 }
595 }
596
597 let tcx = self.tcx();
598 let [poly_trait_ref, ..] = hir_bounds else { return None };
599
600 let in_path = match tcx.parent_hir_node(hir_id).path() {
601 Some(hir::QPath::TypeRelative(qself, _)) if qself.hir_id == hir_id => true,
602 _ => false,
603 };
604 let needs_bracket = in_path
605 && !tcx
606 .sess
607 .source_map()
608 .span_to_prev_source(span)
609 .ok()
610 .is_some_and(|s| s.trim_end().ends_with('<'));
611
612 let is_global = poly_trait_ref.trait_ref.path.is_global();
613
614 let mut sugg = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[(span.shrink_to_lo(),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}dyn {1}",
if needs_bracket { "<" } else { "" },
if is_global { "(" } else { "" }))
}))]))vec![(
615 span.shrink_to_lo(),
616 format!(
617 "{}dyn {}",
618 if needs_bracket { "<" } else { "" },
619 if is_global { "(" } else { "" },
620 ),
621 )];
622
623 if is_global || needs_bracket {
624 sugg.push((
625 span.shrink_to_hi(),
626 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}",
if is_global { ")" } else { "" },
if needs_bracket { ">" } else { "" }))
})format!(
627 "{}{}",
628 if is_global { ")" } else { "" },
629 if needs_bracket { ">" } else { "" },
630 ),
631 ));
632 }
633
634 if span.edition().at_least_rust_2021() {
635 let mut diag = {
self.dcx().struct_span_err(span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}",
"expected a type, found a trait"))
})).with_code(E0782)
}rustc_errors::struct_span_code_err!(
636 self.dcx(),
637 span,
638 E0782,
639 "{}",
640 "expected a type, found a trait"
641 );
642 if span.can_be_used_for_suggestions()
643 && poly_trait_ref.trait_ref.trait_def_id().is_some()
644 && !self.maybe_suggest_impl_trait(span, hir_id, hir_bounds, &mut diag)
645 && !self.maybe_suggest_dyn_trait(hir_id, span, sugg, &mut diag)
646 {
647 self.maybe_suggest_add_generic_impl_trait(span, hir_id, &mut diag);
648 }
649 self.maybe_suggest_blanket_trait_impl(span, hir_id, &mut diag);
651 self.maybe_suggest_assoc_ty_bound(hir_id, &mut diag);
652 self.maybe_suggest_typoed_method(
653 hir_id,
654 poly_trait_ref.trait_ref.trait_def_id(),
655 &mut diag,
656 );
657 if self
659 .tcx()
660 .resolutions(())
661 .paths_matching_assoc_types
662 .contains(&span.with_parent(None))
663 {
664 diag.subdiagnostic(AssocTypeWithSameName { span: span.shrink_to_lo() });
665 }
666 Some(diag.emit_err())
667 } else {
668 tcx.emit_node_span_lint(
669 BARE_TRAIT_OBJECTS,
670 hir_id,
671 span,
672 TraitObjectWithoutDyn { span, hir_id, sugg, this: self },
673 );
674 None
675 }
676 }
677
678 fn maybe_suggest_add_generic_impl_trait(
681 &self,
682 span: Span,
683 hir_id: hir::HirId,
684 diag: &mut Diag<'_>,
685 ) -> bool {
686 let tcx = self.tcx();
687
688 let parent_hir_id = tcx.parent_hir_id(hir_id);
689 let parent_item = tcx.hir_get_parent_item(hir_id).def_id;
690
691 let generics = match tcx.hir_node_by_def_id(parent_item) {
692 hir::Node::Item(hir::Item {
693 kind: hir::ItemKind::Struct(_, generics, variant),
694 ..
695 }) => {
696 if !variant.fields().iter().any(|field| field.hir_id == parent_hir_id) {
697 return false;
698 }
699 generics
700 }
701 hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(_, generics, def), .. }) => {
702 if !def
703 .variants
704 .iter()
705 .flat_map(|variant| variant.data.fields().iter())
706 .any(|field| field.hir_id == parent_hir_id)
707 {
708 return false;
709 }
710 generics
711 }
712 _ => return false,
713 };
714
715 let Ok(rendered_ty) = tcx.sess.source_map().span_to_snippet(span) else {
716 return false;
717 };
718
719 let param = "TUV"
720 .chars()
721 .map(|c| c.to_string())
722 .chain((0..).map(|i| ::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("P{0}", i)) })format!("P{i}")))
723 .find(|s| !generics.params.iter().any(|param| param.name.ident().as_str() == s))
724 .expect("we definitely can find at least one param name to generate");
725 let mut sugg = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[(span, param.to_string())]))vec![(span, param.to_string())];
726 if let Some(insertion_span) = generics.span_for_param_suggestion() {
727 sugg.push((insertion_span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(", {1}: {0}", rendered_ty, param))
})format!(", {param}: {}", rendered_ty)));
728 } else {
729 sugg.push((generics.where_clause_span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("<{1}: {0}>", rendered_ty, param))
})format!("<{param}: {}>", rendered_ty)));
730 }
731 diag.multipart_suggestion(
732 "you might be missing a type parameter",
733 sugg,
734 Applicability::MachineApplicable,
735 );
736 true
737 }
738
739 fn maybe_suggest_blanket_trait_impl(
741 &self,
742 span: Span,
743 hir_id: hir::HirId,
744 diag: &mut Diag<'_>,
745 ) {
746 let tcx = self.tcx();
747 let parent_id = tcx.hir_get_parent_item(hir_id).def_id;
748 if let hir::Node::Item(hir::Item {
749 kind: hir::ItemKind::Impl(hir::Impl { self_ty: impl_self_ty, of_trait, generics, .. }),
750 ..
751 }) = tcx.hir_node_by_def_id(parent_id)
752 && hir_id == impl_self_ty.hir_id
753 {
754 let Some(of_trait) = of_trait else {
755 diag.span_suggestion_verbose(
756 impl_self_ty.span.shrink_to_hi(),
757 "you might have intended to implement this trait for a given type",
758 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" for /* Type */"))
})format!(" for /* Type */"),
759 Applicability::HasPlaceholders,
760 );
761 return;
762 };
763 if !of_trait.trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
764 return;
765 }
766 let of_trait_span = of_trait.trait_ref.path.span;
767 let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else {
769 return;
770 };
771
772 let Ok(impl_trait_name) = self.tcx().sess.source_map().span_to_snippet(span) else {
773 return;
774 };
775 let sugg = self.add_generic_param_suggestion(generics, span, &impl_trait_name);
776 diag.multipart_suggestion(
777 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("alternatively use a blanket implementation to implement `{0}` for all types that also implement `{1}`",
of_trait_name, impl_trait_name))
})format!(
778 "alternatively use a blanket implementation to implement `{of_trait_name}` for \
779 all types that also implement `{impl_trait_name}`"
780 ),
781 sugg,
782 Applicability::MaybeIncorrect,
783 );
784 }
785 }
786
787 fn maybe_suggest_dyn_trait(
795 &self,
796 hir_id: hir::HirId,
797 span: Span,
798 sugg: Vec<(Span, String)>,
799 diag: &mut Diag<'_>,
800 ) -> bool {
801 let tcx = self.tcx();
802 if span.in_derive_expansion() {
803 return false;
804 }
805
806 match tcx.parent_hir_node(hir_id) {
809 hir::Node::Ty(_)
815 | hir::Node::Expr(_)
816 | hir::Node::PatExpr(_)
817 | hir::Node::PathSegment(_)
818 | hir::Node::AssocItemConstraint(_)
819 | hir::Node::TraitRef(_)
820 | hir::Node::Item(_)
821 | hir::Node::WherePredicate(_) => {}
822
823 hir::Node::Field(field) => {
824 if let hir::Node::Item(hir::Item {
826 kind: hir::ItemKind::Struct(_, _, variant), ..
827 }) = tcx.parent_hir_node(field.hir_id)
828 && variant
829 .fields()
830 .last()
831 .is_some_and(|tail_field| tail_field.hir_id == field.hir_id)
832 {
833 } else {
835 return false;
836 }
837 }
838 _ => return false,
839 }
840
841 diag.multipart_suggestion(
843 "you can add the `dyn` keyword if you want a trait object",
844 sugg,
845 Applicability::MachineApplicable,
846 );
847 true
848 }
849
850 fn add_generic_param_suggestion(
851 &self,
852 generics: &hir::Generics<'_>,
853 self_ty_span: Span,
854 impl_trait_name: &str,
855 ) -> Vec<(Span, String)> {
856 let param_name = generics.params.next_type_param_name(None);
858
859 let add_generic_sugg = if let Some(span) = generics.span_for_param_suggestion() {
860 (span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(", {0}: {1}", param_name,
impl_trait_name))
})format!(", {param_name}: {impl_trait_name}"))
861 } else {
862 (generics.span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("<{0}: {1}>", param_name,
impl_trait_name))
})format!("<{param_name}: {impl_trait_name}>"))
863 };
864 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[(self_ty_span, param_name), add_generic_sugg]))vec![(self_ty_span, param_name), add_generic_sugg]
865 }
866
867 fn maybe_suggest_impl_trait(
869 &self,
870 span: Span,
871 hir_id: hir::HirId,
872 hir_bounds: &[hir::PolyTraitRef<'_>],
873 diag: &mut Diag<'_>,
874 ) -> bool {
875 let tcx = self.tcx();
876 let parent_id = tcx.hir_get_parent_item(hir_id).def_id;
877 let (sig, generics) = match tcx.hir_node_by_def_id(parent_id) {
884 hir::Node::Item(hir::Item {
885 kind: hir::ItemKind::Fn { sig, generics, .. }, ..
886 }) => (sig, generics),
887 hir::Node::TraitItem(hir::TraitItem {
888 kind: hir::TraitItemKind::Fn(sig, _),
889 generics,
890 ..
891 }) => (sig, generics),
892 hir::Node::ImplItem(hir::ImplItem {
893 kind: hir::ImplItemKind::Fn(sig, _),
894 generics,
895 ..
896 }) => (sig, generics),
897 _ => return false,
898 };
899 let Ok(trait_name) = tcx.sess.source_map().span_to_snippet(span) else {
900 return false;
901 };
902 let impl_sugg = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[(span.shrink_to_lo(), "impl ".to_string())]))vec![(span.shrink_to_lo(), "impl ".to_string())];
903 let is_dyn_compatible = hir_bounds.iter().all(|bound| match bound.trait_ref.path.res {
905 Res::Def(DefKind::Trait, id) => tcx.is_dyn_compatible(id),
906 _ => false,
907 });
908
909 let borrowed = #[allow(non_exhaustive_omitted_patterns)] match tcx.parent_hir_node(hir_id) {
hir::Node::Ty(hir::Ty { kind: hir::TyKind::Ref(..), .. }) => true,
_ => false,
}matches!(
910 tcx.parent_hir_node(hir_id),
911 hir::Node::Ty(hir::Ty { kind: hir::TyKind::Ref(..), .. })
912 );
913
914 if let hir::FnRetTy::Return(ty) = sig.decl.output
916 && ty.peel_refs().hir_id == hir_id
917 {
918 let pre = if !is_dyn_compatible {
919 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}` is dyn-incompatible, ",
trait_name))
})format!("`{trait_name}` is dyn-incompatible, ")
920 } else {
921 String::new()
922 };
923 let msg = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}use `impl {1}` to return an opaque type, as long as you return a single underlying type",
pre, trait_name))
})format!(
924 "{pre}use `impl {trait_name}` to return an opaque type, as long as you return a \
925 single underlying type",
926 );
927
928 diag.multipart_suggestion(msg, impl_sugg, Applicability::MachineApplicable);
929
930 if is_dyn_compatible {
932 let suggestion = if borrowed {
936 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[(ty.span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Box<dyn {0}>",
trait_name))
}))]))vec![(ty.span, format!("Box<dyn {trait_name}>"))]
937 } else {
938 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[(ty.span.shrink_to_lo(), "Box<dyn ".to_string()),
(ty.span.shrink_to_hi(), ">".to_string())]))vec![
939 (ty.span.shrink_to_lo(), "Box<dyn ".to_string()),
940 (ty.span.shrink_to_hi(), ">".to_string()),
941 ]
942 };
943
944 diag.multipart_suggestion(
945 "alternatively, you can return an owned trait object",
946 suggestion,
947 Applicability::MachineApplicable,
948 );
949 }
950 return true;
951 }
952
953 for ty in sig.decl.inputs {
955 if ty.peel_refs().hir_id != hir_id {
956 continue;
957 }
958 let sugg = self.add_generic_param_suggestion(generics, span, &trait_name);
959 diag.multipart_suggestion(
960 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("use a new generic type parameter, constrained by `{0}`",
trait_name))
})format!("use a new generic type parameter, constrained by `{trait_name}`"),
961 sugg,
962 Applicability::MachineApplicable,
963 );
964 diag.multipart_suggestion(
965 "you can also use an opaque type, but users won't be able to specify the type \
966 parameter when calling the `fn`, having to rely exclusively on type inference",
967 impl_sugg,
968 Applicability::MachineApplicable,
969 );
970 if !is_dyn_compatible {
971 diag.note(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}` is dyn-incompatible, otherwise a trait object could be used",
trait_name))
})format!(
972 "`{trait_name}` is dyn-incompatible, otherwise a trait object could be used"
973 ));
974 } else {
975 let (dyn_str, paren_dyn_str) =
977 if borrowed { ("dyn ", "(dyn ") } else { ("&dyn ", "&(dyn ") };
978
979 let sugg = if let [_, _, ..] = hir_bounds {
980 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[(span.shrink_to_lo(), paren_dyn_str.to_string()),
(span.shrink_to_hi(), ")".to_string())]))vec![
982 (span.shrink_to_lo(), paren_dyn_str.to_string()),
983 (span.shrink_to_hi(), ")".to_string()),
984 ]
985 } else {
986 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[(span.shrink_to_lo(), dyn_str.to_string())]))vec![(span.shrink_to_lo(), dyn_str.to_string())]
987 };
988 diag.multipart_suggestion(
989 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("alternatively, use a trait object to accept any type that implements `{0}`, accessing its methods at runtime using dynamic dispatch",
trait_name))
})format!(
990 "alternatively, use a trait object to accept any type that implements \
991 `{trait_name}`, accessing its methods at runtime using dynamic dispatch",
992 ),
993 sugg,
994 Applicability::MachineApplicable,
995 );
996 }
997 return true;
998 }
999 false
1000 }
1001
1002 fn maybe_suggest_assoc_ty_bound(&self, hir_id: hir::HirId, diag: &mut Diag<'_>) {
1003 let mut parents = self.tcx().hir_parent_iter(hir_id);
1004
1005 if let Some((c_hir_id, hir::Node::AssocItemConstraint(constraint))) = parents.next()
1006 && let Some(obj_ty) = constraint.ty()
1007 && let Some((_, hir::Node::TraitRef(trait_ref))) = parents.next()
1008 {
1009 if let Some((_, hir::Node::Ty(ty))) = parents.next()
1010 && let hir::TyKind::TraitObject(..) = ty.kind
1011 {
1012 return;
1014 }
1015
1016 if trait_ref
1017 .path
1018 .segments
1019 .iter()
1020 .find_map(|seg| {
1021 seg.args.filter(|args| args.constraints.iter().any(|c| c.hir_id == c_hir_id))
1022 })
1023 .is_none_or(|args| args.parenthesized != hir::GenericArgsParentheses::No)
1024 {
1025 return;
1027 }
1028
1029 let lo = if constraint.gen_args.span_ext.is_dummy() {
1030 constraint.ident.span
1031 } else {
1032 constraint.gen_args.span_ext
1033 };
1034 let hi = obj_ty.span;
1035
1036 if lo.ctxt() != hi.ctxt() {
1037 return;
1038 }
1039
1040 diag.span_suggestion_verbose(
1041 lo.between(hi),
1042 "you might have meant to write a bound here",
1043 ": ",
1044 Applicability::MaybeIncorrect,
1045 );
1046 }
1047 }
1048
1049 fn maybe_suggest_typoed_method(
1050 &self,
1051 hir_id: hir::HirId,
1052 trait_def_id: Option<DefId>,
1053 diag: &mut Diag<'_>,
1054 ) {
1055 let tcx = self.tcx();
1056 let Some(trait_def_id) = trait_def_id else {
1057 return;
1058 };
1059 let hir::Node::Expr(hir::Expr {
1060 kind: hir::ExprKind::Path(hir::QPath::TypeRelative(path_ty, segment)),
1061 ..
1062 }) = tcx.parent_hir_node(hir_id)
1063 else {
1064 return;
1065 };
1066 if path_ty.hir_id != hir_id {
1067 return;
1068 }
1069 let names: Vec<_> = tcx
1070 .associated_items(trait_def_id)
1071 .in_definition_order()
1072 .filter(|assoc| assoc.namespace() == hir::def::Namespace::ValueNS)
1073 .map(|cand| cand.name())
1074 .collect();
1075 if let Some(typo) = find_best_match_for_name(&names, segment.ident.name, None) {
1076 diag.span_suggestion_verbose(
1077 segment.ident.span,
1078 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("you may have misspelled this associated item, causing `{0}` to be interpreted as a type rather than a trait",
tcx.item_name(trait_def_id)))
})format!(
1079 "you may have misspelled this associated item, causing `{}` \
1080 to be interpreted as a type rather than a trait",
1081 tcx.item_name(trait_def_id),
1082 ),
1083 typo,
1084 Applicability::MaybeIncorrect,
1085 );
1086 } else {
1087 diag.span_label(
1088 segment.ident.span,
1089 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("not an associated item of trait `{0}`, so `{0}` is interpreted as a type",
tcx.item_name(trait_def_id)))
})format!(
1090 "not an associated item of trait `{trait_name}`, so `{trait_name}` is \
1091 interpreted as a type",
1092 trait_name = tcx.item_name(trait_def_id),
1093 ),
1094 );
1095 }
1096 }
1097}
1098
1099fn replace_dummy_self_with_error<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
1100 tcx: TyCtxt<'tcx>,
1101 t: T,
1102 guar: ErrorGuaranteed,
1103) -> T {
1104 t.fold_with(&mut BottomUpFolder {
1105 tcx,
1106 ty_op: |ty| {
1107 if ty == tcx.types.trait_object_dummy_self { Ty::new_error(tcx, guar) } else { ty }
1108 },
1109 lt_op: |lt| lt,
1110 ct_op: |ct| ct,
1111 })
1112}