1use rustc_data_structures::fx::FxIndexSet;
5use rustc_errors::ErrorGuaranteed;
6use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
7use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION;
8use rustc_middle::ty::{
9 self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
10 Unnormalized,
11};
12use rustc_span::def_id::{DefId, LocalDefId};
13use rustc_span::{bug, span_bug};
14use rustc_trait_selection::traits::{
15 self, IsFirstInputType, OrphanCheckErr, OrphanCheckMode, UncoveredTyParams,
16};
17use tracing::{debug, instrument};
18
19use crate::diagnostics;
20
21{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("orphan_check_impl",
"rustc_hir_analysis::coherence::orphan",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/coherence/orphan.rs"),
::tracing_core::__macro_support::Option::Some(21u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::orphan"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("impl_def_id")
}> =
::tracing::__macro_support::FieldName::new("impl_def_id");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&impl_def_id)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Result<(), ErrorGuaranteed> =
loop {};
return __tracing_attr_fake_return;
}
{
let trait_ref =
tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip();
trait_ref.error_reported()?;
match orphan_check(tcx, impl_def_id, OrphanCheckMode::Proper) {
Ok(()) => {}
Err(err) =>
match orphan_check(tcx, impl_def_id,
OrphanCheckMode::Compat) {
Ok(()) =>
match err {
OrphanCheckErr::UncoveredTyParams(uncovered_ty_params) => {
let hir_id = tcx.local_def_id_to_hir_id(impl_def_id);
for param_def_id in uncovered_ty_params.uncovered {
let ident = tcx.item_ident(param_def_id);
tcx.emit_node_span_lint(UNCOVERED_PARAM_IN_PROJECTION,
hir_id, ident.span,
diagnostics::UncoveredTyParam {
param: ident,
local_ty: uncovered_ty_params.local_ty,
});
}
}
OrphanCheckErr::NonLocalInputType(_) => {
::rustc_span::macros::bug_impl(None,
format_args!("orphanck: shouldn\'t\'ve gotten non-local input tys in compat mode"),
Location::caller())
}
},
Err(err) =>
return Err(emit_orphan_check_error(tcx, trait_ref,
impl_def_id, err)),
},
}
let trait_def_id = trait_ref.def_id;
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/coherence/orphan.rs:92",
"rustc_hir_analysis::coherence::orphan",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/coherence/orphan.rs"),
::tracing_core::__macro_support::Option::Some(92u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::orphan"),
::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!("trait_ref={0:?} trait_def_id={1:?} trait_is_auto={2}",
trait_ref, trait_def_id, tcx.trait_is_auto(trait_def_id)) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};
if tcx.trait_is_auto(trait_def_id) {
let self_ty = tcx.expand_free_alias_tys(trait_ref.self_ty());
enum LocalImpl {
Allow,
Disallow {
problematic_kind: &'static str,
},
}
enum NonlocalImpl {
Allow,
DisallowBecauseNonlocal,
DisallowOther,
}
let (local_impl, nonlocal_impl) =
match self_ty.kind() {
ty::Adt(self_def, _) =>
(LocalImpl::Allow,
if self_def.did().is_local() {
NonlocalImpl::Allow
} else { NonlocalImpl::DisallowBecauseNonlocal }),
ty::Foreign(did) =>
(LocalImpl::Allow,
if did.is_local() {
NonlocalImpl::Allow
} else { NonlocalImpl::DisallowBecauseNonlocal }),
ty::Dynamic(..) =>
(LocalImpl::Disallow { problematic_kind: "trait object" },
NonlocalImpl::DisallowOther),
ty::Param(..) =>
(if self_ty.is_sized(tcx,
ty::TypingEnv::non_body_analysis(tcx, impl_def_id)) {
LocalImpl::Allow
} else {
LocalImpl::Disallow { problematic_kind: "generic type" }
}, NonlocalImpl::DisallowOther),
ty::Alias(_, ty::AliasTy { kind, .. }) => {
let problematic_kind =
match kind {
ty::Projection { .. } => "associated type",
ty::Free { .. } => "type alias",
ty::Opaque { .. } => "opaque type",
ty::Inherent { .. } => "associated type",
};
(LocalImpl::Disallow { problematic_kind },
NonlocalImpl::DisallowOther)
}
ty::Bool | ty::Pat(..) | ty::Char | ty::Int(..) |
ty::Uint(..) | ty::Float(..) | ty::Str | ty::Array(..) |
ty::Slice(..) | ty::RawPtr(..) | ty::Ref(..) | ty::FnPtr(..)
| ty::Never | ty::Tuple(..) | ty::UnsafeBinder(_) =>
(LocalImpl::Allow, NonlocalImpl::DisallowOther),
ty::FnDef(..) | ty::Closure(..) | ty::CoroutineClosure(..) |
ty::Coroutine(..) | ty::CoroutineWitness(..) | ty::Bound(..)
| ty::Placeholder(..) | ty::Infer(..) => {
let sp = tcx.def_span(impl_def_id);
::rustc_span::macros::bug_impl(Some(sp),
format_args!("weird self type for autotrait impl"),
Location::caller())
}
ty::Error(..) => (LocalImpl::Allow, NonlocalImpl::Allow),
};
if trait_def_id.is_local() {
match local_impl {
LocalImpl::Allow => {}
LocalImpl::Disallow { problematic_kind } => {
return Err(tcx.dcx().emit_err(diagnostics::TraitsWithDefaultImpl {
span: tcx.def_span(impl_def_id),
traits: tcx.def_path_str(trait_def_id),
problematic_kind,
self_ty,
}));
}
}
} else {
match nonlocal_impl {
NonlocalImpl::Allow => {}
NonlocalImpl::DisallowBecauseNonlocal => {
return Err(tcx.dcx().emit_err(diagnostics::CrossCrateTraitsDefined {
span: tcx.def_span(impl_def_id),
traits: tcx.def_path_str(trait_def_id),
}));
}
NonlocalImpl::DisallowOther => {
return Err(tcx.dcx().emit_err(diagnostics::CrossCrateTraits {
span: tcx.def_span(impl_def_id),
traits: tcx.def_path_str(trait_def_id),
self_ty,
}));
}
}
}
}
Ok(())
}
}
}#[instrument(level = "debug", skip(tcx))]
22pub(crate) fn orphan_check_impl(
23 tcx: TyCtxt<'_>,
24 impl_def_id: LocalDefId,
25) -> Result<(), ErrorGuaranteed> {
26 let trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip();
27 trait_ref.error_reported()?;
28
29 match orphan_check(tcx, impl_def_id, OrphanCheckMode::Proper) {
30 Ok(()) => {}
31 Err(err) => match orphan_check(tcx, impl_def_id, OrphanCheckMode::Compat) {
32 Ok(()) => match err {
33 OrphanCheckErr::UncoveredTyParams(uncovered_ty_params) => {
34 let hir_id = tcx.local_def_id_to_hir_id(impl_def_id);
35
36 for param_def_id in uncovered_ty_params.uncovered {
37 let ident = tcx.item_ident(param_def_id);
38
39 tcx.emit_node_span_lint(
40 UNCOVERED_PARAM_IN_PROJECTION,
41 hir_id,
42 ident.span,
43 diagnostics::UncoveredTyParam {
44 param: ident,
45 local_ty: uncovered_ty_params.local_ty,
46 },
47 );
48 }
49 }
50 OrphanCheckErr::NonLocalInputType(_) => {
51 bug!("orphanck: shouldn't've gotten non-local input tys in compat mode")
52 }
53 },
54 Err(err) => return Err(emit_orphan_check_error(tcx, trait_ref, impl_def_id, err)),
55 },
56 }
57
58 let trait_def_id = trait_ref.def_id;
59
60 debug!(
93 "trait_ref={:?} trait_def_id={:?} trait_is_auto={}",
94 trait_ref,
95 trait_def_id,
96 tcx.trait_is_auto(trait_def_id)
97 );
98
99 if tcx.trait_is_auto(trait_def_id) {
100 let self_ty = tcx.expand_free_alias_tys(trait_ref.self_ty());
101
102 enum LocalImpl {
138 Allow,
139 Disallow { problematic_kind: &'static str },
140 }
141
142 enum NonlocalImpl {
150 Allow,
151 DisallowBecauseNonlocal,
152 DisallowOther,
153 }
154
155 let (local_impl, nonlocal_impl) = match self_ty.kind() {
158 ty::Adt(self_def, _) => (
161 LocalImpl::Allow,
162 if self_def.did().is_local() {
163 NonlocalImpl::Allow
164 } else {
165 NonlocalImpl::DisallowBecauseNonlocal
166 },
167 ),
168
169 ty::Foreign(did) => (
172 LocalImpl::Allow,
173 if did.is_local() {
174 NonlocalImpl::Allow
175 } else {
176 NonlocalImpl::DisallowBecauseNonlocal
177 },
178 ),
179
180 ty::Dynamic(..) => (
182 LocalImpl::Disallow { problematic_kind: "trait object" },
183 NonlocalImpl::DisallowOther,
184 ),
185
186 ty::Param(..) => (
189 if self_ty.is_sized(tcx, ty::TypingEnv::non_body_analysis(tcx, impl_def_id)) {
190 LocalImpl::Allow
191 } else {
192 LocalImpl::Disallow { problematic_kind: "generic type" }
193 },
194 NonlocalImpl::DisallowOther,
195 ),
196
197 ty::Alias(_, ty::AliasTy { kind, .. }) => {
198 let problematic_kind = match kind {
199 ty::Projection { .. } => "associated type",
205 ty::Free { .. } => "type alias",
208 ty::Opaque { .. } => "opaque type",
211 ty::Inherent { .. } => "associated type",
220 };
221 (LocalImpl::Disallow { problematic_kind }, NonlocalImpl::DisallowOther)
222 }
223
224 ty::Bool
225 | ty::Pat(..)
226 | ty::Char
227 | ty::Int(..)
228 | ty::Uint(..)
229 | ty::Float(..)
230 | ty::Str
231 | ty::Array(..)
232 | ty::Slice(..)
233 | ty::RawPtr(..)
234 | ty::Ref(..)
235 | ty::FnPtr(..)
236 | ty::Never
237 | ty::Tuple(..)
238 | ty::UnsafeBinder(_) => (LocalImpl::Allow, NonlocalImpl::DisallowOther),
239
240 ty::FnDef(..)
241 | ty::Closure(..)
242 | ty::CoroutineClosure(..)
243 | ty::Coroutine(..)
244 | ty::CoroutineWitness(..)
245 | ty::Bound(..)
246 | ty::Placeholder(..)
247 | ty::Infer(..) => {
248 let sp = tcx.def_span(impl_def_id);
249 span_bug!(sp, "weird self type for autotrait impl")
250 }
251
252 ty::Error(..) => (LocalImpl::Allow, NonlocalImpl::Allow),
253 };
254
255 if trait_def_id.is_local() {
256 match local_impl {
257 LocalImpl::Allow => {}
258 LocalImpl::Disallow { problematic_kind } => {
259 return Err(tcx.dcx().emit_err(diagnostics::TraitsWithDefaultImpl {
260 span: tcx.def_span(impl_def_id),
261 traits: tcx.def_path_str(trait_def_id),
262 problematic_kind,
263 self_ty,
264 }));
265 }
266 }
267 } else {
268 match nonlocal_impl {
269 NonlocalImpl::Allow => {}
270 NonlocalImpl::DisallowBecauseNonlocal => {
271 return Err(tcx.dcx().emit_err(diagnostics::CrossCrateTraitsDefined {
272 span: tcx.def_span(impl_def_id),
273 traits: tcx.def_path_str(trait_def_id),
274 }));
275 }
276 NonlocalImpl::DisallowOther => {
277 return Err(tcx.dcx().emit_err(diagnostics::CrossCrateTraits {
278 span: tcx.def_span(impl_def_id),
279 traits: tcx.def_path_str(trait_def_id),
280 self_ty,
281 }));
282 }
283 }
284 }
285 }
286
287 Ok(())
288}
289
290{}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("orphan_check",
"rustc_hir_analysis::coherence::orphan",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/coherence/orphan.rs"),
::tracing_core::__macro_support::Option::Some(298u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::orphan"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("impl_def_id")
}> =
::tracing::__macro_support::FieldName::new("impl_def_id");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("mode")
}> =
::tracing::__macro_support::FieldName::new("mode");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&impl_def_id)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&mode)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
Result<(),
OrphanCheckErr<TyCtxt<'tcx>, FxIndexSet<DefId>>> = loop {};
return __tracing_attr_fake_return;
}
{
let trait_ref = tcx.impl_trait_ref(impl_def_id);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/coherence/orphan.rs:307",
"rustc_hir_analysis::coherence::orphan",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/coherence/orphan.rs"),
::tracing_core::__macro_support::Option::Some(307u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::orphan"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("trait_ref")
}> =
::tracing::__macro_support::FieldName::new("trait_ref");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&trait_ref.skip_binder())
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
if let Some(def_id) =
trait_ref.skip_binder().def_id.as_local() {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/coherence/orphan.rs:311",
"rustc_hir_analysis::coherence::orphan",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/coherence/orphan.rs"),
::tracing_core::__macro_support::Option::Some(311u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::orphan"),
::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!("trait {0:?} is local to current crate",
def_id) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
return Ok(());
}
let infcx =
tcx.infer_ctxt().with_next_trait_solver(true).enable_next_solver_overflow_fcw(false).build(TypingMode::Coherence);
let cause = traits::ObligationCause::dummy();
let args =
infcx.fresh_args_for_item(cause.span,
impl_def_id.to_def_id());
let trait_ref =
trait_ref.instantiate(tcx, args).skip_norm_wip();
let lazily_normalize_ty =
|user_ty: Ty<'tcx>|
{
let ty::Alias(..) =
user_ty.kind() else { return Ok(user_ty) };
let ocx = traits::ObligationCtxt::new(&infcx);
let ty =
ocx.normalize(&cause, ty::ParamEnv::empty(),
Unnormalized::new_wip(user_ty));
let ty = infcx.deeply_resolve_ignoring_regions(ty);
let errors = ocx.try_evaluate_obligations();
if !errors.no_errors() { return Ok(user_ty); }
Ok::<_, !>(ty)
};
let result =
traits::orphan_check_trait_ref(&infcx, trait_ref,
traits::InCrate::Local { mode },
lazily_normalize_ty).into_ok();
result.map_err(|err|
match err {
OrphanCheckErr::UncoveredTyParams(UncoveredTyParams {
uncovered, local_ty }) => {
let mut collector =
UncoveredTyParamCollector {
infcx: &infcx,
uncovered_params: Default::default(),
};
uncovered.visit_with(&mut collector);
if true {
if !!collector.uncovered_params.is_empty() {
::core::panicking::panic("assertion failed: !collector.uncovered_params.is_empty()")
};
};
OrphanCheckErr::UncoveredTyParams(UncoveredTyParams {
uncovered: collector.uncovered_params,
local_ty,
})
}
OrphanCheckErr::NonLocalInputType(tys) => {
let tys =
infcx.probe(|_|
{
for (arg, id_arg) in
std::iter::zip(args,
ty::GenericArgs::identity_for_item(tcx, impl_def_id)) {
let _ =
infcx.at(&cause,
ty::ParamEnv::empty()).eq(DefineOpaqueTypes::No, arg,
id_arg);
}
infcx.deeply_resolve_ignoring_regions(tys)
});
OrphanCheckErr::NonLocalInputType(tys)
}
})
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/coherence/orphan.rs:298",
"rustc_hir_analysis::coherence::orphan",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/3ef0c22cdb86ac42dc6b8f0f1ec36857daa6f2a1/compiler/rustc_hir_analysis/src/coherence/orphan.rs"),
::tracing_core::__macro_support::Option::Some(298u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::coherence::orphan"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "debug", skip(tcx), ret)]
299fn orphan_check<'tcx>(
300 tcx: TyCtxt<'tcx>,
301 impl_def_id: LocalDefId,
302 mode: OrphanCheckMode,
303) -> Result<(), OrphanCheckErr<TyCtxt<'tcx>, FxIndexSet<DefId>>> {
304 let trait_ref = tcx.impl_trait_ref(impl_def_id);
307 debug!(trait_ref = ?trait_ref.skip_binder());
308
309 if let Some(def_id) = trait_ref.skip_binder().def_id.as_local() {
311 debug!("trait {def_id:?} is local to current crate");
312 return Ok(());
313 }
314
315 let infcx = tcx
317 .infer_ctxt()
318 .with_next_trait_solver(true)
319 .enable_next_solver_overflow_fcw(false)
320 .build(TypingMode::Coherence);
321 let cause = traits::ObligationCause::dummy();
322 let args = infcx.fresh_args_for_item(cause.span, impl_def_id.to_def_id());
323 let trait_ref = trait_ref.instantiate(tcx, args).skip_norm_wip();
324
325 let lazily_normalize_ty = |user_ty: Ty<'tcx>| {
326 let ty::Alias(..) = user_ty.kind() else { return Ok(user_ty) };
327
328 let ocx = traits::ObligationCtxt::new(&infcx);
329 let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), Unnormalized::new_wip(user_ty));
330 let ty = infcx.deeply_resolve_ignoring_regions(ty);
331 let errors = ocx.try_evaluate_obligations();
332 if !errors.no_errors() {
333 return Ok(user_ty);
334 }
335
336 Ok::<_, !>(ty)
337 };
338
339 let result = traits::orphan_check_trait_ref(
340 &infcx,
341 trait_ref,
342 traits::InCrate::Local { mode },
343 lazily_normalize_ty,
344 )
345 .into_ok();
346
347 result.map_err(|err| match err {
349 OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered, local_ty }) => {
350 let mut collector =
351 UncoveredTyParamCollector { infcx: &infcx, uncovered_params: Default::default() };
352 uncovered.visit_with(&mut collector);
353 debug_assert!(!collector.uncovered_params.is_empty());
355
356 OrphanCheckErr::UncoveredTyParams(UncoveredTyParams {
357 uncovered: collector.uncovered_params,
358 local_ty,
359 })
360 }
361 OrphanCheckErr::NonLocalInputType(tys) => {
362 let tys = infcx.probe(|_| {
363 for (arg, id_arg) in
366 std::iter::zip(args, ty::GenericArgs::identity_for_item(tcx, impl_def_id))
367 {
368 let _ = infcx.at(&cause, ty::ParamEnv::empty()).eq(
369 DefineOpaqueTypes::No,
370 arg,
371 id_arg,
372 );
373 }
374 infcx.deeply_resolve_ignoring_regions(tys)
375 });
376 OrphanCheckErr::NonLocalInputType(tys)
377 }
378 })
379}
380
381fn emit_orphan_check_error<'tcx>(
382 tcx: TyCtxt<'tcx>,
383 trait_ref: ty::TraitRef<'tcx>,
384 impl_def_id: LocalDefId,
385 err: traits::OrphanCheckErr<TyCtxt<'tcx>, FxIndexSet<DefId>>,
386) -> ErrorGuaranteed {
387 match err {
388 traits::OrphanCheckErr::NonLocalInputType(tys) => {
389 let item = tcx.hir_expect_item(impl_def_id);
390 let impl_ = item.expect_impl();
391 let of_trait = impl_.of_trait.unwrap();
392
393 let span = tcx.def_span(impl_def_id);
394 let mut diag = tcx.dcx().create_err(match trait_ref.self_ty().kind() {
395 ty::Adt(..) => diagnostics::OnlyCurrentTraits::Outside { span, note: () },
396 _ if trait_ref.self_ty().is_primitive() => {
397 diagnostics::OnlyCurrentTraits::Primitive { span, note: () }
398 }
399 _ => diagnostics::OnlyCurrentTraits::Arbitrary { span, note: () },
400 });
401
402 for &(mut ty, is_target_ty) in &tys {
403 let span = if #[allow(non_exhaustive_omitted_patterns)] match is_target_ty {
IsFirstInputType::Yes => true,
_ => false,
}matches!(is_target_ty, IsFirstInputType::Yes) {
404 impl_.self_ty.span
406 } else {
407 of_trait.trait_ref.path.span
409 };
410
411 ty = tcx.erase_and_anonymize_regions(ty);
412
413 let is_foreign =
414 !trait_ref.def_id.is_local() && #[allow(non_exhaustive_omitted_patterns)] match is_target_ty {
IsFirstInputType::No => true,
_ => false,
}matches!(is_target_ty, IsFirstInputType::No);
415
416 match *ty.kind() {
417 ty::Slice(_) => {
418 if is_foreign {
419 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsForeign { span });
420 } else {
421 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsName {
422 span,
423 name: "slices",
424 });
425 }
426 }
427 ty::Array(..) => {
428 if is_foreign {
429 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsForeign { span });
430 } else {
431 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsName {
432 span,
433 name: "arrays",
434 });
435 }
436 }
437 ty::Tuple(..) => {
438 if is_foreign {
439 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsForeign { span });
440 } else {
441 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsName {
442 span,
443 name: "tuples",
444 });
445 }
446 }
447 ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. }) => {
448 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsOpaque { span });
449 }
450 ty::RawPtr(ptr_ty, mutbl) => {
451 if !trait_ref.self_ty().has_param() {
452 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsPointerSugg {
453 wrapper_span: impl_.self_ty.span,
454 struct_span: item.span.shrink_to_lo(),
455 mut_key: mutbl.prefix_str(),
456 ptr_ty,
457 });
458 }
459 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsPointer {
460 span,
461 pointer: ty,
462 });
463 }
464 ty::Adt(adt_def, _) => {
465 if is_foreign {
466 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsForeign { span });
467 } else {
468 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsAdt {
469 span,
470 name: tcx.def_path_str(adt_def.did()),
471 });
472 }
473 }
474 _ => {
475 if is_foreign {
476 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsForeign { span });
477 } else {
478 diag.subdiagnostic(diagnostics::OnlyCurrentTraitsTy { span, ty });
479 }
480 }
481 }
482 }
483
484 diag.emit_err()
485 }
486 traits::OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered, local_ty }) => {
487 let mut guar = None;
488 for param_def_id in uncovered {
489 guar.get_or_insert(tcx.dcx().emit_err(diagnostics::UncoveredTyParam {
490 param: tcx.item_ident(param_def_id),
491 local_ty,
492 }));
493 }
494 guar.unwrap()
495 }
496 }
497}
498
499struct UncoveredTyParamCollector<'cx, 'tcx> {
500 infcx: &'cx InferCtxt<'tcx>,
501 uncovered_params: FxIndexSet<DefId>,
502}
503
504impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UncoveredTyParamCollector<'_, 'tcx> {
505 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
506 if !ty.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
507 return;
508 }
509 let ty::Infer(ty::TyVar(vid)) = *ty.kind() else {
510 return ty.super_visit_with(self);
511 };
512 let origin = self.infcx.type_var_origin(vid);
513 if let Some(def_id) = origin.param_def_id {
514 self.uncovered_params.insert(def_id);
515 }
516 }
517
518 fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
519 if ct.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
520 ct.super_visit_with(self)
521 }
522 }
523}