1 use crate::autoderef
::Autoderef
;
2 use crate::constrained_generic_params
::{identify_constrained_generic_params, Parameter}
;
6 use rustc_data_structures
::fx
::{FxHashMap, FxHashSet, FxIndexSet}
;
7 use rustc_errors
::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}
;
9 use rustc_hir
::def_id
::{DefId, LocalDefId}
;
10 use rustc_hir
::lang_items
::LangItem
;
11 use rustc_hir
::ItemKind
;
12 use rustc_infer
::infer
::outlives
::env
::{OutlivesEnvironment, RegionBoundPairs}
;
13 use rustc_infer
::infer
::outlives
::obligations
::TypeOutlives
;
14 use rustc_infer
::infer
::{self, InferCtxt, TyCtxtInferExt}
;
15 use rustc_middle
::mir
::ConstraintCategory
;
16 use rustc_middle
::ty
::query
::Providers
;
17 use rustc_middle
::ty
::trait_def
::TraitSpecializationKind
;
18 use rustc_middle
::ty
::{
19 self, AdtKind
, DefIdTree
, GenericParamDefKind
, Ty
, TyCtxt
, TypeFoldable
, TypeSuperVisitable
,
20 TypeVisitable
, TypeVisitor
,
22 use rustc_middle
::ty
::{GenericArgKind, InternalSubsts}
;
23 use rustc_session
::parse
::feature_err
;
24 use rustc_span
::symbol
::{sym, Ident, Symbol}
;
25 use rustc_span
::{Span, DUMMY_SP}
;
26 use rustc_target
::spec
::abi
::Abi
;
27 use rustc_trait_selection
::traits
::error_reporting
::TypeErrCtxtExt
;
28 use rustc_trait_selection
::traits
::outlives_bounds
::InferCtxtExt
as _
;
29 use rustc_trait_selection
::traits
::query
::evaluate_obligation
::InferCtxtExt
as _
;
30 use rustc_trait_selection
::traits
::{
31 self, ObligationCause
, ObligationCauseCode
, ObligationCtxt
, WellFormedLoc
,
34 use std
::cell
::LazyCell
;
35 use std
::ops
::{ControlFlow, Deref}
;
37 pub(super) struct WfCheckingCtxt
<'a
, 'tcx
> {
38 pub(super) ocx
: ObligationCtxt
<'a
, 'tcx
>,
41 param_env
: ty
::ParamEnv
<'tcx
>,
43 impl<'a
, 'tcx
> Deref
for WfCheckingCtxt
<'a
, 'tcx
> {
44 type Target
= ObligationCtxt
<'a
, 'tcx
>;
45 fn deref(&self) -> &Self::Target
{
50 impl<'tcx
> WfCheckingCtxt
<'_
, 'tcx
> {
51 fn tcx(&self) -> TyCtxt
<'tcx
> {
55 // Convenience function to normalize during wfcheck. This performs
56 // `ObligationCtxt::normalize`, but provides a nice `ObligationCauseCode`.
57 fn normalize
<T
>(&self, span
: Span
, loc
: Option
<WellFormedLoc
>, value
: T
) -> T
59 T
: TypeFoldable
<'tcx
>,
62 &ObligationCause
::new(span
, self.body_id
, ObligationCauseCode
::WellFormed(loc
)),
68 fn register_wf_obligation(
71 loc
: Option
<WellFormedLoc
>,
72 arg
: ty
::GenericArg
<'tcx
>,
75 traits
::ObligationCause
::new(span
, self.body_id
, ObligationCauseCode
::WellFormed(loc
));
76 // for a type to be WF, we do not need to check if const trait predicates satisfy.
77 let param_env
= self.param_env
.without_const();
78 self.ocx
.register_obligation(traits
::Obligation
::new(
82 ty
::Binder
::dummy(ty
::PredicateKind
::WellFormed(arg
)),
87 pub(super) fn enter_wf_checking_ctxt
<'tcx
, F
>(
90 body_def_id
: LocalDefId
,
93 F
: for<'a
> FnOnce(&WfCheckingCtxt
<'a
, 'tcx
>),
95 let param_env
= tcx
.param_env(body_def_id
);
96 let body_id
= tcx
.hir().local_def_id_to_hir_id(body_def_id
);
97 let infcx
= &tcx
.infer_ctxt().build();
98 let ocx
= ObligationCtxt
::new(infcx
);
100 let mut wfcx
= WfCheckingCtxt { ocx, span, body_id, param_env }
;
102 if !tcx
.features().trivial_bounds
{
103 wfcx
.check_false_global_bounds()
107 let assumed_wf_types
= wfcx
.ocx
.assumed_wf_types(param_env
, span
, body_def_id
);
108 let implied_bounds
= infcx
.implied_bounds_tys(param_env
, body_id
, assumed_wf_types
);
110 let errors
= wfcx
.select_all_or_error();
111 if !errors
.is_empty() {
112 infcx
.err_ctxt().report_fulfillment_errors(&errors
, None
);
116 let outlives_environment
=
117 OutlivesEnvironment
::with_bounds(param_env
, Some(infcx
), implied_bounds
);
121 .check_region_obligations_and_report_errors(body_def_id
, &outlives_environment
);
124 fn check_well_formed(tcx
: TyCtxt
<'_
>, def_id
: hir
::OwnerId
) {
125 let node
= tcx
.hir().owner(def_id
);
127 hir
::OwnerNode
::Crate(_
) => {}
128 hir
::OwnerNode
::Item(item
) => check_item(tcx
, item
),
129 hir
::OwnerNode
::TraitItem(item
) => check_trait_item(tcx
, item
),
130 hir
::OwnerNode
::ImplItem(item
) => check_impl_item(tcx
, item
),
131 hir
::OwnerNode
::ForeignItem(item
) => check_foreign_item(tcx
, item
),
134 if let Some(generics
) = node
.generics() {
135 for param
in generics
.params
{
136 check_param_wf(tcx
, param
)
141 /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
142 /// well-formed, meaning that they do not require any constraints not declared in the struct
143 /// definition itself. For example, this definition would be illegal:
146 /// struct Ref<'a, T> { x: &'a T }
149 /// because the type did not declare that `T:'a`.
151 /// We do this check as a pre-pass before checking fn bodies because if these constraints are
152 /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
154 #[instrument(skip(tcx), level = "debug")]
155 fn check_item
<'tcx
>(tcx
: TyCtxt
<'tcx
>, item
: &'tcx hir
::Item
<'tcx
>) {
156 let def_id
= item
.owner_id
.def_id
;
160 item
.name
= ? tcx
.def_path_str(def_id
.to_def_id())
164 // Right now we check that every default trait implementation
165 // has an implementation of itself. Basically, a case like:
167 // impl Trait for T {}
169 // has a requirement of `T: Trait` which was required for default
170 // method implementations. Although this could be improved now that
171 // there's a better infrastructure in place for this, it's being left
172 // for a follow-up work.
174 // Since there's such a requirement, we need to check *just* positive
175 // implementations, otherwise things like:
177 // impl !Send for T {}
179 // won't be allowed unless there's an *explicit* implementation of `Send`
181 hir
::ItemKind
::Impl(impl_
) => {
183 .impl_trait_ref(def_id
)
184 .map_or(false, |trait_ref
| tcx
.trait_is_auto(trait_ref
.skip_binder().def_id
));
185 if let (hir
::Defaultness
::Default { .. }
, true) = (impl_
.defaultness
, is_auto
) {
186 let sp
= impl_
.of_trait
.as_ref().map_or(item
.span
, |t
| t
.path
.span
);
188 tcx
.sess
.struct_span_err(sp
, "impls of auto traits cannot be default");
189 err
.span_labels(impl_
.defaultness_span
, "default because of this");
190 err
.span_label(sp
, "auto trait");
193 // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
194 match (tcx
.impl_polarity(def_id
), impl_
.polarity
) {
195 (ty
::ImplPolarity
::Positive
, _
) => {
196 check_impl(tcx
, item
, impl_
.self_ty
, &impl_
.of_trait
, impl_
.constness
);
198 (ty
::ImplPolarity
::Negative
, ast
::ImplPolarity
::Negative(span
)) => {
199 // FIXME(#27579): what amount of WF checking do we need for neg impls?
200 if let hir
::Defaultness
::Default { .. }
= impl_
.defaultness
{
201 let mut spans
= vec
![span
];
202 spans
.extend(impl_
.defaultness_span
);
207 "negative impls cannot be default impls"
212 (ty
::ImplPolarity
::Reservation
, _
) => {
213 // FIXME: what amount of WF checking do we need for reservation impls?
218 hir
::ItemKind
::Fn(ref sig
, ..) => {
219 check_item_fn(tcx
, def_id
, item
.ident
, item
.span
, sig
.decl
);
221 hir
::ItemKind
::Static(ty
, ..) => {
222 check_item_type(tcx
, def_id
, ty
.span
, false);
224 hir
::ItemKind
::Const(ty
, ..) => {
225 check_item_type(tcx
, def_id
, ty
.span
, false);
227 hir
::ItemKind
::Struct(_
, ast_generics
) => {
228 check_type_defn(tcx
, item
, false);
229 check_variances_for_type_defn(tcx
, item
, ast_generics
);
231 hir
::ItemKind
::Union(_
, ast_generics
) => {
232 check_type_defn(tcx
, item
, true);
233 check_variances_for_type_defn(tcx
, item
, ast_generics
);
235 hir
::ItemKind
::Enum(_
, ast_generics
) => {
236 check_type_defn(tcx
, item
, true);
237 check_variances_for_type_defn(tcx
, item
, ast_generics
);
239 hir
::ItemKind
::Trait(..) => {
240 check_trait(tcx
, item
);
242 hir
::ItemKind
::TraitAlias(..) => {
243 check_trait(tcx
, item
);
245 // `ForeignItem`s are handled separately.
246 hir
::ItemKind
::ForeignMod { .. }
=> {}
251 fn check_foreign_item(tcx
: TyCtxt
<'_
>, item
: &hir
::ForeignItem
<'_
>) {
252 let def_id
= item
.owner_id
.def_id
;
256 item
.name
= ? tcx
.def_path_str(def_id
.to_def_id())
260 hir
::ForeignItemKind
::Fn(decl
, ..) => {
261 check_item_fn(tcx
, def_id
, item
.ident
, item
.span
, decl
)
263 hir
::ForeignItemKind
::Static(ty
, ..) => check_item_type(tcx
, def_id
, ty
.span
, true),
264 hir
::ForeignItemKind
::Type
=> (),
268 fn check_trait_item(tcx
: TyCtxt
<'_
>, trait_item
: &hir
::TraitItem
<'_
>) {
269 let def_id
= trait_item
.owner_id
.def_id
;
271 let (method_sig
, span
) = match trait_item
.kind
{
272 hir
::TraitItemKind
::Fn(ref sig
, _
) => (Some(sig
), trait_item
.span
),
273 hir
::TraitItemKind
::Type(_bounds
, Some(ty
)) => (None
, ty
.span
),
274 _
=> (None
, trait_item
.span
),
276 check_object_unsafe_self_trait_by_name(tcx
, trait_item
);
277 check_associated_item(tcx
, def_id
, span
, method_sig
);
279 let encl_trait_def_id
= tcx
.local_parent(def_id
);
280 let encl_trait
= tcx
.hir().expect_item(encl_trait_def_id
);
281 let encl_trait_def_id
= encl_trait
.owner_id
.to_def_id();
282 let fn_lang_item_name
= if Some(encl_trait_def_id
) == tcx
.lang_items().fn_trait() {
284 } else if Some(encl_trait_def_id
) == tcx
.lang_items().fn_mut_trait() {
290 if let (Some(fn_lang_item_name
), "call") =
291 (fn_lang_item_name
, trait_item
.ident
.name
.to_ident_string().as_str())
293 // We are looking at the `call` function of the `fn` or `fn_mut` lang item.
294 // Do some rudimentary sanity checking to avoid an ICE later (issue #83471).
295 if let Some(hir
::FnSig { decl, span, .. }
) = method_sig
{
296 if let [self_ty
, _
] = decl
.inputs
{
297 if !matches
!(self_ty
.kind
, hir
::TyKind
::Ref(_
, _
)) {
302 "first argument of `call` in `{fn_lang_item_name}` lang item must be a reference",
312 "`call` function in `{fn_lang_item_name}` lang item takes exactly two arguments",
322 "`call` trait item in `{fn_lang_item_name}` lang item must be a function",
330 /// Require that the user writes where clauses on GATs for the implicit
331 /// outlives bounds involving trait parameters in trait functions and
332 /// lifetimes passed as GAT substs. See `self-outlives-lint` test.
334 /// We use the following trait as an example throughout this function:
335 /// ```rust,ignore (this code fails due to this lint)
337 /// type Iter<'a>: Iterator<Item = Self::Item<'a>>;
339 /// fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
342 fn check_gat_where_clauses(tcx
: TyCtxt
<'_
>, associated_items
: &[hir
::TraitItemRef
]) {
343 // Associates every GAT's def_id to a list of possibly missing bounds detected by this lint.
344 let mut required_bounds_by_item
= FxHashMap
::default();
346 // Loop over all GATs together, because if this lint suggests adding a where-clause bound
347 // to one GAT, it might then require us to an additional bound on another GAT.
348 // In our `IntoIter` example, we discover a missing `Self: 'a` bound on `Iter<'a>`, which
349 // then in a second loop adds a `Self: 'a` bound to `Item` due to the relationship between
352 let mut should_continue
= false;
353 for gat_item
in associated_items
{
354 let gat_def_id
= gat_item
.id
.owner_id
;
355 let gat_item
= tcx
.associated_item(gat_def_id
);
356 // If this item is not an assoc ty, or has no substs, then it's not a GAT
357 if gat_item
.kind
!= ty
::AssocKind
::Type
{
360 let gat_generics
= tcx
.generics_of(gat_def_id
);
361 // FIXME(jackh726): we can also warn in the more general case
362 if gat_generics
.params
.is_empty() {
366 // Gather the bounds with which all other items inside of this trait constrain the GAT.
367 // This is calculated by taking the intersection of the bounds that each item
368 // constrains the GAT with individually.
369 let mut new_required_bounds
: Option
<FxHashSet
<ty
::Predicate
<'_
>>> = None
;
370 for item
in associated_items
{
371 let item_def_id
= item
.id
.owner_id
;
372 // Skip our own GAT, since it does not constrain itself at all.
373 if item_def_id
== gat_def_id
{
377 let item_hir_id
= item
.id
.hir_id();
378 let param_env
= tcx
.param_env(item_def_id
);
380 let item_required_bounds
= match item
.kind
{
381 // In our example, this corresponds to `into_iter` method
382 hir
::AssocItemKind
::Fn { .. }
=> {
383 // For methods, we check the function signature's return type for any GATs
384 // to constrain. In the `into_iter` case, we see that the return type
385 // `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
386 let sig
: ty
::FnSig
<'_
> = tcx
.liberate_late_bound_regions(
387 item_def_id
.to_def_id(),
388 tcx
.fn_sig(item_def_id
),
394 sig
.inputs_and_output
,
395 // We also assume that all of the function signature's parameter types
397 &sig
.inputs().iter().copied().collect(),
402 // In our example, this corresponds to the `Iter` and `Item` associated types
403 hir
::AssocItemKind
::Type
=> {
404 // If our associated item is a GAT with missing bounds, add them to
405 // the param-env here. This allows this GAT to propagate missing bounds
407 let param_env
= augment_param_env(
410 required_bounds_by_item
.get(&item_def_id
),
416 tcx
.explicit_item_bounds(item_def_id
).to_vec(),
417 &FxIndexSet
::default(),
422 hir
::AssocItemKind
::Const
=> None
,
425 if let Some(item_required_bounds
) = item_required_bounds
{
426 // Take the intersection of the required bounds for this GAT, and
427 // the item_required_bounds which are the ones implied by just
429 // This is why we use an Option<_>, since we need to distinguish
430 // the empty set of bounds from the _uninitialized_ set of bounds.
431 if let Some(new_required_bounds
) = &mut new_required_bounds
{
432 new_required_bounds
.retain(|b
| item_required_bounds
.contains(b
));
434 new_required_bounds
= Some(item_required_bounds
);
439 if let Some(new_required_bounds
) = new_required_bounds
{
440 let required_bounds
= required_bounds_by_item
.entry(gat_def_id
).or_default();
441 if new_required_bounds
.into_iter().any(|p
| required_bounds
.insert(p
)) {
442 // Iterate until our required_bounds no longer change
443 // Since they changed here, we should continue the loop
444 should_continue
= true;
448 // We know that this loop will eventually halt, since we only set `should_continue` if the
449 // `required_bounds` for this item grows. Since we are not creating any new region or type
450 // variables, the set of all region and type bounds that we could ever insert are limited
451 // by the number of unique types and regions we observe in a given item.
452 if !should_continue
{
457 for (gat_def_id
, required_bounds
) in required_bounds_by_item
{
458 let gat_item_hir
= tcx
.hir().expect_trait_item(gat_def_id
.def_id
);
459 debug
!(?required_bounds
);
460 let param_env
= tcx
.param_env(gat_def_id
);
461 let gat_hir
= gat_item_hir
.hir_id();
463 let mut unsatisfied_bounds
: Vec
<_
> = required_bounds
465 .filter(|clause
| match clause
.kind().skip_binder() {
466 ty
::PredicateKind
::Clause(ty
::Clause
::RegionOutlives(ty
::OutlivesPredicate(
470 !region_known_to_outlive(tcx
, gat_hir
, param_env
, &FxIndexSet
::default(), a
, b
)
472 ty
::PredicateKind
::Clause(ty
::Clause
::TypeOutlives(ty
::OutlivesPredicate(
475 ))) => !ty_known_to_outlive(tcx
, gat_hir
, param_env
, &FxIndexSet
::default(), a
, b
),
476 _
=> bug
!("Unexpected PredicateKind"),
478 .map(|clause
| clause
.to_string())
481 // We sort so that order is predictable
482 unsatisfied_bounds
.sort();
484 if !unsatisfied_bounds
.is_empty() {
485 let plural
= pluralize
!(unsatisfied_bounds
.len());
486 let mut err
= tcx
.sess
.struct_span_err(
488 &format
!("missing required bound{} on `{}`", plural
, gat_item_hir
.ident
),
491 let suggestion
= format
!(
493 gat_item_hir
.generics
.add_where_or_trailing_comma(),
494 unsatisfied_bounds
.join(", "),
497 gat_item_hir
.generics
.tail_span_for_predicate_suggestion(),
498 &format
!("add the required where clause{plural}"),
500 Applicability
::MachineApplicable
,
504 if unsatisfied_bounds
.len() > 1 { "these bounds are" }
else { "this bound is" }
;
506 "{} currently required to ensure that impls have maximum flexibility",
510 "we are soliciting feedback, see issue #87479 \
511 <https://github.com/rust-lang/rust/issues/87479> \
512 for more information",
520 /// Add a new set of predicates to the caller_bounds of an existing param_env.
521 fn augment_param_env
<'tcx
>(
523 param_env
: ty
::ParamEnv
<'tcx
>,
524 new_predicates
: Option
<&FxHashSet
<ty
::Predicate
<'tcx
>>>,
525 ) -> ty
::ParamEnv
<'tcx
> {
526 let Some(new_predicates
) = new_predicates
else {
530 if new_predicates
.is_empty() {
535 tcx
.mk_predicates(param_env
.caller_bounds().iter().chain(new_predicates
.iter().cloned()));
536 // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
537 // i.e. traits::normalize_param_env_or_error
538 ty
::ParamEnv
::new(bounds
, param_env
.reveal(), param_env
.constness())
541 /// We use the following trait as an example throughout this function.
542 /// Specifically, let's assume that `to_check` here is the return type
543 /// of `into_iter`, and the GAT we are checking this for is `Iter`.
544 /// ```rust,ignore (this code fails due to this lint)
546 /// type Iter<'a>: Iterator<Item = Self::Item<'a>>;
548 /// fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
551 fn gather_gat_bounds
<'tcx
, T
: TypeFoldable
<'tcx
>>(
553 param_env
: ty
::ParamEnv
<'tcx
>,
554 item_hir
: hir
::HirId
,
556 wf_tys
: &FxIndexSet
<Ty
<'tcx
>>,
557 gat_def_id
: LocalDefId
,
558 gat_generics
: &'tcx ty
::Generics
,
559 ) -> Option
<FxHashSet
<ty
::Predicate
<'tcx
>>> {
560 // The bounds we that we would require from `to_check`
561 let mut bounds
= FxHashSet
::default();
563 let (regions
, types
) = GATSubstCollector
::visit(gat_def_id
.to_def_id(), to_check
);
565 // If both regions and types are empty, then this GAT isn't in the
566 // set of types we are checking, and we shouldn't try to do clause analysis
567 // (particularly, doing so would end up with an empty set of clauses,
568 // since the current method would require none, and we take the
569 // intersection of requirements of all methods)
570 if types
.is_empty() && regions
.is_empty() {
574 for (region_a
, region_a_idx
) in ®ions
{
575 // Ignore `'static` lifetimes for the purpose of this lint: it's
576 // because we know it outlives everything and so doesn't give meaningful
578 if let ty
::ReStatic
= **region_a
{
581 // For each region argument (e.g., `'a` in our example), check for a
582 // relationship to the type arguments (e.g., `Self`). If there is an
583 // outlives relationship (`Self: 'a`), then we want to ensure that is
584 // reflected in a where clause on the GAT itself.
585 for (ty
, ty_idx
) in &types
{
586 // In our example, requires that `Self: 'a`
587 if ty_known_to_outlive(tcx
, item_hir
, param_env
, &wf_tys
, *ty
, *region_a
) {
588 debug
!(?ty_idx
, ?region_a_idx
);
589 debug
!("required clause: {ty} must outlive {region_a}");
590 // Translate into the generic parameters of the GAT. In
591 // our example, the type was `Self`, which will also be
592 // `Self` in the GAT.
593 let ty_param
= gat_generics
.param_at(*ty_idx
, tcx
);
595 .mk_ty(ty
::Param(ty
::ParamTy { index: ty_param.index, name: ty_param.name }
));
596 // Same for the region. In our example, 'a corresponds
597 // to the 'me parameter.
598 let region_param
= gat_generics
.param_at(*region_a_idx
, tcx
);
600 tcx
.mk_region(ty
::RegionKind
::ReEarlyBound(ty
::EarlyBoundRegion
{
601 def_id
: region_param
.def_id
,
602 index
: region_param
.index
,
603 name
: region_param
.name
,
605 // The predicate we expect to see. (In our example,
607 let clause
= ty
::PredicateKind
::Clause(ty
::Clause
::TypeOutlives(
608 ty
::OutlivesPredicate(ty_param
, region_param
),
610 let clause
= tcx
.mk_predicate(ty
::Binder
::dummy(clause
));
611 bounds
.insert(clause
);
615 // For each region argument (e.g., `'a` in our example), also check for a
616 // relationship to the other region arguments. If there is an outlives
617 // relationship, then we want to ensure that is reflected in the where clause
618 // on the GAT itself.
619 for (region_b
, region_b_idx
) in ®ions
{
620 // Again, skip `'static` because it outlives everything. Also, we trivially
621 // know that a region outlives itself.
622 if ty
::ReStatic
== **region_b
|| region_a
== region_b
{
625 if region_known_to_outlive(tcx
, item_hir
, param_env
, &wf_tys
, *region_a
, *region_b
) {
626 debug
!(?region_a_idx
, ?region_b_idx
);
627 debug
!("required clause: {region_a} must outlive {region_b}");
628 // Translate into the generic parameters of the GAT.
629 let region_a_param
= gat_generics
.param_at(*region_a_idx
, tcx
);
631 tcx
.mk_region(ty
::RegionKind
::ReEarlyBound(ty
::EarlyBoundRegion
{
632 def_id
: region_a_param
.def_id
,
633 index
: region_a_param
.index
,
634 name
: region_a_param
.name
,
636 // Same for the region.
637 let region_b_param
= gat_generics
.param_at(*region_b_idx
, tcx
);
639 tcx
.mk_region(ty
::RegionKind
::ReEarlyBound(ty
::EarlyBoundRegion
{
640 def_id
: region_b_param
.def_id
,
641 index
: region_b_param
.index
,
642 name
: region_b_param
.name
,
644 // The predicate we expect to see.
645 let clause
= ty
::PredicateKind
::Clause(ty
::Clause
::RegionOutlives(
646 ty
::OutlivesPredicate(region_a_param
, region_b_param
),
648 let clause
= tcx
.mk_predicate(ty
::Binder
::dummy(clause
));
649 bounds
.insert(clause
);
657 /// Given a known `param_env` and a set of well formed types, can we prove that
658 /// `ty` outlives `region`.
659 fn ty_known_to_outlive
<'tcx
>(
662 param_env
: ty
::ParamEnv
<'tcx
>,
663 wf_tys
: &FxIndexSet
<Ty
<'tcx
>>,
665 region
: ty
::Region
<'tcx
>,
667 resolve_regions_with_wf_tys(tcx
, id
, param_env
, &wf_tys
, |infcx
, region_bound_pairs
| {
668 let origin
= infer
::RelateParamBound(DUMMY_SP
, ty
, None
);
669 let outlives
= &mut TypeOutlives
::new(infcx
, tcx
, region_bound_pairs
, None
, param_env
);
670 outlives
.type_must_outlive(origin
, ty
, region
, ConstraintCategory
::BoringNoLocation
);
674 /// Given a known `param_env` and a set of well formed types, can we prove that
675 /// `region_a` outlives `region_b`
676 fn region_known_to_outlive
<'tcx
>(
679 param_env
: ty
::ParamEnv
<'tcx
>,
680 wf_tys
: &FxIndexSet
<Ty
<'tcx
>>,
681 region_a
: ty
::Region
<'tcx
>,
682 region_b
: ty
::Region
<'tcx
>,
684 resolve_regions_with_wf_tys(tcx
, id
, param_env
, &wf_tys
, |mut infcx
, _
| {
685 use rustc_infer
::infer
::outlives
::obligations
::TypeOutlivesDelegate
;
686 let origin
= infer
::RelateRegionParamBound(DUMMY_SP
);
687 // `region_a: region_b` -> `region_b <= region_a`
688 infcx
.push_sub_region_constraint(
692 ConstraintCategory
::BoringNoLocation
,
697 /// Given a known `param_env` and a set of well formed types, set up an
698 /// `InferCtxt`, call the passed function (to e.g. set up region constraints
699 /// to be tested), then resolve region and return errors
700 fn resolve_regions_with_wf_tys
<'tcx
>(
703 param_env
: ty
::ParamEnv
<'tcx
>,
704 wf_tys
: &FxIndexSet
<Ty
<'tcx
>>,
705 add_constraints
: impl for<'a
> FnOnce(&'a InferCtxt
<'tcx
>, &'a RegionBoundPairs
<'tcx
>),
707 // Unfortunately, we have to use a new `InferCtxt` each call, because
708 // region constraints get added and solved there and we need to test each
709 // call individually.
710 let infcx
= tcx
.infer_ctxt().build();
711 let outlives_environment
= OutlivesEnvironment
::with_bounds(
714 infcx
.implied_bounds_tys(param_env
, id
, wf_tys
.clone()),
716 let region_bound_pairs
= outlives_environment
.region_bound_pairs();
718 add_constraints(&infcx
, region_bound_pairs
);
720 infcx
.process_registered_region_obligations(
721 outlives_environment
.region_bound_pairs(),
724 let errors
= infcx
.resolve_regions(&outlives_environment
);
726 debug
!(?errors
, "errors");
728 // If we were able to prove that the type outlives the region without
729 // an error, it must be because of the implied or explicit bounds...
733 /// TypeVisitor that looks for uses of GATs like
734 /// `<P0 as Trait<P1..Pn>>::GAT<Pn..Pm>` and adds the arguments `P0..Pm` into
735 /// the two vectors, `regions` and `types` (depending on their kind). For each
736 /// parameter `Pi` also track the index `i`.
737 struct GATSubstCollector
<'tcx
> {
739 // Which region appears and which parameter index its substituted for
740 regions
: FxHashSet
<(ty
::Region
<'tcx
>, usize)>,
741 // Which params appears and which parameter index its substituted for
742 types
: FxHashSet
<(Ty
<'tcx
>, usize)>,
745 impl<'tcx
> GATSubstCollector
<'tcx
> {
746 fn visit
<T
: TypeFoldable
<'tcx
>>(
749 ) -> (FxHashSet
<(ty
::Region
<'tcx
>, usize)>, FxHashSet
<(Ty
<'tcx
>, usize)>) {
751 GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() }
;
752 t
.visit_with(&mut visitor
);
753 (visitor
.regions
, visitor
.types
)
757 impl<'tcx
> TypeVisitor
<'tcx
> for GATSubstCollector
<'tcx
> {
760 fn visit_ty(&mut self, t
: Ty
<'tcx
>) -> ControlFlow
<Self::BreakTy
> {
762 ty
::Alias(ty
::Projection
, p
) if p
.def_id
== self.gat
=> {
763 for (idx
, subst
) in p
.substs
.iter().enumerate() {
764 match subst
.unpack() {
765 GenericArgKind
::Lifetime(lt
) if !lt
.is_late_bound() => {
766 self.regions
.insert((lt
, idx
));
768 GenericArgKind
::Type(t
) => {
769 self.types
.insert((t
, idx
));
777 t
.super_visit_with(self)
781 fn could_be_self(trait_def_id
: LocalDefId
, ty
: &hir
::Ty
<'_
>) -> bool
{
783 hir
::TyKind
::TraitObject([trait_ref
], ..) => match trait_ref
.trait_ref
.path
.segments
{
784 [s
] => s
.res
.opt_def_id() == Some(trait_def_id
.to_def_id()),
791 /// Detect when an object unsafe trait is referring to itself in one of its associated items.
792 /// When this is done, suggest using `Self` instead.
793 fn check_object_unsafe_self_trait_by_name(tcx
: TyCtxt
<'_
>, item
: &hir
::TraitItem
<'_
>) {
794 let (trait_name
, trait_def_id
) =
795 match tcx
.hir().get_by_def_id(tcx
.hir().get_parent_item(item
.hir_id()).def_id
) {
796 hir
::Node
::Item(item
) => match item
.kind
{
797 hir
::ItemKind
::Trait(..) => (item
.ident
, item
.owner_id
),
802 let mut trait_should_be_self
= vec
![];
804 hir
::TraitItemKind
::Const(ty
, _
) | hir
::TraitItemKind
::Type(_
, Some(ty
))
805 if could_be_self(trait_def_id
.def_id
, ty
) =>
807 trait_should_be_self
.push(ty
.span
)
809 hir
::TraitItemKind
::Fn(sig
, _
) => {
810 for ty
in sig
.decl
.inputs
{
811 if could_be_self(trait_def_id
.def_id
, ty
) {
812 trait_should_be_self
.push(ty
.span
);
815 match sig
.decl
.output
{
816 hir
::FnRetTy
::Return(ty
) if could_be_self(trait_def_id
.def_id
, ty
) => {
817 trait_should_be_self
.push(ty
.span
);
824 if !trait_should_be_self
.is_empty() {
825 if tcx
.object_safety_violations(trait_def_id
).is_empty() {
828 let sugg
= trait_should_be_self
.iter().map(|span
| (*span
, "Self".to_string())).collect();
831 trait_should_be_self
,
832 "associated item referring to unboxed trait object for its own trait",
834 .span_label(trait_name
.span
, "in this trait")
835 .multipart_suggestion(
836 "you might have meant to use `Self` to refer to the implementing type",
838 Applicability
::MachineApplicable
,
844 fn check_impl_item(tcx
: TyCtxt
<'_
>, impl_item
: &hir
::ImplItem
<'_
>) {
845 let (method_sig
, span
) = match impl_item
.kind
{
846 hir
::ImplItemKind
::Fn(ref sig
, _
) => (Some(sig
), impl_item
.span
),
847 // Constrain binding and overflow error spans to `<Ty>` in `type foo = <Ty>`.
848 hir
::ImplItemKind
::Type(ty
) if ty
.span
!= DUMMY_SP
=> (None
, ty
.span
),
849 _
=> (None
, impl_item
.span
),
852 check_associated_item(tcx
, impl_item
.owner_id
.def_id
, span
, method_sig
);
855 fn check_param_wf(tcx
: TyCtxt
<'_
>, param
: &hir
::GenericParam
<'_
>) {
857 // We currently only check wf of const params here.
858 hir
::GenericParamKind
::Lifetime { .. }
| hir
::GenericParamKind
::Type { .. }
=> (),
860 // Const parameters are well formed if their type is structural match.
861 hir
::GenericParamKind
::Const { ty: hir_ty, default: _ }
=> {
862 let ty
= tcx
.type_of(param
.def_id
);
864 if tcx
.features().adt_const_params
{
865 if let Some(non_structural_match_ty
) =
866 traits
::search_for_adt_const_param_violation(param
.span
, tcx
, ty
)
868 // We use the same error code in both branches, because this is really the same
869 // issue: we just special-case the message for type parameters to make it
871 match non_structural_match_ty
.kind() {
873 // Const parameters may not have type parameters as their types,
874 // because we cannot be sure that the type parameter derives `PartialEq`
875 // and `Eq` (just implementing them is not enough for `structural_match`).
880 "`{ty}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
881 used as the type of a const parameter",
885 format
!("`{ty}` may not derive both `PartialEq` and `Eq`"),
888 "it is not currently possible to use a type parameter as the type of a \
898 "`{ty}` is forbidden as the type of a const generic parameter",
900 .note("floats do not derive `Eq` or `Ord`, which are required for const parameters")
908 "using function pointers as const generic parameters is forbidden",
917 "using raw pointers as const generic parameters is forbidden",
922 let mut diag
= struct_span_err
!(
926 "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
927 the type of a const parameter",
928 non_structural_match_ty
,
931 if ty
== non_structural_match_ty
{
934 format
!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),
944 let mut is_ptr
= true;
946 let err
= match ty
.kind() {
947 ty
::Bool
| ty
::Char
| ty
::Int(_
) | ty
::Uint(_
) | ty
::Error(_
) => None
,
948 ty
::FnPtr(_
) => Some("function pointers"),
949 ty
::RawPtr(_
) => Some("raw pointers"),
952 err_ty_str
= format
!("`{ty}`");
953 Some(err_ty_str
.as_str())
957 if let Some(unsupported_type
) = err
{
962 "using {unsupported_type} as const generic parameters is forbidden",
966 let mut err
= tcx
.sess
.struct_span_err(
969 "{unsupported_type} is forbidden as the type of a const generic parameter",
972 err
.note("the only supported types are integers, `bool` and `char`");
973 if tcx
.sess
.is_nightly_build() {
975 "more complex types are supported with `#![feature(adt_const_params)]`",
986 #[instrument(level = "debug", skip(tcx, span, sig_if_method))]
987 fn check_associated_item(
991 sig_if_method
: Option
<&hir
::FnSig
<'_
>>,
993 let loc
= Some(WellFormedLoc
::Ty(item_id
));
994 enter_wf_checking_ctxt(tcx
, span
, item_id
, |wfcx
| {
995 let item
= tcx
.associated_item(item_id
);
997 let self_ty
= match item
.container
{
998 ty
::TraitContainer
=> tcx
.types
.self_param
,
999 ty
::ImplContainer
=> tcx
.type_of(item
.container_id(tcx
)),
1003 ty
::AssocKind
::Const
=> {
1004 let ty
= tcx
.type_of(item
.def_id
);
1005 let ty
= wfcx
.normalize(span
, Some(WellFormedLoc
::Ty(item_id
)), ty
);
1006 wfcx
.register_wf_obligation(span
, loc
, ty
.into());
1008 ty
::AssocKind
::Fn
=> {
1009 let sig
= tcx
.fn_sig(item
.def_id
);
1010 let hir_sig
= sig_if_method
.expect("bad signature for method");
1013 item
.ident(tcx
).span
,
1016 item
.def_id
.expect_local(),
1018 check_method_receiver(wfcx
, hir_sig
, item
, self_ty
);
1020 ty
::AssocKind
::Type
=> {
1021 if let ty
::AssocItemContainer
::TraitContainer
= item
.container
{
1022 check_associated_type_bounds(wfcx
, item
, span
)
1024 if item
.defaultness(tcx
).has_value() {
1025 let ty
= tcx
.type_of(item
.def_id
);
1026 let ty
= wfcx
.normalize(span
, Some(WellFormedLoc
::Ty(item_id
)), ty
);
1027 wfcx
.register_wf_obligation(span
, loc
, ty
.into());
1034 fn item_adt_kind(kind
: &ItemKind
<'_
>) -> Option
<AdtKind
> {
1036 ItemKind
::Struct(..) => Some(AdtKind
::Struct
),
1037 ItemKind
::Union(..) => Some(AdtKind
::Union
),
1038 ItemKind
::Enum(..) => Some(AdtKind
::Enum
),
1043 /// In a type definition, we check that to ensure that the types of the fields are well-formed.
1044 fn check_type_defn
<'tcx
>(tcx
: TyCtxt
<'tcx
>, item
: &hir
::Item
<'tcx
>, all_sized
: bool
) {
1045 let _
= tcx
.representability(item
.owner_id
.def_id
);
1046 let adt_def
= tcx
.adt_def(item
.owner_id
);
1048 enter_wf_checking_ctxt(tcx
, item
.span
, item
.owner_id
.def_id
, |wfcx
| {
1049 let variants
= adt_def
.variants();
1050 let packed
= adt_def
.repr().packed();
1052 for variant
in variants
.iter() {
1053 // All field types must be well-formed.
1054 for field
in &variant
.fields
{
1055 let field_id
= field
.did
.expect_local();
1056 let hir
::Node
::Field(hir
::FieldDef { ty: hir_ty, .. }
) = tcx
.hir().get_by_def_id(field_id
)
1058 let ty
= wfcx
.normalize(hir_ty
.span
, None
, tcx
.type_of(field
.did
));
1059 wfcx
.register_wf_obligation(
1061 Some(WellFormedLoc
::Ty(field_id
)),
1066 // For DST, or when drop needs to copy things around, all
1067 // intermediate types must be sized.
1068 let needs_drop_copy
= || {
1070 let ty
= tcx
.type_of(variant
.fields
.last().unwrap().did
);
1071 let ty
= tcx
.erase_regions(ty
);
1072 if ty
.needs_infer() {
1074 .delay_span_bug(item
.span
, &format
!("inference variables in {:?}", ty
));
1075 // Just treat unresolved type expression as if it needs drop.
1078 ty
.needs_drop(tcx
, tcx
.param_env(item
.owner_id
))
1082 // All fields (except for possibly the last) should be sized.
1083 let all_sized
= all_sized
|| variant
.fields
.is_empty() || needs_drop_copy();
1084 let unsized_len
= if all_sized { 0 }
else { 1 }
;
1086 variant
.fields
[..variant
.fields
.len() - unsized_len
].iter().enumerate()
1088 let last
= idx
== variant
.fields
.len() - 1;
1089 let field_id
= field
.did
.expect_local();
1090 let hir
::Node
::Field(hir
::FieldDef { ty: hir_ty, .. }
) = tcx
.hir().get_by_def_id(field_id
)
1092 let ty
= wfcx
.normalize(hir_ty
.span
, None
, tcx
.type_of(field
.did
));
1093 wfcx
.register_bound(
1094 traits
::ObligationCause
::new(
1097 traits
::FieldSized
{
1098 adt_kind
: match item_adt_kind(&item
.kind
) {
1108 tcx
.require_lang_item(LangItem
::Sized
, None
),
1112 // Explicit `enum` discriminant values must const-evaluate successfully.
1113 if let ty
::VariantDiscr
::Explicit(discr_def_id
) = variant
.discr
{
1114 let cause
= traits
::ObligationCause
::new(
1115 tcx
.def_span(discr_def_id
),
1117 traits
::MiscObligation
,
1119 wfcx
.register_obligation(traits
::Obligation
::new(
1123 ty
::Binder
::dummy(ty
::PredicateKind
::ConstEvaluatable(
1124 ty
::Const
::from_anon_const(tcx
, discr_def_id
.expect_local()),
1130 check_where_clauses(wfcx
, item
.span
, item
.owner_id
.def_id
);
1134 #[instrument(skip(tcx, item))]
1135 fn check_trait(tcx
: TyCtxt
<'_
>, item
: &hir
::Item
<'_
>) {
1136 debug
!(?item
.owner_id
);
1138 let def_id
= item
.owner_id
.def_id
;
1139 let trait_def
= tcx
.trait_def(def_id
);
1140 if trait_def
.is_marker
1141 || matches
!(trait_def
.specialization_kind
, TraitSpecializationKind
::Marker
)
1143 for associated_def_id
in &*tcx
.associated_item_def_ids(def_id
) {
1146 tcx
.def_span(*associated_def_id
),
1148 "marker traits cannot have associated items",
1154 enter_wf_checking_ctxt(tcx
, item
.span
, def_id
, |wfcx
| {
1155 check_where_clauses(wfcx
, item
.span
, def_id
)
1158 // Only check traits, don't check trait aliases
1159 if let hir
::ItemKind
::Trait(_
, _
, _
, _
, items
) = item
.kind
{
1160 check_gat_where_clauses(tcx
, items
);
1164 /// Checks all associated type defaults of trait `trait_def_id`.
1166 /// Assuming the defaults are used, check that all predicates (bounds on the
1167 /// assoc type and where clauses on the trait) hold.
1168 fn check_associated_type_bounds(wfcx
: &WfCheckingCtxt
<'_
, '_
>, item
: &ty
::AssocItem
, span
: Span
) {
1169 let bounds
= wfcx
.tcx().explicit_item_bounds(item
.def_id
);
1171 debug
!("check_associated_type_bounds: bounds={:?}", bounds
);
1172 let wf_obligations
= bounds
.iter().flat_map(|&(bound
, bound_span
)| {
1173 let normalized_bound
= wfcx
.normalize(span
, None
, bound
);
1174 traits
::wf
::predicate_obligations(
1183 wfcx
.register_obligations(wf_obligations
);
1191 decl
: &hir
::FnDecl
<'_
>,
1193 enter_wf_checking_ctxt(tcx
, span
, def_id
, |wfcx
| {
1194 let sig
= tcx
.fn_sig(def_id
);
1195 check_fn_or_method(wfcx
, ident
.span
, sig
, decl
, def_id
);
1199 fn check_item_type(tcx
: TyCtxt
<'_
>, item_id
: LocalDefId
, ty_span
: Span
, allow_foreign_ty
: bool
) {
1200 debug
!("check_item_type: {:?}", item_id
);
1202 enter_wf_checking_ctxt(tcx
, ty_span
, item_id
, |wfcx
| {
1203 let ty
= tcx
.type_of(item_id
);
1204 let item_ty
= wfcx
.normalize(ty_span
, Some(WellFormedLoc
::Ty(item_id
)), ty
);
1206 let mut forbid_unsized
= true;
1207 if allow_foreign_ty
{
1208 let tail
= tcx
.struct_tail_erasing_lifetimes(item_ty
, wfcx
.param_env
);
1209 if let ty
::Foreign(_
) = tail
.kind() {
1210 forbid_unsized
= false;
1214 wfcx
.register_wf_obligation(ty_span
, Some(WellFormedLoc
::Ty(item_id
)), item_ty
.into());
1216 wfcx
.register_bound(
1217 traits
::ObligationCause
::new(ty_span
, wfcx
.body_id
, traits
::WellFormed(None
)),
1220 tcx
.require_lang_item(LangItem
::Sized
, None
),
1224 // Ensure that the end result is `Sync` in a non-thread local `static`.
1225 let should_check_for_sync
= tcx
.static_mutability(item_id
.to_def_id())
1226 == Some(hir
::Mutability
::Not
)
1227 && !tcx
.is_foreign_item(item_id
.to_def_id())
1228 && !tcx
.is_thread_local_static(item_id
.to_def_id());
1230 if should_check_for_sync
{
1231 wfcx
.register_bound(
1232 traits
::ObligationCause
::new(ty_span
, wfcx
.body_id
, traits
::SharedStatic
),
1235 tcx
.require_lang_item(LangItem
::Sync
, Some(ty_span
)),
1241 #[instrument(level = "debug", skip(tcx, ast_self_ty, ast_trait_ref))]
1242 fn check_impl
<'tcx
>(
1244 item
: &'tcx hir
::Item
<'tcx
>,
1245 ast_self_ty
: &hir
::Ty
<'_
>,
1246 ast_trait_ref
: &Option
<hir
::TraitRef
<'_
>>,
1247 constness
: hir
::Constness
,
1249 enter_wf_checking_ctxt(tcx
, item
.span
, item
.owner_id
.def_id
, |wfcx
| {
1250 match ast_trait_ref
{
1251 Some(ast_trait_ref
) => {
1252 // `#[rustc_reservation_impl]` impls are not real impls and
1253 // therefore don't need to be WF (the trait's `Self: Trait` predicate
1255 let trait_ref
= tcx
.impl_trait_ref(item
.owner_id
).unwrap().subst_identity();
1256 let trait_ref
= wfcx
.normalize(
1257 ast_trait_ref
.path
.span
,
1258 Some(WellFormedLoc
::Ty(item
.hir_id().expect_owner().def_id
)),
1261 let trait_pred
= ty
::TraitPredicate
{
1263 constness
: match constness
{
1264 hir
::Constness
::Const
=> ty
::BoundConstness
::ConstIfConst
,
1265 hir
::Constness
::NotConst
=> ty
::BoundConstness
::NotConst
,
1267 polarity
: ty
::ImplPolarity
::Positive
,
1269 let mut obligations
= traits
::wf
::trait_obligations(
1274 ast_trait_ref
.path
.span
,
1277 for obligation
in &mut obligations
{
1278 if let Some(pred
) = obligation
.predicate
.to_opt_poly_trait_pred()
1279 && pred
.self_ty().skip_binder() == trait_ref
.self_ty()
1281 obligation
.cause
.span
= ast_self_ty
.span
;
1284 debug
!(?obligations
);
1285 wfcx
.register_obligations(obligations
);
1288 let self_ty
= tcx
.type_of(item
.owner_id
);
1289 let self_ty
= wfcx
.normalize(
1291 Some(WellFormedLoc
::Ty(item
.hir_id().expect_owner().def_id
)),
1294 wfcx
.register_wf_obligation(
1296 Some(WellFormedLoc
::Ty(item
.hir_id().expect_owner().def_id
)),
1302 check_where_clauses(wfcx
, item
.span
, item
.owner_id
.def_id
);
1306 /// Checks where-clauses and inline bounds that are declared on `def_id`.
1307 #[instrument(level = "debug", skip(wfcx))]
1308 fn check_where_clauses
<'tcx
>(wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>, span
: Span
, def_id
: LocalDefId
) {
1309 let infcx
= wfcx
.infcx
;
1310 let tcx
= wfcx
.tcx();
1312 let predicates
= tcx
.predicates_of(def_id
.to_def_id());
1313 let generics
= tcx
.generics_of(def_id
);
1315 let is_our_default
= |def
: &ty
::GenericParamDef
| match def
.kind
{
1316 GenericParamDefKind
::Type { has_default, .. }
1317 | GenericParamDefKind
::Const { has_default }
=> {
1318 has_default
&& def
.index
>= generics
.parent_count
as u32
1320 GenericParamDefKind
::Lifetime
=> unreachable
!(),
1323 // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
1324 // For example, this forbids the declaration:
1326 // struct Foo<T = Vec<[u32]>> { .. }
1328 // Here, the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
1329 for param
in &generics
.params
{
1331 GenericParamDefKind
::Type { .. }
=> {
1332 if is_our_default(param
) {
1333 let ty
= tcx
.type_of(param
.def_id
);
1334 // Ignore dependent defaults -- that is, where the default of one type
1335 // parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
1336 // be sure if it will error or not as user might always specify the other.
1337 if !ty
.needs_subst() {
1338 wfcx
.register_wf_obligation(
1339 tcx
.def_span(param
.def_id
),
1340 Some(WellFormedLoc
::Ty(param
.def_id
.expect_local())),
1346 GenericParamDefKind
::Const { .. }
=> {
1347 if is_our_default(param
) {
1348 // FIXME(const_generics_defaults): This
1349 // is incorrect when dealing with unused substs, for example
1350 // for `struct Foo<const N: usize, const M: usize = { 1 - 2 }>`
1351 // we should eagerly error.
1352 let default_ct
= tcx
.const_param_default(param
.def_id
).subst_identity();
1353 if !default_ct
.needs_subst() {
1354 wfcx
.register_wf_obligation(
1355 tcx
.def_span(param
.def_id
),
1362 // Doesn't have defaults.
1363 GenericParamDefKind
::Lifetime
=> {}
1367 // Check that trait predicates are WF when params are substituted by their defaults.
1368 // We don't want to overly constrain the predicates that may be written but we want to
1369 // catch cases where a default my never be applied such as `struct Foo<T: Copy = String>`.
1370 // Therefore we check if a predicate which contains a single type param
1371 // with a concrete default is WF with that default substituted.
1372 // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
1374 // First we build the defaulted substitution.
1375 let substs
= InternalSubsts
::for_item(tcx
, def_id
.to_def_id(), |param
, _
| {
1377 GenericParamDefKind
::Lifetime
=> {
1378 // All regions are identity.
1379 tcx
.mk_param_from_def(param
)
1382 GenericParamDefKind
::Type { .. }
=> {
1383 // If the param has a default, ...
1384 if is_our_default(param
) {
1385 let default_ty
= tcx
.type_of(param
.def_id
);
1386 // ... and it's not a dependent default, ...
1387 if !default_ty
.needs_subst() {
1388 // ... then substitute it with the default.
1389 return default_ty
.into();
1393 tcx
.mk_param_from_def(param
)
1395 GenericParamDefKind
::Const { .. }
=> {
1396 // If the param has a default, ...
1397 if is_our_default(param
) {
1398 let default_ct
= tcx
.const_param_default(param
.def_id
).subst_identity();
1399 // ... and it's not a dependent default, ...
1400 if !default_ct
.needs_subst() {
1401 // ... then substitute it with the default.
1402 return default_ct
.into();
1406 tcx
.mk_param_from_def(param
)
1411 // Now we build the substituted predicates.
1412 let default_obligations
= predicates
1415 .flat_map(|&(pred
, sp
)| {
1417 struct CountParams
{
1418 params
: FxHashSet
<u32>,
1420 impl<'tcx
> ty
::visit
::TypeVisitor
<'tcx
> for CountParams
{
1423 fn visit_ty(&mut self, t
: Ty
<'tcx
>) -> ControlFlow
<Self::BreakTy
> {
1424 if let ty
::Param(param
) = t
.kind() {
1425 self.params
.insert(param
.index
);
1427 t
.super_visit_with(self)
1430 fn visit_region(&mut self, _
: ty
::Region
<'tcx
>) -> ControlFlow
<Self::BreakTy
> {
1431 ControlFlow
::Break(())
1434 fn visit_const(&mut self, c
: ty
::Const
<'tcx
>) -> ControlFlow
<Self::BreakTy
> {
1435 if let ty
::ConstKind
::Param(param
) = c
.kind() {
1436 self.params
.insert(param
.index
);
1438 c
.super_visit_with(self)
1441 let mut param_count
= CountParams
::default();
1442 let has_region
= pred
.visit_with(&mut param_count
).is_break();
1443 let substituted_pred
= ty
::EarlyBinder(pred
).subst(tcx
, substs
);
1444 // Don't check non-defaulted params, dependent defaults (including lifetimes)
1445 // or preds with multiple params.
1446 if substituted_pred
.has_non_region_param() || param_count
.params
.len() > 1 || has_region
1449 } else if predicates
.predicates
.iter().any(|&(p
, _
)| p
== substituted_pred
) {
1450 // Avoid duplication of predicates that contain no parameters, for example.
1453 Some((substituted_pred
, sp
))
1457 // Convert each of those into an obligation. So if you have
1458 // something like `struct Foo<T: Copy = String>`, we would
1459 // take that predicate `T: Copy`, substitute to `String: Copy`
1460 // (actually that happens in the previous `flat_map` call),
1461 // and then try to prove it (in this case, we'll fail).
1463 // Note the subtle difference from how we handle `predicates`
1464 // below: there, we are not trying to prove those predicates
1465 // to be *true* but merely *well-formed*.
1466 let pred
= wfcx
.normalize(sp
, None
, pred
);
1467 let cause
= traits
::ObligationCause
::new(
1470 traits
::ItemObligation(def_id
.to_def_id()),
1472 traits
::Obligation
::new(tcx
, cause
, wfcx
.param_env
, pred
)
1475 let predicates
= predicates
.instantiate_identity(tcx
);
1477 let predicates
= wfcx
.normalize(span
, None
, predicates
);
1479 debug
!(?predicates
.predicates
);
1480 assert_eq
!(predicates
.predicates
.len(), predicates
.spans
.len());
1481 let wf_obligations
= predicates
.into_iter().flat_map(|(p
, sp
)| {
1482 traits
::wf
::predicate_obligations(
1484 wfcx
.param_env
.without_const(),
1491 let obligations
: Vec
<_
> = wf_obligations
.chain(default_obligations
).collect();
1492 wfcx
.register_obligations(obligations
);
1495 #[instrument(level = "debug", skip(wfcx, span, hir_decl))]
1496 fn check_fn_or_method
<'tcx
>(
1497 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1499 sig
: ty
::PolyFnSig
<'tcx
>,
1500 hir_decl
: &hir
::FnDecl
<'_
>,
1503 let tcx
= wfcx
.tcx();
1504 let mut sig
= tcx
.liberate_late_bound_regions(def_id
.to_def_id(), sig
);
1506 // Normalize the input and output types one at a time, using a different
1507 // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
1508 // on the entire `FnSig`, since this would use the same `WellFormedLoc`
1509 // for each type, preventing the HIR wf check from generating
1510 // a nice error message.
1512 |idx
| hir_decl
.inputs
.get(idx
).map_or(hir_decl
.output
.span(), |arg
: &hir
::Ty
<'_
>| arg
.span
);
1514 sig
.inputs_and_output
=
1515 tcx
.mk_type_list(sig
.inputs_and_output
.iter().enumerate().map(|(idx
, ty
)| {
1518 Some(WellFormedLoc
::Param
{
1520 // Note that the `param_idx` of the output type is
1521 // one greater than the index of the last input type.
1522 param_idx
: idx
.try_into().unwrap(),
1528 for (idx
, ty
) in sig
.inputs_and_output
.iter().enumerate() {
1529 wfcx
.register_wf_obligation(
1531 Some(WellFormedLoc
::Param { function: def_id, param_idx: idx.try_into().unwrap() }
),
1536 check_where_clauses(wfcx
, span
, def_id
);
1538 check_return_position_impl_trait_in_trait_bounds(
1542 hir_decl
.output
.span(),
1545 if sig
.abi
== Abi
::RustCall
{
1546 let span
= tcx
.def_span(def_id
);
1547 let has_implicit_self
= hir_decl
.implicit_self
!= hir
::ImplicitSelfKind
::None
;
1548 let mut inputs
= sig
.inputs().iter().skip(if has_implicit_self { 1 }
else { 0 }
);
1549 // Check that the argument is a tuple
1550 if let Some(ty
) = inputs
.next() {
1551 wfcx
.register_bound(
1552 ObligationCause
::new(span
, wfcx
.body_id
, ObligationCauseCode
::RustCall
),
1555 tcx
.require_lang_item(hir
::LangItem
::Tuple
, Some(span
)),
1559 hir_decl
.inputs
.last().map_or(span
, |input
| input
.span
),
1560 "functions with the \"rust-call\" ABI must take a single non-self tuple argument",
1563 // No more inputs other than the `self` type and the tuple type
1564 if inputs
.next().is_some() {
1566 hir_decl
.inputs
.last().map_or(span
, |input
| input
.span
),
1567 "functions with the \"rust-call\" ABI must take a single non-self tuple argument",
1573 /// Basically `check_associated_type_bounds`, but separated for now and should be
1574 /// deduplicated when RPITITs get lowered into real associated items.
1575 #[tracing::instrument(level = "trace", skip(wfcx))]
1576 fn check_return_position_impl_trait_in_trait_bounds
<'tcx
>(
1577 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1578 fn_def_id
: LocalDefId
,
1579 fn_output
: Ty
<'tcx
>,
1582 let tcx
= wfcx
.tcx();
1583 if let Some(assoc_item
) = tcx
.opt_associated_item(fn_def_id
.to_def_id())
1584 && assoc_item
.container
== ty
::AssocItemContainer
::TraitContainer
1586 for arg
in fn_output
.walk() {
1587 if let ty
::GenericArgKind
::Type(ty
) = arg
.unpack()
1588 && let ty
::Alias(ty
::Projection
, proj
) = ty
.kind()
1589 && tcx
.def_kind(proj
.def_id
) == DefKind
::ImplTraitPlaceholder
1590 && tcx
.impl_trait_in_trait_parent(proj
.def_id
) == fn_def_id
.to_def_id()
1592 let span
= tcx
.def_span(proj
.def_id
);
1593 let bounds
= wfcx
.tcx().explicit_item_bounds(proj
.def_id
);
1594 let wf_obligations
= bounds
.iter().flat_map(|&(bound
, bound_span
)| {
1595 let bound
= ty
::EarlyBinder(bound
).subst(tcx
, proj
.substs
);
1596 let normalized_bound
= wfcx
.normalize(span
, None
, bound
);
1597 traits
::wf
::predicate_obligations(
1605 wfcx
.register_obligations(wf_obligations
);
1611 const HELP_FOR_SELF_TYPE
: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
1612 `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
1613 of the previous types except `Self`)";
1615 #[instrument(level = "debug", skip(wfcx))]
1616 fn check_method_receiver
<'tcx
>(
1617 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1618 fn_sig
: &hir
::FnSig
<'_
>,
1619 method
: &ty
::AssocItem
,
1622 let tcx
= wfcx
.tcx();
1624 if !method
.fn_has_self_parameter
{
1628 let span
= fn_sig
.decl
.inputs
[0].span
;
1630 let sig
= tcx
.fn_sig(method
.def_id
);
1631 let sig
= tcx
.liberate_late_bound_regions(method
.def_id
, sig
);
1632 let sig
= wfcx
.normalize(span
, None
, sig
);
1634 debug
!("check_method_receiver: sig={:?}", sig
);
1636 let self_ty
= wfcx
.normalize(span
, None
, self_ty
);
1638 let receiver_ty
= sig
.inputs()[0];
1639 let receiver_ty
= wfcx
.normalize(span
, None
, receiver_ty
);
1641 if tcx
.features().arbitrary_self_types
{
1642 if !receiver_is_valid(wfcx
, span
, receiver_ty
, self_ty
, true) {
1643 // Report error; `arbitrary_self_types` was enabled.
1644 e0307(tcx
, span
, receiver_ty
);
1647 if !receiver_is_valid(wfcx
, span
, receiver_ty
, self_ty
, false) {
1648 if receiver_is_valid(wfcx
, span
, receiver_ty
, self_ty
, true) {
1649 // Report error; would have worked with `arbitrary_self_types`.
1651 &tcx
.sess
.parse_sess
,
1652 sym
::arbitrary_self_types
,
1655 "`{receiver_ty}` cannot be used as the type of `self` without \
1656 the `arbitrary_self_types` feature",
1659 .help(HELP_FOR_SELF_TYPE
)
1662 // Report error; would not have worked with `arbitrary_self_types`.
1663 e0307(tcx
, span
, receiver_ty
);
1669 fn e0307(tcx
: TyCtxt
<'_
>, span
: Span
, receiver_ty
: Ty
<'_
>) {
1671 tcx
.sess
.diagnostic(),
1674 "invalid `self` parameter type: {receiver_ty}"
1676 .note("type of `self` must be `Self` or a type that dereferences to it")
1677 .help(HELP_FOR_SELF_TYPE
)
1681 /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
1682 /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
1683 /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
1684 /// strict: `receiver_ty` must implement `Receiver` and directly implement
1685 /// `Deref<Target = self_ty>`.
1687 /// N.B., there are cases this function returns `true` but causes an error to be emitted,
1688 /// particularly when `receiver_ty` derefs to a type that is the same as `self_ty` but has the
1689 /// wrong lifetime. Be careful of this if you are calling this function speculatively.
1690 fn receiver_is_valid
<'tcx
>(
1691 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1693 receiver_ty
: Ty
<'tcx
>,
1695 arbitrary_self_types_enabled
: bool
,
1697 let infcx
= wfcx
.infcx
;
1698 let tcx
= wfcx
.tcx();
1700 ObligationCause
::new(span
, wfcx
.body_id
, traits
::ObligationCauseCode
::MethodReceiver
);
1702 let can_eq_self
= |ty
| infcx
.can_eq(wfcx
.param_env
, self_ty
, ty
).is_ok();
1704 // `self: Self` is always valid.
1705 if can_eq_self(receiver_ty
) {
1706 if let Err(err
) = wfcx
.eq(&cause
, wfcx
.param_env
, self_ty
, receiver_ty
) {
1707 infcx
.err_ctxt().report_mismatched_types(&cause
, self_ty
, receiver_ty
, err
).emit();
1712 let mut autoderef
= Autoderef
::new(infcx
, wfcx
.param_env
, wfcx
.body_id
, span
, receiver_ty
);
1714 // The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`.
1715 if arbitrary_self_types_enabled
{
1716 autoderef
= autoderef
.include_raw_pointers();
1719 // The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
1722 let receiver_trait_def_id
= tcx
.require_lang_item(LangItem
::Receiver
, Some(span
));
1724 // Keep dereferencing `receiver_ty` until we get to `self_ty`.
1726 if let Some((potential_self_ty
, _
)) = autoderef
.next() {
1728 "receiver_is_valid: potential self type `{:?}` to match `{:?}`",
1729 potential_self_ty
, self_ty
1732 if can_eq_self(potential_self_ty
) {
1733 wfcx
.register_obligations(autoderef
.into_obligations());
1735 if let Err(err
) = wfcx
.eq(&cause
, wfcx
.param_env
, self_ty
, potential_self_ty
) {
1738 .report_mismatched_types(&cause
, self_ty
, potential_self_ty
, err
)
1744 // Without `feature(arbitrary_self_types)`, we require that each step in the
1745 // deref chain implement `receiver`
1746 if !arbitrary_self_types_enabled
1747 && !receiver_is_implemented(
1749 receiver_trait_def_id
,
1758 debug
!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty
, self_ty
);
1759 // If the receiver already has errors reported due to it, consider it valid to avoid
1760 // unnecessary errors (#58712).
1761 return receiver_ty
.references_error();
1765 // Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`.
1766 if !arbitrary_self_types_enabled
1767 && !receiver_is_implemented(wfcx
, receiver_trait_def_id
, cause
.clone(), receiver_ty
)
1775 fn receiver_is_implemented
<'tcx
>(
1776 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1777 receiver_trait_def_id
: DefId
,
1778 cause
: ObligationCause
<'tcx
>,
1779 receiver_ty
: Ty
<'tcx
>,
1781 let tcx
= wfcx
.tcx();
1782 let trait_ref
= ty
::Binder
::dummy(tcx
.mk_trait_ref(receiver_trait_def_id
, [receiver_ty
]));
1784 let obligation
= traits
::Obligation
::new(tcx
, cause
, wfcx
.param_env
, trait_ref
);
1786 if wfcx
.infcx
.predicate_must_hold_modulo_regions(&obligation
) {
1790 "receiver_is_implemented: type `{:?}` does not implement `Receiver` trait",
1797 fn check_variances_for_type_defn
<'tcx
>(
1799 item
: &hir
::Item
<'tcx
>,
1800 hir_generics
: &hir
::Generics
<'_
>,
1802 let ty
= tcx
.type_of(item
.owner_id
);
1803 if tcx
.has_error_field(ty
) {
1807 let ty_predicates
= tcx
.predicates_of(item
.owner_id
);
1808 assert_eq
!(ty_predicates
.parent
, None
);
1809 let variances
= tcx
.variances_of(item
.owner_id
);
1811 let mut constrained_parameters
: FxHashSet
<_
> = variances
1814 .filter(|&(_
, &variance
)| variance
!= ty
::Bivariant
)
1815 .map(|(index
, _
)| Parameter(index
as u32))
1818 identify_constrained_generic_params(tcx
, ty_predicates
, None
, &mut constrained_parameters
);
1820 // Lazily calculated because it is only needed in case of an error.
1821 let explicitly_bounded_params
= LazyCell
::new(|| {
1822 let icx
= crate::collect
::ItemCtxt
::new(tcx
, item
.owner_id
.to_def_id());
1826 .filter_map(|predicate
| match predicate
{
1827 hir
::WherePredicate
::BoundPredicate(predicate
) => {
1828 match icx
.to_ty(predicate
.bounded_ty
).kind() {
1829 ty
::Param(data
) => Some(Parameter(data
.index
)),
1835 .collect
::<FxHashSet
<_
>>()
1838 for (index
, _
) in variances
.iter().enumerate() {
1839 let parameter
= Parameter(index
as u32);
1841 if constrained_parameters
.contains(¶meter
) {
1845 let param
= &hir_generics
.params
[index
];
1848 hir
::ParamName
::Error
=> {}
1850 let has_explicit_bounds
= explicitly_bounded_params
.contains(¶meter
);
1851 report_bivariance(tcx
, param
, has_explicit_bounds
);
1857 fn report_bivariance(
1859 param
: &rustc_hir
::GenericParam
<'_
>,
1860 has_explicit_bounds
: bool
,
1861 ) -> ErrorGuaranteed
{
1862 let span
= param
.span
;
1863 let param_name
= param
.name
.ident().name
;
1864 let mut err
= error_392(tcx
, span
, param_name
);
1866 let suggested_marker_id
= tcx
.lang_items().phantom_data();
1867 // Help is available only in presence of lang items.
1868 let msg
= if let Some(def_id
) = suggested_marker_id
{
1870 "consider removing `{}`, referring to it in a field, or using a marker such as `{}`",
1872 tcx
.def_path_str(def_id
),
1875 format
!("consider removing `{param_name}` or referring to it in a field")
1879 if matches
!(param
.kind
, hir
::GenericParamKind
::Type { .. }
) && !has_explicit_bounds
{
1881 "if you intended `{0}` to be a const parameter, use `const {0}: usize` instead",
1888 impl<'tcx
> WfCheckingCtxt
<'_
, 'tcx
> {
1889 /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
1891 #[instrument(level = "debug", skip(self))]
1892 fn check_false_global_bounds(&mut self) {
1893 let tcx
= self.ocx
.infcx
.tcx
;
1894 let mut span
= self.span
;
1895 let empty_env
= ty
::ParamEnv
::empty();
1897 let def_id
= tcx
.hir().local_def_id(self.body_id
);
1898 let predicates_with_span
= tcx
.predicates_of(def_id
).predicates
.iter().copied();
1899 // Check elaborated bounds.
1900 let implied_obligations
= traits
::elaborate_predicates_with_span(tcx
, predicates_with_span
);
1902 for obligation
in implied_obligations
{
1903 // We lower empty bounds like `Vec<dyn Copy>:` as
1904 // `WellFormed(Vec<dyn Copy>)`, which will later get checked by
1905 // regular WF checking
1906 if let ty
::PredicateKind
::WellFormed(..) = obligation
.predicate
.kind().skip_binder() {
1909 let pred
= obligation
.predicate
;
1910 // Match the existing behavior.
1911 if pred
.is_global() && !pred
.has_late_bound_vars() {
1912 let pred
= self.normalize(span
, None
, pred
);
1913 let hir_node
= tcx
.hir().find(self.body_id
);
1915 // only use the span of the predicate clause (#90869)
1917 if let Some(hir
::Generics { predicates, .. }
) =
1918 hir_node
.and_then(|node
| node
.generics())
1920 let obligation_span
= obligation
.cause
.span();
1924 // There seems to be no better way to find out which predicate we are in
1925 .find(|pred
| pred
.span().contains(obligation_span
))
1926 .map(|pred
| pred
.span())
1927 .unwrap_or(obligation_span
);
1930 let obligation
= traits
::Obligation
::new(
1932 traits
::ObligationCause
::new(span
, self.body_id
, traits
::TrivialBound
),
1936 self.ocx
.register_obligation(obligation
);
1942 fn check_mod_type_wf(tcx
: TyCtxt
<'_
>, module
: LocalDefId
) {
1943 let items
= tcx
.hir_module_items(module
);
1944 items
.par_items(|item
| tcx
.ensure().check_well_formed(item
.owner_id
));
1945 items
.par_impl_items(|item
| tcx
.ensure().check_well_formed(item
.owner_id
));
1946 items
.par_trait_items(|item
| tcx
.ensure().check_well_formed(item
.owner_id
));
1947 items
.par_foreign_items(|item
| tcx
.ensure().check_well_formed(item
.owner_id
));
1954 ) -> DiagnosticBuilder
<'_
, ErrorGuaranteed
> {
1955 let mut err
= struct_span_err
!(tcx
.sess
, span
, E0392
, "parameter `{param_name}` is never used");
1956 err
.span_label(span
, "unused parameter");
1960 pub fn provide(providers
: &mut Providers
) {
1961 *providers
= Providers { check_mod_type_wf, check_well_formed, ..*providers }
;