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