1use std::collections::BTreeMap;
5
6use rustc_data_structures::fx::FxHashSet;
7use rustc_errors::{ErrorGuaranteed, MultiSpan};
8use rustc_hir as hir;
9use rustc_hir::ItemKind;
10use rustc_hir::attrs::lang_items::LangItem;
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/0fc141305da7a8a222f65aef1f1acc739c46282b/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/0fc141305da7a8a222f65aef1f1acc739c46282b/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/0fc141305da7a8a222f65aef1f1acc739c46282b/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/0fc141305da7a8a222f65aef1f1acc739c46282b/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/0fc141305da7a8a222f65aef1f1acc739c46282b/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/0fc141305da7a8a222f65aef1f1acc739c46282b/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::CopyImplOnTypeWithDtor { span, impl_ }))
119 }
120 Err(CopyImplementationError::HasUnsafeFields) => {
121 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
122 Err(tcx
123 .dcx()
124 .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)))
125 }
126 }
127}
128
129fn visit_implementation_of_unpin(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
130 let tcx = checker.tcx;
131 let impl_header = checker.impl_header;
132 let impl_did = checker.impl_def_id;
133 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:133",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(133u32),
::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);
134
135 let self_type = impl_header.trait_ref.instantiate_identity().skip_norm_wip().self_ty();
136 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:136",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(136u32),
::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);
137
138 let span = tcx.def_span(impl_did);
139
140 if tcx.features().pin_ergonomics() {
141 match self_type.kind() {
142 ty::Adt(adt, _) if adt.is_pin_project() => {
149 return Err(tcx.dcx().emit_err(crate::diagnostics::ImplUnpinForPinProjectedType {
150 span,
151 adt_span: tcx.def_span(adt.did()),
152 adt_name: tcx.item_name(adt.did()),
153 }));
154 }
155 ty::Adt(_, _) => {}
156 ty::Foreign(_) => {}
158 _ => {
159 return Err(tcx.dcx().span_delayed_bug(span, "impl of `Unpin` for a non-adt type"));
160 }
161 };
162 }
163 Ok(())
164}
165
166fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
167 let tcx = checker.tcx;
168 let header = checker.impl_header;
169 let impl_did = checker.impl_def_id;
170 let self_type = header.trait_ref.instantiate_identity().skip_norm_wip().self_ty();
171 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());
172
173 let param_env = tcx.param_env(impl_did);
174
175 if let ty::ImplPolarity::Negative = header.polarity {
176 return Ok(());
177 }
178
179 if tcx.features().const_param_ty_unchecked() {
180 return Ok(());
181 }
182
183 if !tcx.features().adt_const_params() {
184 match *self_type.kind() {
185 ty::Adt(adt, _) if adt.is_struct() => {
186 let struct_vis = tcx.visibility(adt.did());
187 for variant in adt.variants() {
188 for field in &variant.fields {
189 if struct_vis.greater_than(field.vis, tcx) {
190 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
191 return Err(tcx
192 .dcx()
193 .emit_err(diagnostics::ConstParamTyFieldVisMismatch { span }));
194 }
195 }
196 }
197 }
198
199 _ => {}
200 }
201 }
202
203 let cause = traits::ObligationCause::misc(DUMMY_SP, impl_did);
204 match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, cause) {
205 Ok(()) => Ok(()),
206 Err(ConstParamTyImplementationError::InfrigingFields(fields)) => {
207 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
208 Err(infringing_fields_error(
209 tcx,
210 fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)),
211 LangItem::ConstParamTy,
212 impl_did,
213 span,
214 ))
215 }
216 Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => {
217 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
218 Err(tcx.dcx().emit_err(diagnostics::ConstParamTyImplOnNonAdt { span }))
219 }
220 Err(ConstParamTyImplementationError::NonExhaustive(attr_span)) => {
221 let defn_span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
222 Err(tcx
223 .dcx()
224 .emit_err(diagnostics::ConstParamTyImplOnNonExhaustive { defn_span, attr_span }))
225 }
226 Err(ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(infringing_tys)) => {
227 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
228 Err(infringing_fields_error(
229 tcx,
230 infringing_tys.into_iter().map(|(ty, reason)| (span, ty, reason)),
231 LangItem::ConstParamTy,
232 impl_did,
233 span,
234 ))
235 }
236 Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired) => {
237 let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
238 Err(tcx.dcx().emit_err(diagnostics::ConstParamTyImplOnUnsized { span }))
239 }
240 }
241}
242
243fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
244 let tcx = checker.tcx;
245 let impl_did = checker.impl_def_id;
246 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:246",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(246u32),
::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);
247
248 tcx.ensure_result().coerce_unsized_info(impl_did)
252}
253
254fn visit_implementation_of_reborrow(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
255 let tcx = checker.tcx;
256 let impl_did = checker.impl_def_id;
257 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:257",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(257u32),
::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);
258
259 reborrow_info(tcx, impl_did)
263}
264
265fn visit_implementation_of_coerce_shared(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
266 let tcx = checker.tcx;
267 let impl_did = checker.impl_def_id;
268 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:268",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(268u32),
::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);
269
270 coerce_shared::coerce_shared_info(tcx, impl_did)
274}
275
276fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool {
277 span.ctxt()
278 .outer_expn_data()
279 .macro_def_id
280 .is_some_and(|def_id| tcx.is_diagnostic_item(sym::CoercePointee, def_id))
281}
282
283fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
284 let tcx = checker.tcx;
285 let impl_did = checker.impl_def_id;
286 let trait_ref = checker.impl_header.trait_ref.instantiate_identity().skip_norm_wip();
287 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:287",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(287u32),
::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);
288
289 let span = tcx.def_span(impl_did);
290 let trait_name = "DispatchFromDyn";
291
292 let source = trait_ref.self_ty();
293 let target = {
294 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));
295
296 trait_ref.args.type_at(1)
297 };
298
299 let mut res = Ok(());
302 tcx.for_each_relevant_impl(
303 tcx.require_lang_item(LangItem::CoerceUnsized, span),
304 source,
305 |impl_def_id| {
306 res = res.and(tcx.ensure_result().coerce_unsized_info(impl_def_id));
307 },
308 );
309 res?;
310
311 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:311",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(311u32),
::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);
312
313 let param_env = tcx.param_env(impl_did);
314
315 let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
316 let cause = ObligationCause::misc(span, impl_did);
317
318 match (source.kind(), target.kind()) {
327 (&ty::Pat(_, pat_a), &ty::Pat(_, pat_b)) => {
328 if pat_a != pat_b {
329 return Err(tcx.dcx().emit_err(diagnostics::CoerceSamePatKind {
330 span,
331 trait_name,
332 pat_a: pat_a.to_string(),
333 pat_b: pat_b.to_string(),
334 }));
335 }
336 Ok(())
337 }
338
339 (&ty::Ref(r_a, _, mutbl_a), ty::Ref(r_b, _, mutbl_b))
340 if r_a == *r_b && mutbl_a == *mutbl_b =>
341 {
342 Ok(())
343 }
344 (&ty::RawPtr(_, a_mutbl), &ty::RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
345 (&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b))
346 if def_a.is_struct() && def_b.is_struct() =>
347 {
348 if def_a != def_b {
349 let source_path = tcx.def_path_str(def_a.did());
350 let target_path = tcx.def_path_str(def_b.did());
351 return Err(tcx.dcx().emit_err(diagnostics::CoerceSameStruct {
352 span,
353 trait_name,
354 note: true,
355 source_path,
356 target_path,
357 }));
358 }
359
360 if def_a.repr().c() || def_a.repr().packed() {
361 return Err(tcx.dcx().emit_err(diagnostics::DispatchFromDynRepr { span }));
362 }
363
364 let fields = &def_a.non_enum_variant().fields;
365
366 let mut res = Ok(());
367 let coerced_fields = fields
368 .iter_enumerated()
369 .filter_map(|(i, field)| {
370 let unnormalized_ty = tcx.type_of(field.did).instantiate_identity();
372 if tcx
373 .try_normalize_erasing_regions(
374 ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
375 unnormalized_ty,
376 )
377 .unwrap_or(unnormalized_ty.skip_norm_wip())
378 .is_phantom_data()
379 {
380 return None;
381 }
382
383 let ty_a = field.ty(tcx, args_a).skip_norm_wip();
384 let ty_b = field.ty(tcx, args_b).skip_norm_wip();
385
386 if ty_a == ty_b {
388 if let Ok(layout) =
393 tcx.layout_of(infcx.typing_env(param_env).as_query_input(ty_a))
394 && layout.is_1zst()
395 && !ty_a.has_non_region_param()
396 {
397 return None;
399 }
400
401 res = Err(tcx.dcx().emit_err(diagnostics::DispatchFromDynZST {
402 span,
403 name: field.ident(tcx),
404 ty: ty_a,
405 }));
406
407 None
408 } else {
409 Some((i, ty_a, ty_b, tcx.def_span(field.did)))
410 }
411 })
412 .collect::<Vec<_>>();
413 res?;
414
415 if coerced_fields.is_empty() {
416 return Err(tcx.dcx().emit_err(diagnostics::CoerceNoField {
417 span,
418 trait_name,
419 note: true,
420 }));
421 } else if let &[(_, ty_a, ty_b, field_span)] = &coerced_fields[..] {
422 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
423 ocx.register_obligation(Obligation::new(
424 tcx,
425 cause.clone(),
426 param_env,
427 ty::TraitRef::new(tcx, trait_ref.def_id, [ty_a, ty_b]),
428 ));
429 let errors = ocx.evaluate_obligations_error_on_ambiguity();
430 if let TraitErrors::HasErrors(errors) = errors {
431 if is_from_coerce_pointee_derive(tcx, span) {
432 return Err(tcx.dcx().emit_err(diagnostics::CoerceFieldValidity {
433 span,
434 trait_name,
435 ty: trait_ref.self_ty(),
436 field_span,
437 field_ty: ty_a,
438 }));
439 } else {
440 return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
441 }
442 }
443
444 ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?;
446
447 Ok(())
448 } else {
449 return Err(tcx.dcx().emit_err(diagnostics::CoerceMulti {
450 span,
451 trait_name,
452 number: coerced_fields.len(),
453 fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
454 }));
455 }
456 }
457 _ => Err(tcx.dcx().emit_err(diagnostics::CoerceUnsizedNonStruct { span, trait_name })),
458 }
459}
460
461pub(crate) fn reborrow_info<'tcx>(
462 tcx: TyCtxt<'tcx>,
463 impl_did: LocalDefId,
464) -> Result<(), ErrorGuaranteed> {
465 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:465",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(465u32),
::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);
466 let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
467 let span = tcx.def_span(impl_did);
468 let trait_name = "Reborrow";
469
470 let reborrow_trait = tcx.require_lang_item(LangItem::Reborrow, span);
471
472 let source = tcx.type_of(impl_did).instantiate_identity().skip_norm_wip();
473 let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity().skip_norm_wip();
474
475 if trait_impl_lifetime_params_count(tcx, impl_did) != 1 {
476 return Err(tcx
477 .dcx()
478 .emit_err(diagnostics::CoerceSharedNotSingleLifetimeParam { span, trait_name }));
479 }
480
481 {
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);
482 let param_env = tcx.param_env(impl_did);
483 if !!source.has_escaping_bound_vars() {
::core::panicking::panic("assertion failed: !source.has_escaping_bound_vars()")
};assert!(!source.has_escaping_bound_vars());
484
485 let (def, args) = match source.kind() {
486 &ty::Adt(def, args) if def.is_struct() => (def, args),
487 _ => {
488 return Err(tcx
490 .dcx()
491 .emit_err(diagnostics::CoerceUnsizedNonStruct { span, trait_name }));
492 }
493 };
494
495 let lifetimes_count = generic_lifetime_params_count(args);
496 let data_fields = collect_reborrow_data_fields(tcx, def, args);
497
498 if lifetimes_count != 1 {
499 let item = tcx.hir_expect_item(impl_did);
500 let _span = if let ItemKind::Impl(hir::Impl { of_trait: Some(of_trait), .. }) = &item.kind {
501 of_trait.trait_ref.path.span
502 } else {
503 tcx.def_span(impl_did)
504 };
505
506 return Err(tcx.dcx().emit_err(diagnostics::CoerceSharedMulti { span, trait_name }));
507 }
508
509 if data_fields.is_empty() {
510 return Ok(());
511 }
512
513 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
514 for mut field in data_fields {
516 field.ty = ocx
517 .deeply_normalize(
518 &traits::ObligationCause::misc(field.span, impl_did),
519 param_env,
520 Unnormalized::new_wip(field.ty),
521 )
522 .map_err(|errors| infcx.err_ctxt().report_fulfillment_errors(errors))?;
523 if field_type_is_reborrow(
524 tcx,
525 &infcx,
526 reborrow_trait,
527 impl_did,
528 param_env,
529 field.ty,
530 field.span,
531 ) {
532 continue;
534 }
535
536 assert_field_type_is_copy(tcx, &infcx, impl_did, param_env, field.ty, field.span)?;
538 }
539
540 Ok(())
541}
542
543fn trait_impl_lifetime_params_count(tcx: TyCtxt<'_>, did: LocalDefId) -> usize {
544 tcx.generics_of(did)
545 .own_params
546 .iter()
547 .filter(|p| #[allow(non_exhaustive_omitted_patterns)] match p.kind {
ty::GenericParamDefKind::Lifetime => true,
_ => false,
}matches!(p.kind, ty::GenericParamDefKind::Lifetime))
548 .count()
549}
550
551fn generic_lifetime_params_count(args: &[ty::GenericArg<'_>]) -> usize {
552 args.iter().filter(|arg| arg.as_region().is_some()).count()
553}
554
555#[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) -> ReborrowDataField<'tcx> {
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)]
556struct ReborrowDataField<'tcx> {
557 ident: Ident,
558 name: Symbol,
559 ty: Ty<'tcx>,
560 span: Span,
561}
562
563fn collect_reborrow_data_fields<'tcx>(
564 tcx: TyCtxt<'tcx>,
565 def: ty::AdtDef<'tcx>,
566 args: ty::GenericArgsRef<'tcx>,
567) -> Vec<ReborrowDataField<'tcx>> {
568 def.non_enum_variant()
569 .fields
570 .iter()
571 .filter_map(|field| {
572 let ty = field.ty(tcx, args).skip_norm_wip();
573 (!ty.is_phantom_data()).then_some(ReborrowDataField {
574 ident: field.ident(tcx),
575 name: field.name,
576 ty,
577 span: tcx.def_span(field.did),
578 })
579 })
580 .collect()
581}
582
583fn field_type_is_reborrow<'tcx>(
584 tcx: TyCtxt<'tcx>,
585 infcx: &InferCtxt<'tcx>,
586 reborrow_trait: DefId,
587 impl_did: LocalDefId,
588 param_env: ty::ParamEnv<'tcx>,
589 ty: Ty<'tcx>,
590 span: Span,
591) -> bool {
592 if ty.ref_mutability() == Some(ty::Mutability::Mut) {
593 return true;
595 }
596
597 let ocx = ObligationCtxt::new(infcx);
598 let cause = traits::ObligationCause::misc(span, impl_did);
599 ocx.register_obligation(Obligation::new(
600 tcx,
601 cause,
602 param_env,
603 ty::TraitRef::new(tcx, reborrow_trait, [ty]),
604 ));
605 ocx.evaluate_obligations_error_on_ambiguity().no_errors()
606}
607
608fn field_type_is_copy<'tcx>(
609 tcx: TyCtxt<'tcx>,
610 infcx: &InferCtxt<'tcx>,
611 impl_did: LocalDefId,
612 param_env: ty::ParamEnv<'tcx>,
613 ty: Ty<'tcx>,
614 span: Span,
615) -> bool {
616 let copy_trait = tcx.require_lang_item(LangItem::Copy, span);
617 let ocx = ObligationCtxt::new(infcx);
618 let cause = traits::ObligationCause::misc(span, impl_did);
619 ocx.register_obligation(Obligation::new(
620 tcx,
621 cause,
622 param_env,
623 ty::TraitRef::new(tcx, copy_trait, [ty]),
624 ));
625 ocx.evaluate_obligations_error_on_ambiguity().no_errors()
626}
627
628fn assert_field_type_is_copy<'tcx>(
629 tcx: TyCtxt<'tcx>,
630 infcx: &InferCtxt<'tcx>,
631 impl_did: LocalDefId,
632 param_env: ty::ParamEnv<'tcx>,
633 ty: Ty<'tcx>,
634 span: Span,
635) -> Result<(), ErrorGuaranteed> {
636 let copy_trait = tcx.require_lang_item(LangItem::Copy, span);
637 let ocx = ObligationCtxt::new_with_diagnostics(infcx);
638 let cause = traits::ObligationCause::misc(span, impl_did);
639 let obligation =
640 Obligation::new(tcx, cause, param_env, ty::TraitRef::new(tcx, copy_trait, [ty]));
641 ocx.register_obligation(obligation);
642 let errors = ocx.evaluate_obligations_error_on_ambiguity();
643
644 if let TraitErrors::HasErrors(errors) = errors {
645 Err(infcx.err_ctxt().report_fulfillment_errors(errors))
646 } else {
647 Ok(())
648 }
649}
650
651pub(crate) fn coerce_unsized_info<'tcx>(
652 tcx: TyCtxt<'tcx>,
653 impl_did: LocalDefId,
654) -> Result<CoerceUnsizedInfo, ErrorGuaranteed> {
655 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:655",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(655u32),
::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);
656 let span = tcx.def_span(impl_did);
657 let trait_name = "CoerceUnsized";
658
659 let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, span);
660 let unsize_trait = tcx.require_lang_item(LangItem::Unsize, span);
661
662 let source = tcx.type_of(impl_did).instantiate_identity().skip_norm_wip();
663 let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity().skip_norm_wip();
664
665 {
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);
666 let target = trait_ref.args.type_at(1);
667 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:667",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(667u32),
::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);
668
669 let param_env = tcx.param_env(impl_did);
670 if !!source.has_escaping_bound_vars() {
::core::panicking::panic("assertion failed: !source.has_escaping_bound_vars()")
};assert!(!source.has_escaping_bound_vars());
671
672 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs:672",
"rustc_hir_analysis::coherence::builtin",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/0fc141305da7a8a222f65aef1f1acc739c46282b/compiler/rustc_hir_analysis/src/coherence/builtin.rs"),
::tracing_core::__macro_support::Option::Some(672u32),
::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);
673
674 let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
675 let cause = ObligationCause::misc(span, impl_did);
676 let check_mutbl = |mt_a: ty::TypeAndMut<'tcx>,
677 mt_b: ty::TypeAndMut<'tcx>,
678 mk_ptr: &dyn Fn(Ty<'tcx>) -> Ty<'tcx>| {
679 if mt_a.mutbl < mt_b.mutbl {
680 infcx
681 .err_ctxt()
682 .report_mismatched_types(
683 &cause,
684 param_env,
685 mk_ptr(mt_b.ty),
686 target,
687 ty::error::TypeError::Mutability,
688 )
689 .emit();
690 }
691 (mt_a.ty, mt_b.ty, unsize_trait, None, span)
692 };
693 let (source, target, trait_def_id, kind, field_span) = match (source.kind(), target.kind()) {
694 (&ty::Pat(ty_a, pat_a), &ty::Pat(ty_b, pat_b)) => {
695 if pat_a != pat_b {
696 return Err(tcx.dcx().emit_err(diagnostics::CoerceSamePatKind {
697 span,
698 trait_name,
699 pat_a: pat_a.to_string(),
700 pat_b: pat_b.to_string(),
701 }));
702 }
703 (ty_a, ty_b, coerce_unsized_trait, None, span)
704 }
705
706 (&ty::Ref(r_a, ty_a, mutbl_a), &ty::Ref(r_b, ty_b, mutbl_b)) => {
707 infcx.sub_regions(
708 SubregionOrigin::RelateObjectBound(span),
709 r_b,
710 r_a,
711 ty::VisibleForLeakCheck::Yes,
712 );
713 let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
714 let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b };
715 check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ref(tcx, r_b, ty))
716 }
717
718 (&ty::Ref(_, ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b))
719 | (&ty::RawPtr(ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => {
720 let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
721 let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b };
722 check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ptr(tcx, ty))
723 }
724
725 (&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b))
726 if def_a.is_struct() && def_b.is_struct() =>
727 {
728 if def_a != def_b {
729 let source_path = tcx.def_path_str(def_a.did());
730 let target_path = tcx.def_path_str(def_b.did());
731 return Err(tcx.dcx().emit_err(diagnostics::CoerceSameStruct {
732 span,
733 trait_name,
734 note: true,
735 source_path,
736 target_path,
737 }));
738 }
739
740 let fields = &def_a.non_enum_variant().fields;
780 let diff_fields = fields
781 .iter_enumerated()
782 .filter_map(|(i, f)| {
783 let (a, b) =
784 (f.ty(tcx, args_a).skip_norm_wip(), f.ty(tcx, args_b).skip_norm_wip());
785
786 let unnormalized_ty = tcx.type_of(f.did).instantiate_identity();
788 if tcx
789 .try_normalize_erasing_regions(
790 ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
791 unnormalized_ty,
792 )
793 .unwrap_or(unnormalized_ty.skip_norm_wip())
794 .is_phantom_data()
795 {
796 return None;
797 }
798
799 if a == b {
809 return None;
810 }
811
812 Some((i, a, b, tcx.def_span(f.did)))
815 })
816 .collect::<Vec<_>>();
817
818 if diff_fields.is_empty() {
819 return Err(tcx.dcx().emit_err(diagnostics::CoerceNoField {
820 span,
821 trait_name,
822 note: true,
823 }));
824 } else if diff_fields.len() > 1 {
825 let item = tcx.hir_expect_item(impl_did);
826 let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(of_trait), .. }) =
827 &item.kind
828 {
829 of_trait.trait_ref.path.span
830 } else {
831 tcx.def_span(impl_did)
832 };
833
834 return Err(tcx.dcx().emit_err(diagnostics::CoerceMulti {
835 span,
836 trait_name,
837 number: diff_fields.len(),
838 fields: diff_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
839 }));
840 }
841
842 let (i, a, b, field_span) = diff_fields[0];
843 let kind = ty::adjustment::CustomCoerceUnsized::Struct(i);
844 (a, b, coerce_unsized_trait, Some(kind), field_span)
845 }
846
847 _ => {
848 return Err(tcx
849 .dcx()
850 .emit_err(diagnostics::CoerceUnsizedNonStruct { span, trait_name }));
851 }
852 };
853
854 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
856 let cause = traits::ObligationCause::misc(span, impl_did);
857 let obligation = Obligation::new(
858 tcx,
859 cause,
860 param_env,
861 ty::TraitRef::new(tcx, trait_def_id, [source, target]),
862 );
863 ocx.register_obligation(obligation);
864 let errors = ocx.evaluate_obligations_error_on_ambiguity();
865
866 if let TraitErrors::HasErrors(errors) = errors {
867 if is_from_coerce_pointee_derive(tcx, span) {
868 return Err(tcx.dcx().emit_err(diagnostics::CoerceFieldValidity {
869 span,
870 trait_name,
871 ty: trait_ref.self_ty(),
872 field_span,
873 field_ty: source,
874 }));
875 } else {
876 return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
877 }
878 }
879
880 ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?;
882
883 Ok(CoerceUnsizedInfo { custom_kind: kind })
884}
885
886fn infringing_fields_error<'tcx>(
887 tcx: TyCtxt<'tcx>,
888 infringing_tys: impl Iterator<Item = (Span, Ty<'tcx>, InfringingFieldsReason<'tcx>)>,
889 lang_item: LangItem,
890 impl_did: LocalDefId,
891 impl_span: Span,
892) -> ErrorGuaranteed {
893 let trait_did = tcx.require_lang_item(lang_item, impl_span);
894
895 let trait_name = tcx.def_path_str(trait_did);
896
897 let mut errors: BTreeMap<_, Vec<_>> = Default::default();
900 let mut bounds = ::alloc::vec::Vec::new()vec![];
901
902 let mut seen_tys = FxHashSet::default();
903
904 let mut label_spans = Vec::new();
905
906 for (span, ty, reason) in infringing_tys {
907 if !seen_tys.insert(ty) {
909 continue;
910 }
911
912 label_spans.push(span);
913
914 match reason {
915 InfringingFieldsReason::Fulfill(fulfillment_errors) => {
916 for error in fulfillment_errors {
917 let error_predicate = error.obligation.predicate;
918 if error_predicate != error.root_obligation.predicate {
924 errors
925 .entry((ty.to_string(), error_predicate.to_string()))
926 .or_default()
927 .push(error.obligation.cause.span);
928 }
929 if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitClause {
930 trait_ref,
931 polarity: ty::ClausePolarity::Positive,
932 ..
933 })) = error_predicate.kind().skip_binder()
934 {
935 let ty = trait_ref.self_ty();
936 if let ty::Param(_) = ty.kind() {
937 bounds.push((
938 ::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("{0}", ty)) })format!("{ty}"),
939 trait_ref.print_trait_sugared().to_string(),
940 Some(trait_ref.def_id),
941 ));
942 }
943 }
944 }
945 }
946 InfringingFieldsReason::Regions(region_errors) => {
947 for error in region_errors {
948 let ty = ty.to_string();
949 match error {
950 RegionResolutionError::ConcreteFailure(origin, a, b) => {
951 let predicate = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}: {1}", b, a))
})format!("{b}: {a}");
952 errors
953 .entry((ty.clone(), predicate.clone()))
954 .or_default()
955 .push(origin.span());
956 if let ty::RegionKind::ReEarlyParam(ebr) = b.kind()
957 && ebr.is_named()
958 {
959 bounds.push((b.to_string(), a.to_string(), None));
960 }
961 }
962 RegionResolutionError::GenericBoundFailure(origin, a, b) => {
963 let predicate = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}: {1}", a, b))
})format!("{a}: {b}");
964 errors
965 .entry((ty.clone(), predicate.clone()))
966 .or_default()
967 .push(origin.span());
968 if let infer::region_constraints::GenericKind::Param(_) = a {
969 bounds.push((a.to_string(), b.to_string(), None));
970 }
971 }
972 _ => continue,
973 }
974 }
975 }
976 }
977 }
978 let mut notes = Vec::new();
979 for ((ty, error_predicate), spans) in errors {
980 let span: MultiSpan = spans.into();
981 notes.push(diagnostics::ImplForTyRequires {
982 span,
983 error_predicate,
984 trait_name: trait_name.clone(),
985 ty,
986 });
987 }
988
989 let mut err = tcx.dcx().create_err(diagnostics::TraitCannotImplForTy {
990 span: impl_span,
991 trait_name,
992 label_spans,
993 notes,
994 });
995
996 suggest_constraining_type_params(
997 tcx,
998 tcx.hir_get_generics(impl_did).expect("impls always have generics"),
999 &mut err,
1000 bounds
1001 .iter()
1002 .map(|(param, constraint, def_id)| (param.as_str(), constraint.as_str(), *def_id)),
1003 None,
1004 );
1005
1006 err.emit()
1007}
1008
1009fn visit_implementation_of_coerce_pointee_validity(
1010 checker: &Checker<'_>,
1011) -> Result<(), ErrorGuaranteed> {
1012 let tcx = checker.tcx;
1013 let self_ty =
1014 tcx.impl_trait_ref(checker.impl_def_id).instantiate_identity().skip_norm_wip().self_ty();
1015 let span = tcx.def_span(checker.impl_def_id);
1016 if !tcx.is_builtin_derived(checker.impl_def_id.into()) {
1017 return Err(tcx.dcx().emit_err(diagnostics::CoercePointeeNoUserValidityAssertion { span }));
1018 }
1019 let ty::Adt(def, _args) = self_ty.kind() else {
1020 return Err(tcx.dcx().emit_err(diagnostics::CoercePointeeNotConcreteType { span }));
1021 };
1022 let did = def.did();
1023 let span = tcx.def_span(did);
1025 if !def.is_struct() {
1026 return Err(tcx
1027 .dcx()
1028 .emit_err(diagnostics::CoercePointeeNotStruct { span, kind: def.descr().into() }));
1029 }
1030 if !def.repr().transparent() {
1031 return Err(tcx.dcx().emit_err(diagnostics::CoercePointeeNotTransparent { span }));
1032 }
1033 if def.all_fields().next().is_none() {
1034 return Err(tcx.dcx().emit_err(diagnostics::CoercePointeeNoField { span }));
1035 }
1036 Ok(())
1037}