1use std::collections::BTreeMap;
5
6use rustc_attr_ir::lang_items::LangItem;
7use rustc_data_structures::fx::FxHashSet;
8use rustc_errors::{ErrorGuaranteed, MultiSpan};
9use rustc_hir as hir;
10use rustc_hir::ItemKind;
11use rustc_hir::def_id::{DefId, LocalDefId};
12use rustc_infer::infer::{self, InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt};
13use rustc_infer::traits::{Obligation, TraitErrors};
14use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
15use rustc_middle::ty::print::PrintTraitRefExt as _;
16use rustc_middle::ty::{
17 self, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized, suggest_constraining_type_params,
18};
19use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
20use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
21use rustc_trait_selection::traits::misc::{
22 ConstParamTyImplementationError, CopyImplementationError, InfringingFieldsReason,
23 type_allowed_to_implement_const_param_ty, type_allowed_to_implement_copy,
24};
25use rustc_trait_selection::traits::{self, ObligationCause, ObligationCtxt};
26use tracing::debug;
27
28use crate::diagnostics;
29
30mod coerce_shared;
31
32pub(super) fn check_trait<'tcx>(
33 tcx: TyCtxt<'tcx>,
34 trait_def_id: DefId,
35 impl_def_id: LocalDefId,
36 impl_header: ty::ImplTraitHeader<'tcx>,
37) -> Result<(), ErrorGuaranteed> {
38 let checker = Checker { tcx, impl_def_id, impl_header };
39 match tcx.as_lang_item(trait_def_id) {
40 Some(LangItem::Drop) => visit_implementation_of_drop(&checker),
41 Some(LangItem::AsyncDrop) => visit_implementation_of_drop(&checker),
42 Some(LangItem::Copy) => visit_implementation_of_copy(&checker),
43 Some(LangItem::Unpin) => visit_implementation_of_unpin(&checker),
44 Some(LangItem::ConstParamTy) => visit_implementation_of_const_param_ty(&checker),
45 Some(LangItem::CoerceUnsized) => visit_implementation_of_coerce_unsized(&checker),
46 Some(LangItem::Reborrow) => visit_implementation_of_reborrow(&checker),
47 Some(LangItem::CoerceShared) => visit_implementation_of_coerce_shared(&checker),
48 Some(LangItem::DispatchFromDyn) => visit_implementation_of_dispatch_from_dyn(&checker),
49 Some(LangItem::CoercePointeeValidated) => {
50 visit_implementation_of_coerce_pointee_validity(&checker)
51 }
52 _ => Ok(()),
53 }
54}
55
56struct Checker<'tcx> {
57 tcx: TyCtxt<'tcx>,
58 impl_def_id: LocalDefId,
59 impl_header: ty::ImplTraitHeader<'tcx>,
60}
61
62fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
63 let tcx = checker.tcx;
64 let impl_did = checker.impl_def_id;
65 match checker.impl_header.trait_ref.instantiate_identity().skip_norm_wip().self_ty().kind() {
67 ty::Adt(def, _) if def.did().is_local() => return Ok(()),
68 ty::Error(_) => return Ok(()),
69 _ => {}
70 }
71
72 let impl_ = tcx.hir_expect_item(impl_did).expect_impl();
73
74 Err(tcx.dcx().emit_err(diagnostics::DropImplOnWrongItem {
75 span: impl_.self_ty.span,
76 trait_: tcx.item_name(checker.impl_header.trait_ref.skip_binder().def_id),
77 }))
78}
79
80fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
81 let tcx = checker.tcx;
82 let impl_header = checker.impl_header;
83 let impl_did = checker.impl_def_id;
84 {
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/coherence/builtin.rs:84",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(84u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_copy: impl_did={0:?}",
impl_did) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
85
86 let self_type = impl_header.trait_ref.instantiate_identity().skip_norm_wip().self_ty();
87 {
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/coherence/builtin.rs:87",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(87u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_copy: self_type={0:?} (bound)",
self_type) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
88
89 let param_env = tcx.param_env(impl_did);
90 if !!self_type.has_escaping_bound_vars() {
::core::panicking::panic("assertion failed: !self_type.has_escaping_bound_vars()")
};assert!(!self_type.has_escaping_bound_vars());
91
92 {
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/coherence/builtin.rs:92",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(92u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_copy: self_type={0:?} (free)",
self_type) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type);
93
94 if let ty::ImplPolarity::Negative = impl_header.polarity {
95 return Ok(());
96 }
97
98 let cause = traits::ObligationCause::misc(DUMMY_SP, impl_did);
99 match type_allowed_to_implement_copy(tcx, param_env, self_type, cause, impl_header.safety) {
100 Ok(()) => Ok(()),
101 Err(CopyImplementationError::InfringingFields(fields)) => {
102 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
103 Err(infringing_fields_error(
104 tcx,
105 fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)),
106 LangItem::Copy,
107 impl_did,
108 span,
109 ))
110 }
111 Err(CopyImplementationError::NotAnAdt) => {
112 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
113 Err(tcx.dcx().emit_err(diagnostics::CopyImplOnNonAdt { span }))
114 }
115 Err(CopyImplementationError::HasDestructor(did)) => {
116 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
117 let impl_ = tcx.def_span(did);
118 Err(tcx.dcx().emit_err(diagnostics::TraitImplOnTypeWithDtor {
119 span,
120 impl_,
121 trait_name: sym::Copy,
122 }))
123 }
124 Err(CopyImplementationError::HasUnsafeFields) => {
125 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
126 Err(tcx
127 .dcx()
128 .span_delayed_bug(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("cannot implement `Copy` for `{0}`",
self_type))
})format!("cannot implement `Copy` for `{}`", self_type)))
129 }
130 }
131}
132
133fn visit_implementation_of_unpin(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
134 let tcx = checker.tcx;
135 let impl_header = checker.impl_header;
136 let impl_did = checker.impl_def_id;
137 {
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/coherence/builtin.rs:137",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(137u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_unpin: impl_did={0:?}",
impl_did) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_unpin: impl_did={:?}", impl_did);
138
139 let self_type = impl_header.trait_ref.instantiate_identity().skip_norm_wip().self_ty();
140 {
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/coherence/builtin.rs:140",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(140u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_unpin: self_type={0:?}",
self_type) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_unpin: self_type={:?}", self_type);
141
142 let span = tcx.def_span(impl_did);
143
144 if tcx.features().pin_ergonomics() {
145 match self_type.kind() {
146 ty::Adt(adt, _) if adt.is_pin_project() => {
153 return Err(tcx.dcx().emit_err(crate::diagnostics::ImplUnpinForPinProjectedType {
154 span,
155 adt_span: tcx.def_span(adt.did()),
156 adt_name: tcx.item_name(adt.did()),
157 }));
158 }
159 ty::Adt(_, _) => {}
160 ty::Foreign(_) => {}
162 _ => {
163 return Err(tcx.dcx().span_delayed_bug(span, "impl of `Unpin` for a non-adt type"));
164 }
165 };
166 }
167 Ok(())
168}
169
170fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
171 let tcx = checker.tcx;
172 let header = checker.impl_header;
173 let impl_did = checker.impl_def_id;
174 let self_type = header.trait_ref.instantiate_identity().skip_norm_wip().self_ty();
175 if !!self_type.has_escaping_bound_vars() {
::core::panicking::panic("assertion failed: !self_type.has_escaping_bound_vars()")
};assert!(!self_type.has_escaping_bound_vars());
176
177 let param_env = tcx.param_env(impl_did);
178
179 if let ty::ImplPolarity::Negative = header.polarity {
180 return Ok(());
181 }
182
183 if tcx.features().const_param_ty_unchecked() {
184 return Ok(());
185 }
186
187 if !tcx.features().adt_const_params() {
188 match *self_type.kind() {
189 ty::Adt(adt, _) if adt.is_struct() => {
190 let struct_vis = tcx.visibility(adt.did());
191 for variant in adt.variants() {
192 for field in &variant.fields {
193 if struct_vis.greater_than(field.vis, tcx) {
194 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
195 return Err(tcx
196 .dcx()
197 .emit_err(diagnostics::ConstParamTyFieldVisMismatch { span }));
198 }
199 }
200 }
201 }
202
203 _ => {}
204 }
205 }
206
207 let cause = traits::ObligationCause::misc(DUMMY_SP, impl_did);
208 match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, cause) {
209 Ok(()) => Ok(()),
210 Err(ConstParamTyImplementationError::InfrigingFields(fields)) => {
211 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
212 Err(infringing_fields_error(
213 tcx,
214 fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)),
215 LangItem::ConstParamTy,
216 impl_did,
217 span,
218 ))
219 }
220 Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => {
221 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
222 Err(tcx.dcx().emit_err(diagnostics::ConstParamTyImplOnNonAdt { span }))
223 }
224 Err(ConstParamTyImplementationError::NonExhaustive(attr_span)) => {
225 let defn_span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
226 Err(tcx
227 .dcx()
228 .emit_err(diagnostics::ConstParamTyImplOnNonExhaustive { defn_span, attr_span }))
229 }
230 Err(ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(infringing_tys)) => {
231 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
232 Err(infringing_fields_error(
233 tcx,
234 infringing_tys.into_iter().map(|(ty, reason)| (span, ty, reason)),
235 LangItem::ConstParamTy,
236 impl_did,
237 span,
238 ))
239 }
240 Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired) => {
241 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
242 Err(tcx.dcx().emit_err(diagnostics::ConstParamTyImplOnUnsized { span }))
243 }
244 }
245}
246
247fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
248 let tcx = checker.tcx;
249 let impl_did = checker.impl_def_id;
250 {
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/coherence/builtin.rs:250",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(250u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_coerce_unsized: impl_did={0:?}",
impl_did) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_coerce_unsized: impl_did={:?}", impl_did);
251
252 tcx.ensure_result().coerce_unsized_info(impl_did)
256}
257
258fn visit_implementation_of_reborrow(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
259 let tcx = checker.tcx;
260 let impl_did = checker.impl_def_id;
261 {
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/coherence/builtin.rs:261",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(261u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_reborrow: impl_did={0:?}",
impl_did) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_reborrow: impl_did={:?}", impl_did);
262
263 reborrow_info(tcx, impl_did)
267}
268
269fn visit_implementation_of_coerce_shared(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
270 let tcx = checker.tcx;
271 let impl_did = checker.impl_def_id;
272 {
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/coherence/builtin.rs:272",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(272u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_coerce_shared: impl_did={0:?}",
impl_did) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_coerce_shared: impl_did={:?}", impl_did);
273
274 coerce_shared::coerce_shared_info(tcx, impl_did)
278}
279
280fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool {
281 span.ctxt()
282 .outer_expn_data()
283 .macro_def_id
284 .is_some_and(|def_id| tcx.is_diagnostic_item(sym::CoercePointee, def_id))
285}
286
287fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
288 let tcx = checker.tcx;
289 let impl_did = checker.impl_def_id;
290 let trait_ref = checker.impl_header.trait_ref.instantiate_identity().skip_norm_wip();
291 {
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/coherence/builtin.rs:291",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(291u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_dispatch_from_dyn: impl_did={0:?}",
impl_did) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did);
292
293 let span = tcx.def_span(impl_did);
294 let trait_name = "DispatchFromDyn";
295
296 let source = trait_ref.self_ty();
297 let target = {
298 if !tcx.is_lang_item(trait_ref.def_id, LangItem::DispatchFromDyn) {
::core::panicking::panic("assertion failed: tcx.is_lang_item(trait_ref.def_id, LangItem::DispatchFromDyn)")
};assert!(tcx.is_lang_item(trait_ref.def_id, LangItem::DispatchFromDyn));
299
300 trait_ref.args.type_at(1)
301 };
302
303 let mut res = Ok(());
306 tcx.for_each_relevant_impl(
307 tcx.require_lang_item(LangItem::CoerceUnsized, span),
308 source,
309 |impl_def_id| {
310 res = res.and(tcx.ensure_result().coerce_unsized_info(impl_def_id));
311 },
312 );
313 res?;
314
315 {
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/coherence/builtin.rs:315",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(315u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_dispatch_from_dyn: {0:?} -> {1:?}",
source, target) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_dispatch_from_dyn: {:?} -> {:?}", source, target);
316
317 let param_env = tcx.param_env(impl_did);
318
319 let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
320 let cause = ObligationCause::misc(span, impl_did);
321
322 match (source.kind(), target.kind()) {
331 (&ty::Pat(_, pat_a), &ty::Pat(_, pat_b)) => {
332 if pat_a != pat_b {
333 return Err(tcx.dcx().emit_err(diagnostics::CoerceSamePatKind {
334 span,
335 trait_name,
336 pat_a: pat_a.to_string(),
337 pat_b: pat_b.to_string(),
338 }));
339 }
340 Ok(())
341 }
342
343 (&ty::Ref(r_a, _, mutbl_a), ty::Ref(r_b, _, mutbl_b))
344 if r_a == *r_b && mutbl_a == *mutbl_b =>
345 {
346 Ok(())
347 }
348 (&ty::RawPtr(_, a_mutbl), &ty::RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
349 (&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b))
350 if def_a.is_struct() && def_b.is_struct() =>
351 {
352 if def_a != def_b {
353 let source_path = tcx.def_path_str(def_a.did());
354 let target_path = tcx.def_path_str(def_b.did());
355 return Err(tcx.dcx().emit_err(diagnostics::CoerceSameStruct {
356 span,
357 trait_name,
358 note: true,
359 source_path,
360 target_path,
361 }));
362 }
363
364 if def_a.repr().c() || def_a.repr().packed() {
365 return Err(tcx.dcx().emit_err(diagnostics::DispatchFromDynRepr { span }));
366 }
367
368 let fields = &def_a.non_enum_variant().fields;
369
370 let mut res = Ok(());
371 let coerced_fields = fields
372 .iter_enumerated()
373 .filter_map(|(i, field)| {
374 let unnormalized_ty = tcx.type_of(field.did).instantiate_identity();
376 if tcx
377 .try_normalize_erasing_regions(
378 ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
379 unnormalized_ty,
380 )
381 .unwrap_or(unnormalized_ty.skip_norm_wip())
382 .is_phantom_data()
383 {
384 return None;
385 }
386
387 let ty_a = field.ty(tcx, args_a).skip_norm_wip();
388 let ty_b = field.ty(tcx, args_b).skip_norm_wip();
389
390 if ty_a == ty_b {
392 if let Ok(layout) =
397 tcx.layout_of(infcx.typing_env(param_env).as_query_input(ty_a))
398 && layout.is_1zst()
399 && !ty_a.has_non_region_param()
400 {
401 return None;
403 }
404
405 res = Err(tcx.dcx().emit_err(diagnostics::DispatchFromDynZST {
406 span,
407 name: field.ident(tcx),
408 ty: ty_a,
409 }));
410
411 None
412 } else {
413 Some((i, ty_a, ty_b, tcx.def_span(field.did)))
414 }
415 })
416 .collect::<Vec<_>>();
417 res?;
418
419 if coerced_fields.is_empty() {
420 return Err(tcx.dcx().emit_err(diagnostics::CoerceNoField {
421 span,
422 trait_name,
423 note: true,
424 }));
425 } else if let &[(_, ty_a, ty_b, field_span)] = &coerced_fields[..] {
426 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
427 ocx.register_obligation(Obligation::new(
428 tcx,
429 cause.clone(),
430 param_env,
431 ty::TraitRef::new(tcx, trait_ref.def_id, [ty_a, ty_b]),
432 ));
433 let errors = ocx.evaluate_obligations_error_on_ambiguity();
434 if let TraitErrors::HasErrors(errors) = errors {
435 if is_from_coerce_pointee_derive(tcx, span) {
436 return Err(tcx.dcx().emit_err(diagnostics::CoerceFieldValidity {
437 span,
438 trait_name,
439 ty: trait_ref.self_ty(),
440 field_span,
441 field_ty: ty_a,
442 }));
443 } else {
444 return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
445 }
446 }
447
448 ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?;
450
451 Ok(())
452 } else {
453 return Err(tcx.dcx().emit_err(diagnostics::CoerceMulti {
454 span,
455 trait_name,
456 number: coerced_fields.len(),
457 fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
458 }));
459 }
460 }
461 _ => Err(tcx.dcx().emit_err(diagnostics::CoerceUnsizedNonStruct { span, trait_name })),
462 }
463}
464
465pub(crate) fn reborrow_info<'tcx>(
466 tcx: TyCtxt<'tcx>,
467 impl_did: LocalDefId,
468) -> Result<(), ErrorGuaranteed> {
469 {
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/coherence/builtin.rs:469",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(469u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("compute_reborrow_info(impl_did={0:?})",
impl_did) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("compute_reborrow_info(impl_did={:?})", impl_did);
470 let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
471 let span = tcx.def_span(impl_did);
472 let trait_name = "Reborrow";
473
474 let reborrow_trait = tcx.require_lang_item(LangItem::Reborrow, span);
475
476 let source = tcx.type_of(impl_did).instantiate_identity().skip_norm_wip();
477 let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity().skip_norm_wip();
478
479 if trait_impl_lifetime_params_count(tcx, impl_did) != 1 {
480 return Err(tcx
481 .dcx()
482 .emit_err(diagnostics::CoerceSharedNotSingleLifetimeParam { span, trait_name }));
483 }
484
485 {
match (&trait_ref.def_id, &reborrow_trait) {
(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);
}
}
}
};assert_eq!(trait_ref.def_id, reborrow_trait);
486 let param_env = tcx.param_env(impl_did);
487 if !!source.has_escaping_bound_vars() {
::core::panicking::panic("assertion failed: !source.has_escaping_bound_vars()")
};assert!(!source.has_escaping_bound_vars());
488
489 let (def, args) = match source.kind() {
490 &ty::Adt(def, args) if def.is_struct() => (def, args),
491 _ => {
492 return Err(tcx
494 .dcx()
495 .emit_err(diagnostics::CoerceUnsizedNonStruct { span, trait_name }));
496 }
497 };
498
499 let lifetimes_count = generic_lifetime_params_count(args);
500 let data_fields = collect_reborrow_data_fields(tcx, def, args);
501
502 if lifetimes_count != 1 {
503 let item = tcx.hir_expect_item(impl_did);
504 let _span = if let ItemKind::Impl(hir::Impl { of_trait: Some(of_trait), .. }) = &item.kind {
505 of_trait.trait_ref.path.span
506 } else {
507 tcx.def_span(impl_did)
508 };
509
510 return Err(tcx.dcx().emit_err(diagnostics::CoerceSharedMulti { span, trait_name }));
511 }
512
513 if data_fields.is_empty() {
514 return Ok(());
515 }
516
517 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
518 for mut field in data_fields {
520 field.ty = ocx
521 .deeply_normalize(
522 &traits::ObligationCause::misc(field.span, impl_did),
523 param_env,
524 Unnormalized::new_wip(field.ty),
525 )
526 .map_err(|errors| infcx.err_ctxt().report_fulfillment_errors(errors))?;
527 if field_type_is_reborrow(
528 tcx,
529 &infcx,
530 reborrow_trait,
531 impl_did,
532 param_env,
533 field.ty,
534 field.span,
535 ) {
536 continue;
538 }
539
540 assert_field_type_is_copy(tcx, &infcx, impl_did, param_env, field.ty, field.span)?;
542 }
543
544 if let Some(did) = def.destructor(tcx).map(|dtor| dtor.did) {
545 let impl_ = tcx.def_span(did);
546 return Err(tcx.dcx().emit_err(diagnostics::TraitImplOnTypeWithDtor {
547 span,
548 impl_,
549 trait_name: sym::Reborrow,
550 }));
551 }
552
553 Ok(())
554}
555
556fn trait_impl_lifetime_params_count(tcx: TyCtxt<'_>, did: LocalDefId) -> usize {
557 tcx.generics_of(did)
558 .own_params
559 .iter()
560 .filter(|p| #[allow(non_exhaustive_omitted_patterns)] match p.kind {
ty::GenericParamDefKind::Lifetime => true,
_ => false,
}matches!(p.kind, ty::GenericParamDefKind::Lifetime))
561 .count()
562}
563
564fn generic_lifetime_params_count(args: &[ty::GenericArg<'_>]) -> usize {
565 args.iter().filter(|arg| arg.as_region().is_some()).count()
566}
567
568#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for ReborrowDataField<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for ReborrowDataField<'tcx> {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<Ident>;
let _: ::core::clone::AssertParamIsClone<Symbol>;
let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for ReborrowDataField<'tcx> { }Copy)]
569struct ReborrowDataField<'tcx> {
570 ident: Ident,
571 name: Symbol,
572 ty: Ty<'tcx>,
573 span: Span,
574}
575
576fn collect_reborrow_data_fields<'tcx>(
577 tcx: TyCtxt<'tcx>,
578 def: ty::AdtDef<'tcx>,
579 args: ty::GenericArgsRef<'tcx>,
580) -> Vec<ReborrowDataField<'tcx>> {
581 def.non_enum_variant()
582 .fields
583 .iter()
584 .filter_map(|field| {
585 let ty = field.ty(tcx, args).skip_norm_wip();
586 (!ty.is_phantom_data()).then_some(ReborrowDataField {
587 ident: field.ident(tcx),
588 name: field.name,
589 ty,
590 span: tcx.def_span(field.did),
591 })
592 })
593 .collect()
594}
595
596fn field_type_is_reborrow<'tcx>(
597 tcx: TyCtxt<'tcx>,
598 infcx: &InferCtxt<'tcx>,
599 reborrow_trait: DefId,
600 impl_did: LocalDefId,
601 param_env: ty::ParamEnv<'tcx>,
602 ty: Ty<'tcx>,
603 span: Span,
604) -> bool {
605 if ty.ref_mutability() == Some(ty::Mutability::Mut) {
606 return true;
608 }
609
610 let ocx = ObligationCtxt::new(infcx);
611 let cause = traits::ObligationCause::misc(span, impl_did);
612 ocx.register_obligation(Obligation::new(
613 tcx,
614 cause,
615 param_env,
616 ty::TraitRef::new(tcx, reborrow_trait, [ty]),
617 ));
618 ocx.evaluate_obligations_error_on_ambiguity().no_errors()
619}
620
621fn field_type_is_copy<'tcx>(
622 tcx: TyCtxt<'tcx>,
623 infcx: &InferCtxt<'tcx>,
624 impl_did: LocalDefId,
625 param_env: ty::ParamEnv<'tcx>,
626 ty: Ty<'tcx>,
627 span: Span,
628) -> bool {
629 let copy_trait = tcx.require_lang_item(LangItem::Copy, span);
630 let ocx = ObligationCtxt::new(infcx);
631 let cause = traits::ObligationCause::misc(span, impl_did);
632 ocx.register_obligation(Obligation::new(
633 tcx,
634 cause,
635 param_env,
636 ty::TraitRef::new(tcx, copy_trait, [ty]),
637 ));
638 ocx.evaluate_obligations_error_on_ambiguity().no_errors()
639}
640
641fn assert_field_type_is_copy<'tcx>(
642 tcx: TyCtxt<'tcx>,
643 infcx: &InferCtxt<'tcx>,
644 impl_did: LocalDefId,
645 param_env: ty::ParamEnv<'tcx>,
646 ty: Ty<'tcx>,
647 span: Span,
648) -> Result<(), ErrorGuaranteed> {
649 let copy_trait = tcx.require_lang_item(LangItem::Copy, span);
650 let ocx = ObligationCtxt::new_with_diagnostics(infcx);
651 let cause = traits::ObligationCause::misc(span, impl_did);
652 let obligation =
653 Obligation::new(tcx, cause, param_env, ty::TraitRef::new(tcx, copy_trait, [ty]));
654 ocx.register_obligation(obligation);
655 let errors = ocx.evaluate_obligations_error_on_ambiguity();
656
657 if let TraitErrors::HasErrors(errors) = errors {
658 Err(infcx.err_ctxt().report_fulfillment_errors(errors))
659 } else {
660 Ok(())
661 }
662}
663
664pub(crate) fn coerce_unsized_info<'tcx>(
665 tcx: TyCtxt<'tcx>,
666 impl_did: LocalDefId,
667) -> Result<CoerceUnsizedInfo, ErrorGuaranteed> {
668 {
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/coherence/builtin.rs:668",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(668u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("compute_coerce_unsized_info(impl_did={0:?})",
impl_did) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did);
669 let span = tcx.def_span(impl_did);
670 let trait_name = "CoerceUnsized";
671
672 let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, span);
673 let unsize_trait = tcx.require_lang_item(LangItem::Unsize, span);
674
675 let source = tcx.type_of(impl_did).instantiate_identity().skip_norm_wip();
676 let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity().skip_norm_wip();
677
678 {
match (&trait_ref.def_id, &coerce_unsized_trait) {
(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);
}
}
}
};assert_eq!(trait_ref.def_id, coerce_unsized_trait);
679 let target = trait_ref.args.type_at(1);
680 {
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/coherence/builtin.rs:680",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(680u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_coerce_unsized: {0:?} -> {1:?} (bound)",
source, target) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target);
681
682 let param_env = tcx.param_env(impl_did);
683 if !!source.has_escaping_bound_vars() {
::core::panicking::panic("assertion failed: !source.has_escaping_bound_vars()")
};assert!(!source.has_escaping_bound_vars());
684
685 {
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/coherence/builtin.rs:685",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(685u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::builtin"),
::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!("visit_implementation_of_coerce_unsized: {0:?} -> {1:?} (free)",
source, target) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (free)", source, target);
686
687 let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
688 let cause = ObligationCause::misc(span, impl_did);
689 let check_mutbl = |mt_a: ty::TypeAndMut<'tcx>,
690 mt_b: ty::TypeAndMut<'tcx>,
691 mk_ptr: &dyn Fn(Ty<'tcx>) -> Ty<'tcx>| {
692 if mt_a.mutbl < mt_b.mutbl {
693 infcx
694 .err_ctxt()
695 .report_mismatched_types(
696 &cause,
697 param_env,
698 mk_ptr(mt_b.ty),
699 target,
700 ty::error::TypeError::Mutability,
701 )
702 .emit();
703 }
704 (mt_a.ty, mt_b.ty, unsize_trait, None, span)
705 };
706 let (source, target, trait_def_id, kind, field_span) = match (source.kind(), target.kind()) {
707 (&ty::Pat(ty_a, pat_a), &ty::Pat(ty_b, pat_b)) => {
708 if pat_a != pat_b {
709 return Err(tcx.dcx().emit_err(diagnostics::CoerceSamePatKind {
710 span,
711 trait_name,
712 pat_a: pat_a.to_string(),
713 pat_b: pat_b.to_string(),
714 }));
715 }
716 (ty_a, ty_b, coerce_unsized_trait, None, span)
717 }
718
719 (&ty::Ref(r_a, ty_a, mutbl_a), &ty::Ref(r_b, ty_b, mutbl_b)) => {
720 infcx.sub_regions(
721 SubregionOrigin::RelateObjectBound(span),
722 r_b,
723 r_a,
724 ty::VisibleForLeakCheck::Yes,
725 );
726 let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
727 let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b };
728 check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ref(tcx, r_b, ty))
729 }
730
731 (&ty::Ref(_, ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b))
732 | (&ty::RawPtr(ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => {
733 let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
734 let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b };
735 check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ptr(tcx, ty))
736 }
737
738 (&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b))
739 if def_a.is_struct() && def_b.is_struct() =>
740 {
741 if def_a != def_b {
742 let source_path = tcx.def_path_str(def_a.did());
743 let target_path = tcx.def_path_str(def_b.did());
744 return Err(tcx.dcx().emit_err(diagnostics::CoerceSameStruct {
745 span,
746 trait_name,
747 note: true,
748 source_path,
749 target_path,
750 }));
751 }
752
753 let fields = &def_a.non_enum_variant().fields;
793 let diff_fields = fields
794 .iter_enumerated()
795 .filter_map(|(i, f)| {
796 let (a, b) =
797 (f.ty(tcx, args_a).skip_norm_wip(), f.ty(tcx, args_b).skip_norm_wip());
798
799 let unnormalized_ty = tcx.type_of(f.did).instantiate_identity();
801 if tcx
802 .try_normalize_erasing_regions(
803 ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
804 unnormalized_ty,
805 )
806 .unwrap_or(unnormalized_ty.skip_norm_wip())
807 .is_phantom_data()
808 {
809 return None;
810 }
811
812 if a == b {
822 return None;
823 }
824
825 Some((i, a, b, tcx.def_span(f.did)))
828 })
829 .collect::<Vec<_>>();
830
831 if diff_fields.is_empty() {
832 return Err(tcx.dcx().emit_err(diagnostics::CoerceNoField {
833 span,
834 trait_name,
835 note: true,
836 }));
837 } else if diff_fields.len() > 1 {
838 let item = tcx.hir_expect_item(impl_did);
839 let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(of_trait), .. }) =
840 &item.kind
841 {
842 of_trait.trait_ref.path.span
843 } else {
844 tcx.def_span(impl_did)
845 };
846
847 return Err(tcx.dcx().emit_err(diagnostics::CoerceMulti {
848 span,
849 trait_name,
850 number: diff_fields.len(),
851 fields: diff_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
852 }));
853 }
854
855 let (i, a, b, field_span) = diff_fields[0];
856 let kind = ty::adjustment::CustomCoerceUnsized::Struct(i);
857 (a, b, coerce_unsized_trait, Some(kind), field_span)
858 }
859
860 _ => {
861 return Err(tcx
862 .dcx()
863 .emit_err(diagnostics::CoerceUnsizedNonStruct { span, trait_name }));
864 }
865 };
866
867 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
869 let cause = traits::ObligationCause::misc(span, impl_did);
870 let obligation = Obligation::new(
871 tcx,
872 cause,
873 param_env,
874 ty::TraitRef::new(tcx, trait_def_id, [source, target]),
875 );
876 ocx.register_obligation(obligation);
877 let errors = ocx.evaluate_obligations_error_on_ambiguity();
878
879 if let TraitErrors::HasErrors(errors) = errors {
880 if is_from_coerce_pointee_derive(tcx, span) {
881 return Err(tcx.dcx().emit_err(diagnostics::CoerceFieldValidity {
882 span,
883 trait_name,
884 ty: trait_ref.self_ty(),
885 field_span,
886 field_ty: source,
887 }));
888 } else {
889 return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
890 }
891 }
892
893 ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?;
895
896 Ok(CoerceUnsizedInfo { custom_kind: kind })
897}
898
899fn infringing_fields_error<'tcx>(
900 tcx: TyCtxt<'tcx>,
901 infringing_tys: impl Iterator<Item = (Span, Ty<'tcx>, InfringingFieldsReason<'tcx>)>,
902 lang_item: LangItem,
903 impl_did: LocalDefId,
904 impl_span: Span,
905) -> ErrorGuaranteed {
906 let trait_did = tcx.require_lang_item(lang_item, impl_span);
907
908 let trait_name = tcx.def_path_str(trait_did);
909
910 let mut errors: BTreeMap<_, Vec<_>> = Default::default();
913 let mut bounds = ::alloc::vec::Vec::new()vec![];
914
915 let mut seen_tys = FxHashSet::default();
916
917 let mut label_spans = Vec::new();
918
919 for (span, ty, reason) in infringing_tys {
920 if !seen_tys.insert(ty) {
922 continue;
923 }
924
925 label_spans.push(span);
926
927 match reason {
928 InfringingFieldsReason::Fulfill(fulfillment_errors) => {
929 for error in fulfillment_errors {
930 let error_predicate = error.obligation.predicate;
931 if error_predicate != error.root_obligation.predicate {
937 errors
938 .entry((ty.to_string(), error_predicate.to_string()))
939 .or_default()
940 .push(error.obligation.cause.span);
941 }
942 if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitClause {
943 trait_ref,
944 polarity: ty::ClausePolarity::Positive,
945 ..
946 })) = error_predicate.kind().skip_binder()
947 {
948 let ty = trait_ref.self_ty();
949 if let ty::Param(_) = ty.kind() {
950 bounds.push((
951 ::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("{0}", ty)) })format!("{ty}"),
952 trait_ref.print_trait_sugared().to_string(),
953 Some(trait_ref.def_id),
954 ));
955 }
956 }
957 }
958 }
959 InfringingFieldsReason::Regions(region_errors) => {
960 for error in region_errors {
961 let ty = ty.to_string();
962 match error {
963 RegionResolutionError::ConcreteFailure(origin, a, b) => {
964 let predicate = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}: {1}", b, a))
})format!("{b}: {a}");
965 errors
966 .entry((ty.clone(), predicate.clone()))
967 .or_default()
968 .push(origin.span());
969 if let ty::RegionKind::ReEarlyParam(ebr) = b.kind()
970 && ebr.is_named()
971 {
972 bounds.push((b.to_string(), a.to_string(), None));
973 }
974 }
975 RegionResolutionError::GenericBoundFailure(origin, a, b) => {
976 let predicate = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}: {1}", a, b))
})format!("{a}: {b}");
977 errors
978 .entry((ty.clone(), predicate.clone()))
979 .or_default()
980 .push(origin.span());
981 if let infer::region_constraints::GenericKind::Param(_) = a {
982 bounds.push((a.to_string(), b.to_string(), None));
983 }
984 }
985 _ => continue,
986 }
987 }
988 }
989 }
990 }
991 let mut notes = Vec::new();
992 for ((ty, error_predicate), spans) in errors {
993 let span: MultiSpan = spans.into();
994 notes.push(diagnostics::ImplForTyRequires {
995 span,
996 error_predicate,
997 trait_name: trait_name.clone(),
998 ty,
999 });
1000 }
1001
1002 let mut err = tcx.dcx().create_err(diagnostics::TraitCannotImplForTy {
1003 span: impl_span,
1004 trait_name,
1005 label_spans,
1006 notes,
1007 });
1008
1009 suggest_constraining_type_params(
1010 tcx,
1011 tcx.hir_get_generics(impl_did).expect("impls always have generics"),
1012 &mut err,
1013 bounds
1014 .iter()
1015 .map(|(param, constraint, def_id)| (param.as_str(), constraint.as_str(), *def_id)),
1016 None,
1017 );
1018
1019 err.emit_err()
1020}
1021
1022fn visit_implementation_of_coerce_pointee_validity(
1023 checker: &Checker<'_>,
1024) -> Result<(), ErrorGuaranteed> {
1025 let tcx = checker.tcx;
1026 let self_ty =
1027 tcx.impl_trait_ref(checker.impl_def_id).instantiate_identity().skip_norm_wip().self_ty();
1028 let span = tcx.def_span(checker.impl_def_id);
1029 if !tcx.is_builtin_derived(checker.impl_def_id.into()) {
1030 return Err(tcx.dcx().emit_err(diagnostics::CoercePointeeNoUserValidityAssertion { span }));
1031 }
1032 let ty::Adt(def, _args) = self_ty.kind() else {
1033 return Err(tcx.dcx().emit_err(diagnostics::CoercePointeeNotConcreteType { span }));
1034 };
1035 let did = def.did();
1036 let span = tcx.def_span(did);
1038 if !def.is_struct() {
1039 return Err(tcx
1040 .dcx()
1041 .emit_err(diagnostics::CoercePointeeNotStruct { span, kind: def.descr().into() }));
1042 }
1043 if !def.repr().transparent() {
1044 return Err(tcx.dcx().emit_err(diagnostics::CoercePointeeNotTransparent { span }));
1045 }
1046 if def.all_fields().next().is_none() {
1047 return Err(tcx.dcx().emit_err(diagnostics::CoercePointeeNoField { span }));
1048 }
1049 Ok(())
1050}