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_middle::{bug, span_bug};
13use rustc_span::def_id::{DefId, LocalDefId};
14use rustc_trait_selection::traits::{
15 self, IsFirstInputType, OrphanCheckErr, OrphanCheckMode, UncoveredTyParams,
16};
17use tracing::{debug, instrument};
18
19use crate::errors;
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("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(&["impl_def_id"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&impl_def_id)
as &dyn 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) => {
lint_uncovered_ty_params(tcx, uncovered_ty_params,
impl_def_id)
}
OrphanCheckErr::NonLocalInputType(_) => {
::rustc_middle::util::bug::bug_fmt(format_args!("orphanck: shouldn\'t\'ve gotten non-local input tys in compat mode"))
}
},
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 compiler/rustc_hir_analysis/src/coherence/orphan.rs:78",
"rustc_hir_analysis::coherence::orphan",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/coherence/orphan.rs"),
::tracing_core::__macro_support::Option::Some(78u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::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 Value))])
});
} else { ; }
};
if tcx.trait_is_auto(trait_def_id) {
let self_ty = 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_middle::util::bug::span_bug_fmt(sp,
format_args!("weird self type for autotrait impl"))
}
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(errors::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(errors::CrossCrateTraitsDefined {
span: tcx.def_span(impl_def_id),
traits: tcx.def_path_str(trait_def_id),
}));
}
NonlocalImpl::DisallowOther => {
return Err(tcx.dcx().emit_err(errors::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 lint_uncovered_ty_params(tcx, uncovered_ty_params, impl_def_id)
35 }
36 OrphanCheckErr::NonLocalInputType(_) => {
37 bug!("orphanck: shouldn't've gotten non-local input tys in compat mode")
38 }
39 },
40 Err(err) => return Err(emit_orphan_check_error(tcx, trait_ref, impl_def_id, err)),
41 },
42 }
43
44 let trait_def_id = trait_ref.def_id;
45
46 debug!(
79 "trait_ref={:?} trait_def_id={:?} trait_is_auto={}",
80 trait_ref,
81 trait_def_id,
82 tcx.trait_is_auto(trait_def_id)
83 );
84
85 if tcx.trait_is_auto(trait_def_id) {
86 let self_ty = trait_ref.self_ty();
87
88 enum LocalImpl {
124 Allow,
125 Disallow { problematic_kind: &'static str },
126 }
127
128 enum NonlocalImpl {
136 Allow,
137 DisallowBecauseNonlocal,
138 DisallowOther,
139 }
140
141 let (local_impl, nonlocal_impl) = match self_ty.kind() {
144 ty::Adt(self_def, _) => (
147 LocalImpl::Allow,
148 if self_def.did().is_local() {
149 NonlocalImpl::Allow
150 } else {
151 NonlocalImpl::DisallowBecauseNonlocal
152 },
153 ),
154
155 ty::Foreign(did) => (
158 LocalImpl::Allow,
159 if did.is_local() {
160 NonlocalImpl::Allow
161 } else {
162 NonlocalImpl::DisallowBecauseNonlocal
163 },
164 ),
165
166 ty::Dynamic(..) => (
168 LocalImpl::Disallow { problematic_kind: "trait object" },
169 NonlocalImpl::DisallowOther,
170 ),
171
172 ty::Param(..) => (
175 if self_ty.is_sized(tcx, ty::TypingEnv::non_body_analysis(tcx, impl_def_id)) {
176 LocalImpl::Allow
177 } else {
178 LocalImpl::Disallow { problematic_kind: "generic type" }
179 },
180 NonlocalImpl::DisallowOther,
181 ),
182
183 ty::Alias(ty::AliasTy { kind, .. }) => {
184 let problematic_kind = match kind {
185 ty::Projection { .. } => "associated type",
191 ty::Free { .. } => "type alias",
194 ty::Opaque { .. } => "opaque type",
197 ty::Inherent { .. } => "associated type",
206 };
207 (LocalImpl::Disallow { problematic_kind }, NonlocalImpl::DisallowOther)
208 }
209
210 ty::Bool
211 | ty::Pat(..)
212 | ty::Char
213 | ty::Int(..)
214 | ty::Uint(..)
215 | ty::Float(..)
216 | ty::Str
217 | ty::Array(..)
218 | ty::Slice(..)
219 | ty::RawPtr(..)
220 | ty::Ref(..)
221 | ty::FnPtr(..)
222 | ty::Never
223 | ty::Tuple(..)
224 | ty::UnsafeBinder(_) => (LocalImpl::Allow, NonlocalImpl::DisallowOther),
225
226 ty::FnDef(..)
227 | ty::Closure(..)
228 | ty::CoroutineClosure(..)
229 | ty::Coroutine(..)
230 | ty::CoroutineWitness(..)
231 | ty::Bound(..)
232 | ty::Placeholder(..)
233 | ty::Infer(..) => {
234 let sp = tcx.def_span(impl_def_id);
235 span_bug!(sp, "weird self type for autotrait impl")
236 }
237
238 ty::Error(..) => (LocalImpl::Allow, NonlocalImpl::Allow),
239 };
240
241 if trait_def_id.is_local() {
242 match local_impl {
243 LocalImpl::Allow => {}
244 LocalImpl::Disallow { problematic_kind } => {
245 return Err(tcx.dcx().emit_err(errors::TraitsWithDefaultImpl {
246 span: tcx.def_span(impl_def_id),
247 traits: tcx.def_path_str(trait_def_id),
248 problematic_kind,
249 self_ty,
250 }));
251 }
252 }
253 } else {
254 match nonlocal_impl {
255 NonlocalImpl::Allow => {}
256 NonlocalImpl::DisallowBecauseNonlocal => {
257 return Err(tcx.dcx().emit_err(errors::CrossCrateTraitsDefined {
258 span: tcx.def_span(impl_def_id),
259 traits: tcx.def_path_str(trait_def_id),
260 }));
261 }
262 NonlocalImpl::DisallowOther => {
263 return Err(tcx.dcx().emit_err(errors::CrossCrateTraits {
264 span: tcx.def_span(impl_def_id),
265 traits: tcx.def_path_str(trait_def_id),
266 self_ty,
267 }));
268 }
269 }
270 }
271 }
272
273 Ok(())
274}
275
276x;#[instrument(level = "debug", skip(tcx), ret)]
285fn orphan_check<'tcx>(
286 tcx: TyCtxt<'tcx>,
287 impl_def_id: LocalDefId,
288 mode: OrphanCheckMode,
289) -> Result<(), OrphanCheckErr<TyCtxt<'tcx>, FxIndexSet<DefId>>> {
290 let trait_ref = tcx.impl_trait_ref(impl_def_id);
293 debug!(trait_ref = ?trait_ref.skip_binder());
294
295 if let Some(def_id) = trait_ref.skip_binder().def_id.as_local() {
297 debug!("trait {def_id:?} is local to current crate");
298 return Ok(());
299 }
300
301 let infcx = tcx.infer_ctxt().build(TypingMode::Coherence);
303 let cause = traits::ObligationCause::dummy();
304 let args = infcx.fresh_args_for_item(cause.span, impl_def_id.to_def_id());
305 let trait_ref = trait_ref.instantiate(tcx, args).skip_norm_wip();
306
307 let lazily_normalize_ty = |user_ty: Ty<'tcx>| {
308 let ty::Alias(..) = user_ty.kind() else { return Ok(user_ty) };
309
310 let ocx = traits::ObligationCtxt::new(&infcx);
311 let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), Unnormalized::new_wip(user_ty));
312 let ty = infcx.resolve_vars_if_possible(ty);
313 let errors = ocx.try_evaluate_obligations();
314 if !errors.is_empty() {
315 return Ok(user_ty);
316 }
317
318 let ty = if infcx.next_trait_solver() {
319 ocx.structurally_normalize_ty(
320 &cause,
321 ty::ParamEnv::empty(),
322 Unnormalized::new_wip(infcx.resolve_vars_if_possible(ty)),
323 )
324 .unwrap_or(ty)
325 } else {
326 ty
327 };
328
329 Ok::<_, !>(ty)
330 };
331
332 let result = traits::orphan_check_trait_ref(
333 &infcx,
334 trait_ref,
335 traits::InCrate::Local { mode },
336 lazily_normalize_ty,
337 )
338 .into_ok();
339
340 result.map_err(|err| match err {
342 OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered, local_ty }) => {
343 let mut collector =
344 UncoveredTyParamCollector { infcx: &infcx, uncovered_params: Default::default() };
345 uncovered.visit_with(&mut collector);
346 debug_assert!(!collector.uncovered_params.is_empty());
348
349 OrphanCheckErr::UncoveredTyParams(UncoveredTyParams {
350 uncovered: collector.uncovered_params,
351 local_ty,
352 })
353 }
354 OrphanCheckErr::NonLocalInputType(tys) => {
355 let tys = infcx.probe(|_| {
356 for (arg, id_arg) in
359 std::iter::zip(args, ty::GenericArgs::identity_for_item(tcx, impl_def_id))
360 {
361 let _ = infcx.at(&cause, ty::ParamEnv::empty()).eq(
362 DefineOpaqueTypes::No,
363 arg,
364 id_arg,
365 );
366 }
367 infcx.resolve_vars_if_possible(tys)
368 });
369 OrphanCheckErr::NonLocalInputType(tys)
370 }
371 })
372}
373
374fn emit_orphan_check_error<'tcx>(
375 tcx: TyCtxt<'tcx>,
376 trait_ref: ty::TraitRef<'tcx>,
377 impl_def_id: LocalDefId,
378 err: traits::OrphanCheckErr<TyCtxt<'tcx>, FxIndexSet<DefId>>,
379) -> ErrorGuaranteed {
380 match err {
381 traits::OrphanCheckErr::NonLocalInputType(tys) => {
382 let item = tcx.hir_expect_item(impl_def_id);
383 let impl_ = item.expect_impl();
384 let of_trait = impl_.of_trait.unwrap();
385
386 let span = tcx.def_span(impl_def_id);
387 let mut diag = tcx.dcx().create_err(match trait_ref.self_ty().kind() {
388 ty::Adt(..) => errors::OnlyCurrentTraits::Outside { span, note: () },
389 _ if trait_ref.self_ty().is_primitive() => {
390 errors::OnlyCurrentTraits::Primitive { span, note: () }
391 }
392 _ => errors::OnlyCurrentTraits::Arbitrary { span, note: () },
393 });
394
395 for &(mut ty, is_target_ty) in &tys {
396 let span = if #[allow(non_exhaustive_omitted_patterns)] match is_target_ty {
IsFirstInputType::Yes => true,
_ => false,
}matches!(is_target_ty, IsFirstInputType::Yes) {
397 impl_.self_ty.span
399 } else {
400 of_trait.trait_ref.path.span
402 };
403
404 ty = tcx.erase_and_anonymize_regions(ty);
405
406 let is_foreign =
407 !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);
408
409 match *ty.kind() {
410 ty::Slice(_) => {
411 if is_foreign {
412 diag.subdiagnostic(errors::OnlyCurrentTraitsForeign { span });
413 } else {
414 diag.subdiagnostic(errors::OnlyCurrentTraitsName {
415 span,
416 name: "slices",
417 });
418 }
419 }
420 ty::Array(..) => {
421 if is_foreign {
422 diag.subdiagnostic(errors::OnlyCurrentTraitsForeign { span });
423 } else {
424 diag.subdiagnostic(errors::OnlyCurrentTraitsName {
425 span,
426 name: "arrays",
427 });
428 }
429 }
430 ty::Tuple(..) => {
431 if is_foreign {
432 diag.subdiagnostic(errors::OnlyCurrentTraitsForeign { span });
433 } else {
434 diag.subdiagnostic(errors::OnlyCurrentTraitsName {
435 span,
436 name: "tuples",
437 });
438 }
439 }
440 ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) => {
441 diag.subdiagnostic(errors::OnlyCurrentTraitsOpaque { span });
442 }
443 ty::RawPtr(ptr_ty, mutbl) => {
444 if !trait_ref.self_ty().has_param() {
445 diag.subdiagnostic(errors::OnlyCurrentTraitsPointerSugg {
446 wrapper_span: impl_.self_ty.span,
447 struct_span: item.span.shrink_to_lo(),
448 mut_key: mutbl.prefix_str(),
449 ptr_ty,
450 });
451 }
452 diag.subdiagnostic(errors::OnlyCurrentTraitsPointer { span, pointer: ty });
453 }
454 ty::Adt(adt_def, _) => {
455 diag.subdiagnostic(errors::OnlyCurrentTraitsAdt {
456 span,
457 name: tcx.def_path_str(adt_def.did()),
458 });
459 }
460 _ => {
461 diag.subdiagnostic(errors::OnlyCurrentTraitsTy { span, ty });
462 }
463 }
464 }
465
466 diag.emit()
467 }
468 traits::OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered, local_ty }) => {
469 let mut reported = None;
470 for param_def_id in uncovered {
471 let name = tcx.item_ident(param_def_id);
472 let span = name.span;
473
474 reported.get_or_insert(match local_ty {
475 Some(local_type) => tcx.dcx().emit_err(errors::TyParamFirstLocal {
476 span,
477 note: (),
478 param: name,
479 local_type,
480 }),
481 None => tcx.dcx().emit_err(errors::TyParamSome { span, note: (), param: name }),
482 });
483 }
484 reported.unwrap() }
486 }
487}
488
489fn lint_uncovered_ty_params<'tcx>(
490 tcx: TyCtxt<'tcx>,
491 UncoveredTyParams { uncovered, local_ty }: UncoveredTyParams<TyCtxt<'tcx>, FxIndexSet<DefId>>,
492 impl_def_id: LocalDefId,
493) {
494 let hir_id = tcx.local_def_id_to_hir_id(impl_def_id);
495
496 for param_def_id in uncovered {
497 let span = tcx.def_ident_span(param_def_id).unwrap();
498 let name = tcx.item_ident(param_def_id);
499
500 match local_ty {
501 Some(local_type) => tcx.emit_node_span_lint(
502 UNCOVERED_PARAM_IN_PROJECTION,
503 hir_id,
504 span,
505 errors::TyParamFirstLocalLint { span, note: (), param: name, local_type },
506 ),
507 None => tcx.emit_node_span_lint(
508 UNCOVERED_PARAM_IN_PROJECTION,
509 hir_id,
510 span,
511 errors::TyParamSomeLint { span, note: (), param: name },
512 ),
513 };
514 }
515}
516
517struct UncoveredTyParamCollector<'cx, 'tcx> {
518 infcx: &'cx InferCtxt<'tcx>,
519 uncovered_params: FxIndexSet<DefId>,
520}
521
522impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UncoveredTyParamCollector<'_, 'tcx> {
523 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
524 if !ty.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
525 return;
526 }
527 let ty::Infer(ty::TyVar(vid)) = *ty.kind() else {
528 return ty.super_visit_with(self);
529 };
530 let origin = self.infcx.type_var_origin(vid);
531 if let Some(def_id) = origin.param_def_id {
532 self.uncovered_params.insert(def_id);
533 }
534 }
535
536 fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
537 if ct.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
538 ct.super_visit_with(self)
539 }
540 }
541}