1 use crate::constrained_generic_params
::{identify_constrained_generic_params, Parameter}
;
4 use rustc_data_structures
::fx
::{FxHashMap, FxHashSet}
;
5 use rustc_errors
::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}
;
7 use rustc_hir
::def_id
::{DefId, LocalDefId}
;
8 use rustc_hir
::lang_items
::LangItem
;
9 use rustc_hir
::ItemKind
;
10 use rustc_infer
::infer
::outlives
::env
::{OutlivesEnvironment, RegionBoundPairs}
;
11 use rustc_infer
::infer
::outlives
::obligations
::TypeOutlives
;
12 use rustc_infer
::infer
::{self, InferCtxt, TyCtxtInferExt}
;
13 use rustc_middle
::mir
::ConstraintCategory
;
14 use rustc_middle
::ty
::query
::Providers
;
15 use rustc_middle
::ty
::subst
::{GenericArgKind, InternalSubsts, Subst}
;
16 use rustc_middle
::ty
::trait_def
::TraitSpecializationKind
;
17 use rustc_middle
::ty
::{
18 self, AdtKind
, DefIdTree
, GenericParamDefKind
, ToPredicate
, Ty
, TyCtxt
, TypeFoldable
,
19 TypeSuperVisitable
, TypeVisitable
, TypeVisitor
,
21 use rustc_session
::parse
::feature_err
;
22 use rustc_span
::symbol
::{sym, Ident, Symbol}
;
23 use rustc_span
::{Span, DUMMY_SP}
;
24 use rustc_trait_selection
::autoderef
::Autoderef
;
25 use rustc_trait_selection
::traits
::error_reporting
::InferCtxtExt
;
26 use rustc_trait_selection
::traits
::outlives_bounds
::InferCtxtExt
as _
;
27 use rustc_trait_selection
::traits
::query
::evaluate_obligation
::InferCtxtExt
as _
;
28 use rustc_trait_selection
::traits
::{
29 self, ObligationCause
, ObligationCauseCode
, ObligationCtxt
, WellFormedLoc
,
32 use std
::cell
::LazyCell
;
33 use std
::convert
::TryInto
;
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 fn normalize
<T
>(&self, span
: Span
, loc
: Option
<WellFormedLoc
>, value
: T
) -> T
57 T
: TypeFoldable
<'tcx
>,
60 ObligationCause
::new(span
, self.body_id
, ObligationCauseCode
::WellFormed(loc
)),
66 fn register_wf_obligation(
69 loc
: Option
<WellFormedLoc
>,
70 arg
: ty
::GenericArg
<'tcx
>,
73 traits
::ObligationCause
::new(span
, self.body_id
, ObligationCauseCode
::WellFormed(loc
));
74 // for a type to be WF, we do not need to check if const trait predicates satisfy.
75 let param_env
= self.param_env
.without_const();
76 self.ocx
.register_obligation(traits
::Obligation
::new(
79 ty
::Binder
::dummy(ty
::PredicateKind
::WellFormed(arg
)).to_predicate(self.tcx()),
84 pub(super) fn enter_wf_checking_ctxt
<'tcx
, F
>(
87 body_def_id
: LocalDefId
,
90 F
: for<'a
> FnOnce(&WfCheckingCtxt
<'a
, 'tcx
>),
92 let param_env
= tcx
.param_env(body_def_id
);
93 let body_id
= tcx
.hir().local_def_id_to_hir_id(body_def_id
);
94 tcx
.infer_ctxt().enter(|ref infcx
| {
95 let ocx
= ObligationCtxt
::new(infcx
);
97 let assumed_wf_types
= ocx
.assumed_wf_types(param_env
, span
, body_def_id
);
99 let mut wfcx
= WfCheckingCtxt { ocx, span, body_id, param_env }
;
101 if !tcx
.features().trivial_bounds
{
102 wfcx
.check_false_global_bounds()
105 let errors
= wfcx
.select_all_or_error();
106 if !errors
.is_empty() {
107 infcx
.report_fulfillment_errors(&errors
, None
, false);
111 let implied_bounds
= infcx
.implied_bounds_tys(param_env
, body_id
, assumed_wf_types
);
112 let outlives_environment
=
113 OutlivesEnvironment
::with_bounds(param_env
, Some(infcx
), implied_bounds
);
115 infcx
.check_region_obligations_and_report_errors(body_def_id
, &outlives_environment
);
119 fn check_well_formed(tcx
: TyCtxt
<'_
>, def_id
: LocalDefId
) {
120 let node
= tcx
.hir().expect_owner(def_id
);
122 hir
::OwnerNode
::Crate(_
) => {}
123 hir
::OwnerNode
::Item(item
) => check_item(tcx
, item
),
124 hir
::OwnerNode
::TraitItem(item
) => check_trait_item(tcx
, item
),
125 hir
::OwnerNode
::ImplItem(item
) => check_impl_item(tcx
, item
),
126 hir
::OwnerNode
::ForeignItem(item
) => check_foreign_item(tcx
, item
),
129 if let Some(generics
) = node
.generics() {
130 for param
in generics
.params
{
131 check_param_wf(tcx
, param
)
136 /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
137 /// well-formed, meaning that they do not require any constraints not declared in the struct
138 /// definition itself. For example, this definition would be illegal:
141 /// struct Ref<'a, T> { x: &'a T }
144 /// because the type did not declare that `T:'a`.
146 /// We do this check as a pre-pass before checking fn bodies because if these constraints are
147 /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
149 #[instrument(skip(tcx), level = "debug")]
150 fn check_item
<'tcx
>(tcx
: TyCtxt
<'tcx
>, item
: &'tcx hir
::Item
<'tcx
>) {
151 let def_id
= item
.def_id
;
155 item
.name
= ? tcx
.def_path_str(def_id
.to_def_id())
159 // Right now we check that every default trait implementation
160 // has an implementation of itself. Basically, a case like:
162 // impl Trait for T {}
164 // has a requirement of `T: Trait` which was required for default
165 // method implementations. Although this could be improved now that
166 // there's a better infrastructure in place for this, it's being left
167 // for a follow-up work.
169 // Since there's such a requirement, we need to check *just* positive
170 // implementations, otherwise things like:
172 // impl !Send for T {}
174 // won't be allowed unless there's an *explicit* implementation of `Send`
176 hir
::ItemKind
::Impl(ref impl_
) => {
178 .impl_trait_ref(item
.def_id
)
179 .map_or(false, |trait_ref
| tcx
.trait_is_auto(trait_ref
.def_id
));
180 if let (hir
::Defaultness
::Default { .. }
, true) = (impl_
.defaultness
, is_auto
) {
181 let sp
= impl_
.of_trait
.as_ref().map_or(item
.span
, |t
| t
.path
.span
);
183 tcx
.sess
.struct_span_err(sp
, "impls of auto traits cannot be default");
184 err
.span_labels(impl_
.defaultness_span
, "default because of this");
185 err
.span_label(sp
, "auto trait");
188 // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
189 match (tcx
.impl_polarity(def_id
), impl_
.polarity
) {
190 (ty
::ImplPolarity
::Positive
, _
) => {
191 check_impl(tcx
, item
, impl_
.self_ty
, &impl_
.of_trait
, impl_
.constness
);
193 (ty
::ImplPolarity
::Negative
, ast
::ImplPolarity
::Negative(span
)) => {
194 // FIXME(#27579): what amount of WF checking do we need for neg impls?
195 if let hir
::Defaultness
::Default { .. }
= impl_
.defaultness
{
196 let mut spans
= vec
![span
];
197 spans
.extend(impl_
.defaultness_span
);
202 "negative impls cannot be default impls"
207 (ty
::ImplPolarity
::Reservation
, _
) => {
208 // FIXME: what amount of WF checking do we need for reservation impls?
213 hir
::ItemKind
::Fn(ref sig
, ..) => {
214 check_item_fn(tcx
, item
.def_id
, item
.ident
, item
.span
, sig
.decl
);
216 hir
::ItemKind
::Static(ty
, ..) => {
217 check_item_type(tcx
, item
.def_id
, ty
.span
, false);
219 hir
::ItemKind
::Const(ty
, ..) => {
220 check_item_type(tcx
, item
.def_id
, ty
.span
, false);
222 hir
::ItemKind
::Struct(ref struct_def
, ref ast_generics
) => {
223 check_type_defn(tcx
, item
, false, |wfcx
| vec
![wfcx
.non_enum_variant(struct_def
)]);
225 check_variances_for_type_defn(tcx
, item
, ast_generics
);
227 hir
::ItemKind
::Union(ref struct_def
, ref ast_generics
) => {
228 check_type_defn(tcx
, item
, true, |wfcx
| vec
![wfcx
.non_enum_variant(struct_def
)]);
230 check_variances_for_type_defn(tcx
, item
, ast_generics
);
232 hir
::ItemKind
::Enum(ref enum_def
, ref ast_generics
) => {
233 check_type_defn(tcx
, item
, true, |wfcx
| wfcx
.enum_variants(enum_def
));
235 check_variances_for_type_defn(tcx
, item
, ast_generics
);
237 hir
::ItemKind
::Trait(..) => {
238 check_trait(tcx
, item
);
240 hir
::ItemKind
::TraitAlias(..) => {
241 check_trait(tcx
, item
);
243 // `ForeignItem`s are handled separately.
244 hir
::ItemKind
::ForeignMod { .. }
=> {}
249 fn check_foreign_item(tcx
: TyCtxt
<'_
>, item
: &hir
::ForeignItem
<'_
>) {
250 let def_id
= item
.def_id
;
254 item
.name
= ? tcx
.def_path_str(def_id
.to_def_id())
258 hir
::ForeignItemKind
::Fn(decl
, ..) => {
259 check_item_fn(tcx
, item
.def_id
, item
.ident
, item
.span
, decl
)
261 hir
::ForeignItemKind
::Static(ty
, ..) => check_item_type(tcx
, item
.def_id
, ty
.span
, true),
262 hir
::ForeignItemKind
::Type
=> (),
266 fn check_trait_item(tcx
: TyCtxt
<'_
>, trait_item
: &hir
::TraitItem
<'_
>) {
267 let def_id
= trait_item
.def_id
;
269 let (method_sig
, span
) = match trait_item
.kind
{
270 hir
::TraitItemKind
::Fn(ref sig
, _
) => (Some(sig
), trait_item
.span
),
271 hir
::TraitItemKind
::Type(_bounds
, Some(ty
)) => (None
, ty
.span
),
272 _
=> (None
, trait_item
.span
),
274 check_object_unsafe_self_trait_by_name(tcx
, trait_item
);
275 check_associated_item(tcx
, trait_item
.def_id
, span
, method_sig
);
277 let encl_trait_def_id
= tcx
.local_parent(def_id
);
278 let encl_trait
= tcx
.hir().expect_item(encl_trait_def_id
);
279 let encl_trait_def_id
= encl_trait
.def_id
.to_def_id();
280 let fn_lang_item_name
= if Some(encl_trait_def_id
) == tcx
.lang_items().fn_trait() {
282 } else if Some(encl_trait_def_id
) == tcx
.lang_items().fn_mut_trait() {
288 if let (Some(fn_lang_item_name
), "call") =
289 (fn_lang_item_name
, trait_item
.ident
.name
.to_ident_string().as_str())
291 // We are looking at the `call` function of the `fn` or `fn_mut` lang item.
292 // Do some rudimentary sanity checking to avoid an ICE later (issue #83471).
293 if let Some(hir
::FnSig { decl, span, .. }
) = method_sig
{
294 if let [self_ty
, _
] = decl
.inputs
{
295 if !matches
!(self_ty
.kind
, hir
::TyKind
::Rptr(_
, _
)) {
300 "first argument of `call` in `{fn_lang_item_name}` lang item must be a reference",
310 "`call` function in `{fn_lang_item_name}` lang item takes exactly two arguments",
320 "`call` trait item in `{fn_lang_item_name}` lang item must be a function",
328 /// Require that the user writes where clauses on GATs for the implicit
329 /// outlives bounds involving trait parameters in trait functions and
330 /// lifetimes passed as GAT substs. See `self-outlives-lint` test.
332 /// We use the following trait as an example throughout this function:
333 /// ```rust,ignore (this code fails due to this lint)
335 /// type Iter<'a>: Iterator<Item = Self::Item<'a>>;
337 /// fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
340 fn check_gat_where_clauses(tcx
: TyCtxt
<'_
>, associated_items
: &[hir
::TraitItemRef
]) {
341 // Associates every GAT's def_id to a list of possibly missing bounds detected by this lint.
342 let mut required_bounds_by_item
= FxHashMap
::default();
344 // Loop over all GATs together, because if this lint suggests adding a where-clause bound
345 // to one GAT, it might then require us to an additional bound on another GAT.
346 // In our `IntoIter` example, we discover a missing `Self: 'a` bound on `Iter<'a>`, which
347 // then in a second loop adds a `Self: 'a` bound to `Item` due to the relationship between
350 let mut should_continue
= false;
351 for gat_item
in associated_items
{
352 let gat_def_id
= gat_item
.id
.def_id
;
353 let gat_item
= tcx
.associated_item(gat_def_id
);
354 // If this item is not an assoc ty, or has no substs, then it's not a GAT
355 if gat_item
.kind
!= ty
::AssocKind
::Type
{
358 let gat_generics
= tcx
.generics_of(gat_def_id
);
359 // FIXME(jackh726): we can also warn in the more general case
360 if gat_generics
.params
.is_empty() {
364 // Gather the bounds with which all other items inside of this trait constrain the GAT.
365 // This is calculated by taking the intersection of the bounds that each item
366 // constrains the GAT with individually.
367 let mut new_required_bounds
: Option
<FxHashSet
<ty
::Predicate
<'_
>>> = None
;
368 for item
in associated_items
{
369 let item_def_id
= item
.id
.def_id
;
370 // Skip our own GAT, since it does not constrain itself at all.
371 if item_def_id
== gat_def_id
{
375 let item_hir_id
= item
.id
.hir_id();
376 let param_env
= tcx
.param_env(item_def_id
);
378 let item_required_bounds
= match item
.kind
{
379 // In our example, this corresponds to `into_iter` method
380 hir
::AssocItemKind
::Fn { .. }
=> {
381 // For methods, we check the function signature's return type for any GATs
382 // to constrain. In the `into_iter` case, we see that the return type
383 // `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
384 let sig
: ty
::FnSig
<'_
> = tcx
.liberate_late_bound_regions(
385 item_def_id
.to_def_id(),
386 tcx
.fn_sig(item_def_id
),
392 sig
.inputs_and_output
,
393 // We also assume that all of the function signature's parameter types
395 &sig
.inputs().iter().copied().collect(),
400 // In our example, this corresponds to the `Iter` and `Item` associated types
401 hir
::AssocItemKind
::Type
=> {
402 // If our associated item is a GAT with missing bounds, add them to
403 // the param-env here. This allows this GAT to propagate missing bounds
405 let param_env
= augment_param_env(
408 required_bounds_by_item
.get(&item_def_id
),
414 tcx
.explicit_item_bounds(item_def_id
)
417 .collect
::<Vec
<_
>>(),
418 &FxHashSet
::default(),
423 hir
::AssocItemKind
::Const
=> None
,
426 if let Some(item_required_bounds
) = item_required_bounds
{
427 // Take the intersection of the required bounds for this GAT, and
428 // the item_required_bounds which are the ones implied by just
430 // This is why we use an Option<_>, since we need to distinguish
431 // the empty set of bounds from the _uninitialized_ set of bounds.
432 if let Some(new_required_bounds
) = &mut new_required_bounds
{
433 new_required_bounds
.retain(|b
| item_required_bounds
.contains(b
));
435 new_required_bounds
= Some(item_required_bounds
);
440 if let Some(new_required_bounds
) = new_required_bounds
{
441 let required_bounds
= required_bounds_by_item
.entry(gat_def_id
).or_default();
442 if new_required_bounds
.into_iter().any(|p
| required_bounds
.insert(p
)) {
443 // Iterate until our required_bounds no longer change
444 // Since they changed here, we should continue the loop
445 should_continue
= true;
449 // We know that this loop will eventually halt, since we only set `should_continue` if the
450 // `required_bounds` for this item grows. Since we are not creating any new region or type
451 // variables, the set of all region and type bounds that we could ever insert are limited
452 // by the number of unique types and regions we observe in a given item.
453 if !should_continue
{
458 for (gat_def_id
, required_bounds
) in required_bounds_by_item
{
459 let gat_item_hir
= tcx
.hir().expect_trait_item(gat_def_id
);
460 debug
!(?required_bounds
);
461 let param_env
= tcx
.param_env(gat_def_id
);
462 let gat_hir
= gat_item_hir
.hir_id();
464 let mut unsatisfied_bounds
: Vec
<_
> = required_bounds
466 .filter(|clause
| match clause
.kind().skip_binder() {
467 ty
::PredicateKind
::RegionOutlives(ty
::OutlivesPredicate(a
, b
)) => {
468 !region_known_to_outlive(tcx
, gat_hir
, param_env
, &FxHashSet
::default(), a
, b
)
470 ty
::PredicateKind
::TypeOutlives(ty
::OutlivesPredicate(a
, b
)) => {
471 !ty_known_to_outlive(tcx
, gat_hir
, param_env
, &FxHashSet
::default(), a
, b
)
473 _
=> bug
!("Unexpected PredicateKind"),
475 .map(|clause
| clause
.to_string())
478 // We sort so that order is predictable
479 unsatisfied_bounds
.sort();
481 if !unsatisfied_bounds
.is_empty() {
482 let plural
= pluralize
!(unsatisfied_bounds
.len());
483 let mut err
= tcx
.sess
.struct_span_err(
485 &format
!("missing required bound{} on `{}`", plural
, gat_item_hir
.ident
),
488 let suggestion
= format
!(
490 gat_item_hir
.generics
.add_where_or_trailing_comma(),
491 unsatisfied_bounds
.join(", "),
494 gat_item_hir
.generics
.tail_span_for_predicate_suggestion(),
495 &format
!("add the required where clause{plural}"),
497 Applicability
::MachineApplicable
,
501 if unsatisfied_bounds
.len() > 1 { "these bounds are" }
else { "this bound is" }
;
503 "{} currently required to ensure that impls have maximum flexibility",
507 "we are soliciting feedback, see issue #87479 \
508 <https://github.com/rust-lang/rust/issues/87479> \
509 for more information",
517 /// Add a new set of predicates to the caller_bounds of an existing param_env.
518 fn augment_param_env
<'tcx
>(
520 param_env
: ty
::ParamEnv
<'tcx
>,
521 new_predicates
: Option
<&FxHashSet
<ty
::Predicate
<'tcx
>>>,
522 ) -> ty
::ParamEnv
<'tcx
> {
523 let Some(new_predicates
) = new_predicates
else {
527 if new_predicates
.is_empty() {
532 tcx
.mk_predicates(param_env
.caller_bounds().iter().chain(new_predicates
.iter().cloned()));
533 // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
534 // i.e. traits::normalize_param_env_or_error
535 ty
::ParamEnv
::new(bounds
, param_env
.reveal(), param_env
.constness())
538 /// We use the following trait as an example throughout this function.
539 /// Specifically, let's assume that `to_check` here is the return type
540 /// of `into_iter`, and the GAT we are checking this for is `Iter`.
541 /// ```rust,ignore (this code fails due to this lint)
543 /// type Iter<'a>: Iterator<Item = Self::Item<'a>>;
545 /// fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
548 fn gather_gat_bounds
<'tcx
, T
: TypeFoldable
<'tcx
>>(
550 param_env
: ty
::ParamEnv
<'tcx
>,
551 item_hir
: hir
::HirId
,
553 wf_tys
: &FxHashSet
<Ty
<'tcx
>>,
554 gat_def_id
: LocalDefId
,
555 gat_generics
: &'tcx ty
::Generics
,
556 ) -> Option
<FxHashSet
<ty
::Predicate
<'tcx
>>> {
557 // The bounds we that we would require from `to_check`
558 let mut bounds
= FxHashSet
::default();
560 let (regions
, types
) = GATSubstCollector
::visit(gat_def_id
.to_def_id(), to_check
);
562 // If both regions and types are empty, then this GAT isn't in the
563 // set of types we are checking, and we shouldn't try to do clause analysis
564 // (particularly, doing so would end up with an empty set of clauses,
565 // since the current method would require none, and we take the
566 // intersection of requirements of all methods)
567 if types
.is_empty() && regions
.is_empty() {
571 for (region_a
, region_a_idx
) in ®ions
{
572 // Ignore `'static` lifetimes for the purpose of this lint: it's
573 // because we know it outlives everything and so doesn't give meaningful
575 if let ty
::ReStatic
= **region_a
{
578 // For each region argument (e.g., `'a` in our example), check for a
579 // relationship to the type arguments (e.g., `Self`). If there is an
580 // outlives relationship (`Self: 'a`), then we want to ensure that is
581 // reflected in a where clause on the GAT itself.
582 for (ty
, ty_idx
) in &types
{
583 // In our example, requires that `Self: 'a`
584 if ty_known_to_outlive(tcx
, item_hir
, param_env
, &wf_tys
, *ty
, *region_a
) {
585 debug
!(?ty_idx
, ?region_a_idx
);
586 debug
!("required clause: {ty} must outlive {region_a}");
587 // Translate into the generic parameters of the GAT. In
588 // our example, the type was `Self`, which will also be
589 // `Self` in the GAT.
590 let ty_param
= gat_generics
.param_at(*ty_idx
, tcx
);
592 .mk_ty(ty
::Param(ty
::ParamTy { index: ty_param.index, name: ty_param.name }
));
593 // Same for the region. In our example, 'a corresponds
594 // to the 'me parameter.
595 let region_param
= gat_generics
.param_at(*region_a_idx
, tcx
);
597 tcx
.mk_region(ty
::RegionKind
::ReEarlyBound(ty
::EarlyBoundRegion
{
598 def_id
: region_param
.def_id
,
599 index
: region_param
.index
,
600 name
: region_param
.name
,
602 // The predicate we expect to see. (In our example,
605 ty
::PredicateKind
::TypeOutlives(ty
::OutlivesPredicate(ty_param
, region_param
));
606 let clause
= tcx
.mk_predicate(ty
::Binder
::dummy(clause
));
607 bounds
.insert(clause
);
611 // For each region argument (e.g., `'a` in our example), also check for a
612 // relationship to the other region arguments. If there is an outlives
613 // relationship, then we want to ensure that is reflected in the where clause
614 // on the GAT itself.
615 for (region_b
, region_b_idx
) in ®ions
{
616 // Again, skip `'static` because it outlives everything. Also, we trivially
617 // know that a region outlives itself.
618 if ty
::ReStatic
== **region_b
|| region_a
== region_b
{
621 if region_known_to_outlive(tcx
, item_hir
, param_env
, &wf_tys
, *region_a
, *region_b
) {
622 debug
!(?region_a_idx
, ?region_b_idx
);
623 debug
!("required clause: {region_a} must outlive {region_b}");
624 // Translate into the generic parameters of the GAT.
625 let region_a_param
= gat_generics
.param_at(*region_a_idx
, tcx
);
627 tcx
.mk_region(ty
::RegionKind
::ReEarlyBound(ty
::EarlyBoundRegion
{
628 def_id
: region_a_param
.def_id
,
629 index
: region_a_param
.index
,
630 name
: region_a_param
.name
,
632 // Same for the region.
633 let region_b_param
= gat_generics
.param_at(*region_b_idx
, tcx
);
635 tcx
.mk_region(ty
::RegionKind
::ReEarlyBound(ty
::EarlyBoundRegion
{
636 def_id
: region_b_param
.def_id
,
637 index
: region_b_param
.index
,
638 name
: region_b_param
.name
,
640 // The predicate we expect to see.
641 let clause
= ty
::PredicateKind
::RegionOutlives(ty
::OutlivesPredicate(
645 let clause
= tcx
.mk_predicate(ty
::Binder
::dummy(clause
));
646 bounds
.insert(clause
);
654 /// Given a known `param_env` and a set of well formed types, can we prove that
655 /// `ty` outlives `region`.
656 fn ty_known_to_outlive
<'tcx
>(
659 param_env
: ty
::ParamEnv
<'tcx
>,
660 wf_tys
: &FxHashSet
<Ty
<'tcx
>>,
662 region
: ty
::Region
<'tcx
>,
664 resolve_regions_with_wf_tys(tcx
, id
, param_env
, &wf_tys
, |infcx
, region_bound_pairs
| {
665 let origin
= infer
::RelateParamBound(DUMMY_SP
, ty
, None
);
666 let outlives
= &mut TypeOutlives
::new(infcx
, tcx
, region_bound_pairs
, None
, param_env
);
667 outlives
.type_must_outlive(origin
, ty
, region
, ConstraintCategory
::BoringNoLocation
);
671 /// Given a known `param_env` and a set of well formed types, can we prove that
672 /// `region_a` outlives `region_b`
673 fn region_known_to_outlive
<'tcx
>(
676 param_env
: ty
::ParamEnv
<'tcx
>,
677 wf_tys
: &FxHashSet
<Ty
<'tcx
>>,
678 region_a
: ty
::Region
<'tcx
>,
679 region_b
: ty
::Region
<'tcx
>,
681 resolve_regions_with_wf_tys(tcx
, id
, param_env
, &wf_tys
, |mut infcx
, _
| {
682 use rustc_infer
::infer
::outlives
::obligations
::TypeOutlivesDelegate
;
683 let origin
= infer
::RelateRegionParamBound(DUMMY_SP
);
684 // `region_a: region_b` -> `region_b <= region_a`
685 infcx
.push_sub_region_constraint(
689 ConstraintCategory
::BoringNoLocation
,
694 /// Given a known `param_env` and a set of well formed types, set up an
695 /// `InferCtxt`, call the passed function (to e.g. set up region constraints
696 /// to be tested), then resolve region and return errors
697 fn resolve_regions_with_wf_tys
<'tcx
>(
700 param_env
: ty
::ParamEnv
<'tcx
>,
701 wf_tys
: &FxHashSet
<Ty
<'tcx
>>,
702 add_constraints
: impl for<'a
> FnOnce(&'a InferCtxt
<'a
, 'tcx
>, &'a RegionBoundPairs
<'tcx
>),
704 // Unfortunately, we have to use a new `InferCtxt` each call, because
705 // region constraints get added and solved there and we need to test each
706 // call individually.
707 tcx
.infer_ctxt().enter(|infcx
| {
708 let outlives_environment
= OutlivesEnvironment
::with_bounds(
711 infcx
.implied_bounds_tys(param_env
, id
, wf_tys
.clone()),
713 let region_bound_pairs
= outlives_environment
.region_bound_pairs();
715 add_constraints(&infcx
, region_bound_pairs
);
717 let errors
= infcx
.resolve_regions(&outlives_environment
);
719 debug
!(?errors
, "errors");
721 // If we were able to prove that the type outlives the region without
722 // an error, it must be because of the implied or explicit bounds...
727 /// TypeVisitor that looks for uses of GATs like
728 /// `<P0 as Trait<P1..Pn>>::GAT<Pn..Pm>` and adds the arguments `P0..Pm` into
729 /// the two vectors, `regions` and `types` (depending on their kind). For each
730 /// parameter `Pi` also track the index `i`.
731 struct GATSubstCollector
<'tcx
> {
733 // Which region appears and which parameter index its substituted for
734 regions
: FxHashSet
<(ty
::Region
<'tcx
>, usize)>,
735 // Which params appears and which parameter index its substituted for
736 types
: FxHashSet
<(Ty
<'tcx
>, usize)>,
739 impl<'tcx
> GATSubstCollector
<'tcx
> {
740 fn visit
<T
: TypeFoldable
<'tcx
>>(
743 ) -> (FxHashSet
<(ty
::Region
<'tcx
>, usize)>, FxHashSet
<(Ty
<'tcx
>, usize)>) {
745 GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() }
;
746 t
.visit_with(&mut visitor
);
747 (visitor
.regions
, visitor
.types
)
751 impl<'tcx
> TypeVisitor
<'tcx
> for GATSubstCollector
<'tcx
> {
754 fn visit_ty(&mut self, t
: Ty
<'tcx
>) -> ControlFlow
<Self::BreakTy
> {
756 ty
::Projection(p
) if p
.item_def_id
== self.gat
=> {
757 for (idx
, subst
) in p
.substs
.iter().enumerate() {
758 match subst
.unpack() {
759 GenericArgKind
::Lifetime(lt
) if !lt
.is_late_bound() => {
760 self.regions
.insert((lt
, idx
));
762 GenericArgKind
::Type(t
) => {
763 self.types
.insert((t
, idx
));
771 t
.super_visit_with(self)
775 fn could_be_self(trait_def_id
: LocalDefId
, ty
: &hir
::Ty
<'_
>) -> bool
{
777 hir
::TyKind
::TraitObject([trait_ref
], ..) => match trait_ref
.trait_ref
.path
.segments
{
778 [s
] => s
.res
.opt_def_id() == Some(trait_def_id
.to_def_id()),
785 /// Detect when an object unsafe trait is referring to itself in one of its associated items.
786 /// When this is done, suggest using `Self` instead.
787 fn check_object_unsafe_self_trait_by_name(tcx
: TyCtxt
<'_
>, item
: &hir
::TraitItem
<'_
>) {
788 let (trait_name
, trait_def_id
) =
789 match tcx
.hir().get_by_def_id(tcx
.hir().get_parent_item(item
.hir_id())) {
790 hir
::Node
::Item(item
) => match item
.kind
{
791 hir
::ItemKind
::Trait(..) => (item
.ident
, item
.def_id
),
796 let mut trait_should_be_self
= vec
![];
798 hir
::TraitItemKind
::Const(ty
, _
) | hir
::TraitItemKind
::Type(_
, Some(ty
))
799 if could_be_self(trait_def_id
, ty
) =>
801 trait_should_be_self
.push(ty
.span
)
803 hir
::TraitItemKind
::Fn(sig
, _
) => {
804 for ty
in sig
.decl
.inputs
{
805 if could_be_self(trait_def_id
, ty
) {
806 trait_should_be_self
.push(ty
.span
);
809 match sig
.decl
.output
{
810 hir
::FnRetTy
::Return(ty
) if could_be_self(trait_def_id
, ty
) => {
811 trait_should_be_self
.push(ty
.span
);
818 if !trait_should_be_self
.is_empty() {
819 if tcx
.object_safety_violations(trait_def_id
).is_empty() {
822 let sugg
= trait_should_be_self
.iter().map(|span
| (*span
, "Self".to_string())).collect();
825 trait_should_be_self
,
826 "associated item referring to unboxed trait object for its own trait",
828 .span_label(trait_name
.span
, "in this trait")
829 .multipart_suggestion(
830 "you might have meant to use `Self` to refer to the implementing type",
832 Applicability
::MachineApplicable
,
838 fn check_impl_item(tcx
: TyCtxt
<'_
>, impl_item
: &hir
::ImplItem
<'_
>) {
839 let def_id
= impl_item
.def_id
;
841 let (method_sig
, span
) = match impl_item
.kind
{
842 hir
::ImplItemKind
::Fn(ref sig
, _
) => (Some(sig
), impl_item
.span
),
843 // Constrain binding and overflow error spans to `<Ty>` in `type foo = <Ty>`.
844 hir
::ImplItemKind
::TyAlias(ty
) if ty
.span
!= DUMMY_SP
=> (None
, ty
.span
),
845 _
=> (None
, impl_item
.span
),
848 check_associated_item(tcx
, def_id
, span
, method_sig
);
851 fn check_param_wf(tcx
: TyCtxt
<'_
>, param
: &hir
::GenericParam
<'_
>) {
853 // We currently only check wf of const params here.
854 hir
::GenericParamKind
::Lifetime { .. }
| hir
::GenericParamKind
::Type { .. }
=> (),
856 // Const parameters are well formed if their type is structural match.
857 hir
::GenericParamKind
::Const { ty: hir_ty, default: _ }
=> {
858 let ty
= tcx
.type_of(tcx
.hir().local_def_id(param
.hir_id
));
860 if tcx
.features().adt_const_params
{
861 if let Some(non_structural_match_ty
) =
862 traits
::search_for_adt_const_param_violation(param
.span
, tcx
, ty
)
864 // We use the same error code in both branches, because this is really the same
865 // issue: we just special-case the message for type parameters to make it
867 match non_structural_match_ty
.kind() {
869 // Const parameters may not have type parameters as their types,
870 // because we cannot be sure that the type parameter derives `PartialEq`
871 // and `Eq` (just implementing them is not enough for `structural_match`).
876 "`{ty}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
877 used as the type of a const parameter",
881 format
!("`{ty}` may not derive both `PartialEq` and `Eq`"),
884 "it is not currently possible to use a type parameter as the type of a \
894 "`{ty}` is forbidden as the type of a const generic parameter",
896 .note("floats do not derive `Eq` or `Ord`, which are required for const parameters")
904 "using function pointers as const generic parameters is forbidden",
913 "using raw pointers as const generic parameters is forbidden",
918 let mut diag
= struct_span_err
!(
922 "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
923 the type of a const parameter",
924 non_structural_match_ty
,
927 if ty
== non_structural_match_ty
{
930 format
!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),
940 let mut is_ptr
= true;
942 let err
= match ty
.kind() {
943 ty
::Bool
| ty
::Char
| ty
::Int(_
) | ty
::Uint(_
) | ty
::Error(_
) => None
,
944 ty
::FnPtr(_
) => Some("function pointers"),
945 ty
::RawPtr(_
) => Some("raw pointers"),
948 err_ty_str
= format
!("`{ty}`");
949 Some(err_ty_str
.as_str())
953 if let Some(unsupported_type
) = err
{
958 "using {unsupported_type} as const generic parameters is forbidden",
962 let mut err
= tcx
.sess
.struct_span_err(
965 "{unsupported_type} is forbidden as the type of a const generic parameter",
968 err
.note("the only supported types are integers, `bool` and `char`");
969 if tcx
.sess
.is_nightly_build() {
971 "more complex types are supported with `#![feature(adt_const_params)]`",
982 #[instrument(level = "debug", skip(tcx, span, sig_if_method))]
983 fn check_associated_item(
987 sig_if_method
: Option
<&hir
::FnSig
<'_
>>,
989 let loc
= Some(WellFormedLoc
::Ty(item_id
));
990 enter_wf_checking_ctxt(tcx
, span
, item_id
, |wfcx
| {
991 let item
= tcx
.associated_item(item_id
);
993 let self_ty
= match item
.container
{
994 ty
::TraitContainer
=> tcx
.types
.self_param
,
995 ty
::ImplContainer
=> tcx
.type_of(item
.container_id(tcx
)),
999 ty
::AssocKind
::Const
=> {
1000 let ty
= tcx
.type_of(item
.def_id
);
1001 let ty
= wfcx
.normalize(span
, Some(WellFormedLoc
::Ty(item_id
)), ty
);
1002 wfcx
.register_wf_obligation(span
, loc
, ty
.into());
1004 ty
::AssocKind
::Fn
=> {
1005 let sig
= tcx
.fn_sig(item
.def_id
);
1006 let hir_sig
= sig_if_method
.expect("bad signature for method");
1009 item
.ident(tcx
).span
,
1012 item
.def_id
.expect_local(),
1014 check_method_receiver(wfcx
, hir_sig
, item
, self_ty
);
1016 ty
::AssocKind
::Type
=> {
1017 if let ty
::AssocItemContainer
::TraitContainer
= item
.container
{
1018 check_associated_type_bounds(wfcx
, item
, span
)
1020 if item
.defaultness(tcx
).has_value() {
1021 let ty
= tcx
.type_of(item
.def_id
);
1022 let ty
= wfcx
.normalize(span
, Some(WellFormedLoc
::Ty(item_id
)), ty
);
1023 wfcx
.register_wf_obligation(span
, loc
, ty
.into());
1030 fn item_adt_kind(kind
: &ItemKind
<'_
>) -> Option
<AdtKind
> {
1032 ItemKind
::Struct(..) => Some(AdtKind
::Struct
),
1033 ItemKind
::Union(..) => Some(AdtKind
::Union
),
1034 ItemKind
::Enum(..) => Some(AdtKind
::Enum
),
1039 /// In a type definition, we check that to ensure that the types of the fields are well-formed.
1040 fn check_type_defn
<'tcx
, F
>(
1042 item
: &hir
::Item
<'tcx
>,
1044 mut lookup_fields
: F
,
1046 F
: FnMut(&WfCheckingCtxt
<'_
, 'tcx
>) -> Vec
<AdtVariant
<'tcx
>>,
1048 enter_wf_checking_ctxt(tcx
, item
.span
, item
.def_id
, |wfcx
| {
1049 let variants
= lookup_fields(wfcx
);
1050 let packed
= tcx
.adt_def(item
.def_id
).repr().packed();
1052 for variant
in &variants
{
1053 // All field types must be well-formed.
1054 for field
in &variant
.fields
{
1055 wfcx
.register_wf_obligation(
1057 Some(WellFormedLoc
::Ty(field
.def_id
)),
1062 // For DST, or when drop needs to copy things around, all
1063 // intermediate types must be sized.
1064 let needs_drop_copy
= || {
1066 let ty
= variant
.fields
.last().unwrap().ty
;
1067 let ty
= tcx
.erase_regions(ty
);
1068 if ty
.needs_infer() {
1070 .delay_span_bug(item
.span
, &format
!("inference variables in {:?}", ty
));
1071 // Just treat unresolved type expression as if it needs drop.
1074 ty
.needs_drop(tcx
, tcx
.param_env(item
.def_id
))
1078 // All fields (except for possibly the last) should be sized.
1079 let all_sized
= all_sized
|| variant
.fields
.is_empty() || needs_drop_copy();
1080 let unsized_len
= if all_sized { 0 }
else { 1 }
;
1082 variant
.fields
[..variant
.fields
.len() - unsized_len
].iter().enumerate()
1084 let last
= idx
== variant
.fields
.len() - 1;
1085 wfcx
.register_bound(
1086 traits
::ObligationCause
::new(
1089 traits
::FieldSized
{
1090 adt_kind
: match item_adt_kind(&item
.kind
) {
1100 tcx
.require_lang_item(LangItem
::Sized
, None
),
1104 // Explicit `enum` discriminant values must const-evaluate successfully.
1105 if let Some(discr_def_id
) = variant
.explicit_discr
{
1106 let discr_substs
= InternalSubsts
::identity_for_item(tcx
, discr_def_id
.to_def_id());
1108 let cause
= traits
::ObligationCause
::new(
1109 tcx
.def_span(discr_def_id
),
1111 traits
::MiscObligation
,
1113 wfcx
.register_obligation(traits
::Obligation
::new(
1116 ty
::Binder
::dummy(ty
::PredicateKind
::ConstEvaluatable(ty
::Unevaluated
::new(
1117 ty
::WithOptConstParam
::unknown(discr_def_id
.to_def_id()),
1125 check_where_clauses(wfcx
, item
.span
, item
.def_id
);
1129 #[instrument(skip(tcx, item))]
1130 fn check_trait(tcx
: TyCtxt
<'_
>, item
: &hir
::Item
<'_
>) {
1131 debug
!(?item
.def_id
);
1133 let trait_def
= tcx
.trait_def(item
.def_id
);
1134 if trait_def
.is_marker
1135 || matches
!(trait_def
.specialization_kind
, TraitSpecializationKind
::Marker
)
1137 for associated_def_id
in &*tcx
.associated_item_def_ids(item
.def_id
) {
1140 tcx
.def_span(*associated_def_id
),
1142 "marker traits cannot have associated items",
1148 enter_wf_checking_ctxt(tcx
, item
.span
, item
.def_id
, |wfcx
| {
1149 check_where_clauses(wfcx
, item
.span
, item
.def_id
)
1152 // Only check traits, don't check trait aliases
1153 if let hir
::ItemKind
::Trait(_
, _
, _
, _
, items
) = item
.kind
{
1154 check_gat_where_clauses(tcx
, items
);
1158 /// Checks all associated type defaults of trait `trait_def_id`.
1160 /// Assuming the defaults are used, check that all predicates (bounds on the
1161 /// assoc type and where clauses on the trait) hold.
1162 fn check_associated_type_bounds(wfcx
: &WfCheckingCtxt
<'_
, '_
>, item
: &ty
::AssocItem
, span
: Span
) {
1163 let bounds
= wfcx
.tcx().explicit_item_bounds(item
.def_id
);
1165 debug
!("check_associated_type_bounds: bounds={:?}", bounds
);
1166 let wf_obligations
= bounds
.iter().flat_map(|&(bound
, bound_span
)| {
1167 let normalized_bound
= wfcx
.normalize(span
, None
, bound
);
1168 traits
::wf
::predicate_obligations(
1177 wfcx
.register_obligations(wf_obligations
);
1185 decl
: &hir
::FnDecl
<'_
>,
1187 enter_wf_checking_ctxt(tcx
, span
, def_id
, |wfcx
| {
1188 let sig
= tcx
.fn_sig(def_id
);
1189 check_fn_or_method(wfcx
, ident
.span
, sig
, decl
, def_id
);
1193 fn check_item_type(tcx
: TyCtxt
<'_
>, item_id
: LocalDefId
, ty_span
: Span
, allow_foreign_ty
: bool
) {
1194 debug
!("check_item_type: {:?}", item_id
);
1196 enter_wf_checking_ctxt(tcx
, ty_span
, item_id
, |wfcx
| {
1197 let ty
= tcx
.type_of(item_id
);
1198 let item_ty
= wfcx
.normalize(ty_span
, Some(WellFormedLoc
::Ty(item_id
)), ty
);
1200 let mut forbid_unsized
= true;
1201 if allow_foreign_ty
{
1202 let tail
= tcx
.struct_tail_erasing_lifetimes(item_ty
, wfcx
.param_env
);
1203 if let ty
::Foreign(_
) = tail
.kind() {
1204 forbid_unsized
= false;
1208 wfcx
.register_wf_obligation(ty_span
, Some(WellFormedLoc
::Ty(item_id
)), item_ty
.into());
1210 wfcx
.register_bound(
1211 traits
::ObligationCause
::new(ty_span
, wfcx
.body_id
, traits
::WellFormed(None
)),
1214 tcx
.require_lang_item(LangItem
::Sized
, None
),
1218 // Ensure that the end result is `Sync` in a non-thread local `static`.
1219 let should_check_for_sync
= tcx
.static_mutability(item_id
.to_def_id())
1220 == Some(hir
::Mutability
::Not
)
1221 && !tcx
.is_foreign_item(item_id
.to_def_id())
1222 && !tcx
.is_thread_local_static(item_id
.to_def_id());
1224 if should_check_for_sync
{
1225 wfcx
.register_bound(
1226 traits
::ObligationCause
::new(ty_span
, wfcx
.body_id
, traits
::SharedStatic
),
1229 tcx
.require_lang_item(LangItem
::Sync
, Some(ty_span
)),
1235 #[instrument(level = "debug", skip(tcx, ast_self_ty, ast_trait_ref))]
1236 fn check_impl
<'tcx
>(
1238 item
: &'tcx hir
::Item
<'tcx
>,
1239 ast_self_ty
: &hir
::Ty
<'_
>,
1240 ast_trait_ref
: &Option
<hir
::TraitRef
<'_
>>,
1241 constness
: hir
::Constness
,
1243 enter_wf_checking_ctxt(tcx
, item
.span
, item
.def_id
, |wfcx
| {
1244 match *ast_trait_ref
{
1245 Some(ref ast_trait_ref
) => {
1246 // `#[rustc_reservation_impl]` impls are not real impls and
1247 // therefore don't need to be WF (the trait's `Self: Trait` predicate
1249 let trait_ref
= tcx
.impl_trait_ref(item
.def_id
).unwrap();
1250 let trait_ref
= wfcx
.normalize(ast_trait_ref
.path
.span
, None
, trait_ref
);
1251 let trait_pred
= ty
::TraitPredicate
{
1253 constness
: match constness
{
1254 hir
::Constness
::Const
=> ty
::BoundConstness
::ConstIfConst
,
1255 hir
::Constness
::NotConst
=> ty
::BoundConstness
::NotConst
,
1257 polarity
: ty
::ImplPolarity
::Positive
,
1259 let obligations
= traits
::wf
::trait_obligations(
1264 ast_trait_ref
.path
.span
,
1267 debug
!(?obligations
);
1268 wfcx
.register_obligations(obligations
);
1271 let self_ty
= tcx
.type_of(item
.def_id
);
1272 let self_ty
= wfcx
.normalize(
1274 Some(WellFormedLoc
::Ty(item
.hir_id().expect_owner())),
1277 wfcx
.register_wf_obligation(
1279 Some(WellFormedLoc
::Ty(item
.hir_id().expect_owner())),
1285 check_where_clauses(wfcx
, item
.span
, item
.def_id
);
1289 /// Checks where-clauses and inline bounds that are declared on `def_id`.
1290 #[instrument(level = "debug", skip(wfcx))]
1291 fn check_where_clauses
<'tcx
>(wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>, span
: Span
, def_id
: LocalDefId
) {
1292 let infcx
= wfcx
.infcx
;
1293 let tcx
= wfcx
.tcx();
1295 let predicates
= tcx
.bound_predicates_of(def_id
.to_def_id());
1296 let generics
= tcx
.generics_of(def_id
);
1298 let is_our_default
= |def
: &ty
::GenericParamDef
| match def
.kind
{
1299 GenericParamDefKind
::Type { has_default, .. }
1300 | GenericParamDefKind
::Const { has_default }
=> {
1301 has_default
&& def
.index
>= generics
.parent_count
as u32
1303 GenericParamDefKind
::Lifetime
=> unreachable
!(),
1306 // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
1307 // For example, this forbids the declaration:
1309 // struct Foo<T = Vec<[u32]>> { .. }
1311 // Here, the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
1312 for param
in &generics
.params
{
1314 GenericParamDefKind
::Type { .. }
=> {
1315 if is_our_default(param
) {
1316 let ty
= tcx
.type_of(param
.def_id
);
1317 // Ignore dependent defaults -- that is, where the default of one type
1318 // parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
1319 // be sure if it will error or not as user might always specify the other.
1320 if !ty
.needs_subst() {
1321 wfcx
.register_wf_obligation(
1322 tcx
.def_span(param
.def_id
),
1323 Some(WellFormedLoc
::Ty(param
.def_id
.expect_local())),
1329 GenericParamDefKind
::Const { .. }
=> {
1330 if is_our_default(param
) {
1331 // FIXME(const_generics_defaults): This
1332 // is incorrect when dealing with unused substs, for example
1333 // for `struct Foo<const N: usize, const M: usize = { 1 - 2 }>`
1334 // we should eagerly error.
1335 let default_ct
= tcx
.const_param_default(param
.def_id
);
1336 if !default_ct
.needs_subst() {
1337 wfcx
.register_wf_obligation(
1338 tcx
.def_span(param
.def_id
),
1345 // Doesn't have defaults.
1346 GenericParamDefKind
::Lifetime
=> {}
1350 // Check that trait predicates are WF when params are substituted by their defaults.
1351 // We don't want to overly constrain the predicates that may be written but we want to
1352 // catch cases where a default my never be applied such as `struct Foo<T: Copy = String>`.
1353 // Therefore we check if a predicate which contains a single type param
1354 // with a concrete default is WF with that default substituted.
1355 // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
1357 // First we build the defaulted substitution.
1358 let substs
= InternalSubsts
::for_item(tcx
, def_id
.to_def_id(), |param
, _
| {
1360 GenericParamDefKind
::Lifetime
=> {
1361 // All regions are identity.
1362 tcx
.mk_param_from_def(param
)
1365 GenericParamDefKind
::Type { .. }
=> {
1366 // If the param has a default, ...
1367 if is_our_default(param
) {
1368 let default_ty
= tcx
.type_of(param
.def_id
);
1369 // ... and it's not a dependent default, ...
1370 if !default_ty
.needs_subst() {
1371 // ... then substitute it with the default.
1372 return default_ty
.into();
1376 tcx
.mk_param_from_def(param
)
1378 GenericParamDefKind
::Const { .. }
=> {
1379 // If the param has a default, ...
1380 if is_our_default(param
) {
1381 let default_ct
= tcx
.const_param_default(param
.def_id
);
1382 // ... and it's not a dependent default, ...
1383 if !default_ct
.needs_subst() {
1384 // ... then substitute it with the default.
1385 return default_ct
.into();
1389 tcx
.mk_param_from_def(param
)
1394 // Now we build the substituted predicates.
1395 let default_obligations
= predicates
1399 .flat_map(|&(pred
, sp
)| {
1401 struct CountParams
{
1402 params
: FxHashSet
<u32>,
1404 impl<'tcx
> ty
::visit
::TypeVisitor
<'tcx
> for CountParams
{
1407 fn visit_ty(&mut self, t
: Ty
<'tcx
>) -> ControlFlow
<Self::BreakTy
> {
1408 if let ty
::Param(param
) = t
.kind() {
1409 self.params
.insert(param
.index
);
1411 t
.super_visit_with(self)
1414 fn visit_region(&mut self, _
: ty
::Region
<'tcx
>) -> ControlFlow
<Self::BreakTy
> {
1418 fn visit_const(&mut self, c
: ty
::Const
<'tcx
>) -> ControlFlow
<Self::BreakTy
> {
1419 if let ty
::ConstKind
::Param(param
) = c
.kind() {
1420 self.params
.insert(param
.index
);
1422 c
.super_visit_with(self)
1425 let mut param_count
= CountParams
::default();
1426 let has_region
= pred
.visit_with(&mut param_count
).is_break();
1427 let substituted_pred
= predicates
.rebind(pred
).subst(tcx
, substs
);
1428 // Don't check non-defaulted params, dependent defaults (including lifetimes)
1429 // or preds with multiple params.
1430 if substituted_pred
.has_param_types_or_consts()
1431 || param_count
.params
.len() > 1
1435 } else if predicates
.0.predicates
.iter().any(|&(p
, _
)| p
== substituted_pred
) {
1436 // Avoid duplication of predicates that contain no parameters, for example.
1439 Some((substituted_pred
, sp
))
1443 // Convert each of those into an obligation. So if you have
1444 // something like `struct Foo<T: Copy = String>`, we would
1445 // take that predicate `T: Copy`, substitute to `String: Copy`
1446 // (actually that happens in the previous `flat_map` call),
1447 // and then try to prove it (in this case, we'll fail).
1449 // Note the subtle difference from how we handle `predicates`
1450 // below: there, we are not trying to prove those predicates
1451 // to be *true* but merely *well-formed*.
1452 let pred
= wfcx
.normalize(sp
, None
, pred
);
1453 let cause
= traits
::ObligationCause
::new(
1456 traits
::ItemObligation(def_id
.to_def_id()),
1458 traits
::Obligation
::new(cause
, wfcx
.param_env
, pred
)
1461 let predicates
= predicates
.0.instantiate_identity
(tcx
);
1463 let predicates
= wfcx
.normalize(span
, None
, predicates
);
1465 debug
!(?predicates
.predicates
);
1466 assert_eq
!(predicates
.predicates
.len(), predicates
.spans
.len());
1467 let wf_obligations
=
1468 iter
::zip(&predicates
.predicates
, &predicates
.spans
).flat_map(|(&p
, &sp
)| {
1469 traits
::wf
::predicate_obligations(
1471 wfcx
.param_env
.without_const(),
1478 let obligations
: Vec
<_
> = wf_obligations
.chain(default_obligations
).collect();
1479 wfcx
.register_obligations(obligations
);
1482 #[instrument(level = "debug", skip(wfcx, span, hir_decl))]
1483 fn check_fn_or_method
<'tcx
>(
1484 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1486 sig
: ty
::PolyFnSig
<'tcx
>,
1487 hir_decl
: &hir
::FnDecl
<'_
>,
1490 let tcx
= wfcx
.tcx();
1491 let sig
= tcx
.liberate_late_bound_regions(def_id
.to_def_id(), sig
);
1493 // Normalize the input and output types one at a time, using a different
1494 // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
1495 // on the entire `FnSig`, since this would use the same `WellFormedLoc`
1496 // for each type, preventing the HIR wf check from generating
1497 // a nice error message.
1498 let ty
::FnSig { mut inputs_and_output, c_variadic, unsafety, abi }
= sig
;
1499 inputs_and_output
= tcx
.mk_type_list(inputs_and_output
.iter().enumerate().map(|(i
, ty
)| {
1502 Some(WellFormedLoc
::Param
{
1504 // Note that the `param_idx` of the output type is
1505 // one greater than the index of the last input type.
1506 param_idx
: i
.try_into().unwrap(),
1511 // Manually call `normalize_associated_types_in` on the other types
1512 // in `FnSig`. This ensures that if the types of these fields
1513 // ever change to include projections, we will start normalizing
1514 // them automatically.
1515 let sig
= ty
::FnSig
{
1517 c_variadic
: wfcx
.normalize(span
, None
, c_variadic
),
1518 unsafety
: wfcx
.normalize(span
, None
, unsafety
),
1519 abi
: wfcx
.normalize(span
, None
, abi
),
1522 for (i
, (&input_ty
, ty
)) in iter
::zip(sig
.inputs(), hir_decl
.inputs
).enumerate() {
1523 wfcx
.register_wf_obligation(
1525 Some(WellFormedLoc
::Param { function: def_id, param_idx: i.try_into().unwrap() }
),
1530 wfcx
.register_wf_obligation(
1531 hir_decl
.output
.span(),
1532 Some(WellFormedLoc
::Param
{
1534 param_idx
: sig
.inputs().len().try_into().unwrap(),
1536 sig
.output().into(),
1539 check_where_clauses(wfcx
, span
, def_id
);
1541 check_return_position_impl_trait_in_trait_bounds(
1546 hir_decl
.output
.span(),
1550 /// Basically `check_associated_type_bounds`, but separated for now and should be
1551 /// deduplicated when RPITITs get lowered into real associated items.
1552 fn check_return_position_impl_trait_in_trait_bounds
<'tcx
>(
1554 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1555 fn_def_id
: LocalDefId
,
1556 fn_output
: Ty
<'tcx
>,
1559 if let Some(assoc_item
) = tcx
.opt_associated_item(fn_def_id
.to_def_id())
1560 && assoc_item
.container
== ty
::AssocItemContainer
::TraitContainer
1562 for arg
in fn_output
.walk() {
1563 if let ty
::GenericArgKind
::Type(ty
) = arg
.unpack()
1564 && let ty
::Projection(proj
) = ty
.kind()
1565 && tcx
.def_kind(proj
.item_def_id
) == DefKind
::ImplTraitPlaceholder
1566 && tcx
.impl_trait_in_trait_parent(proj
.item_def_id
) == fn_def_id
.to_def_id()
1568 let bounds
= wfcx
.tcx().explicit_item_bounds(proj
.item_def_id
);
1569 let wf_obligations
= bounds
.iter().flat_map(|&(bound
, bound_span
)| {
1570 let normalized_bound
= wfcx
.normalize(span
, None
, bound
);
1571 traits
::wf
::predicate_obligations(
1579 wfcx
.register_obligations(wf_obligations
);
1585 const HELP_FOR_SELF_TYPE
: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
1586 `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
1587 of the previous types except `Self`)";
1589 #[instrument(level = "debug", skip(wfcx))]
1590 fn check_method_receiver
<'tcx
>(
1591 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1592 fn_sig
: &hir
::FnSig
<'_
>,
1593 method
: &ty
::AssocItem
,
1596 let tcx
= wfcx
.tcx();
1598 if !method
.fn_has_self_parameter
{
1602 let span
= fn_sig
.decl
.inputs
[0].span
;
1604 let sig
= tcx
.fn_sig(method
.def_id
);
1605 let sig
= tcx
.liberate_late_bound_regions(method
.def_id
, sig
);
1606 let sig
= wfcx
.normalize(span
, None
, sig
);
1608 debug
!("check_method_receiver: sig={:?}", sig
);
1610 let self_ty
= wfcx
.normalize(span
, None
, self_ty
);
1612 let receiver_ty
= sig
.inputs()[0];
1613 let receiver_ty
= wfcx
.normalize(span
, None
, receiver_ty
);
1615 if tcx
.features().arbitrary_self_types
{
1616 if !receiver_is_valid(wfcx
, span
, receiver_ty
, self_ty
, true) {
1617 // Report error; `arbitrary_self_types` was enabled.
1618 e0307(tcx
, span
, receiver_ty
);
1621 if !receiver_is_valid(wfcx
, span
, receiver_ty
, self_ty
, false) {
1622 if receiver_is_valid(wfcx
, span
, receiver_ty
, self_ty
, true) {
1623 // Report error; would have worked with `arbitrary_self_types`.
1625 &tcx
.sess
.parse_sess
,
1626 sym
::arbitrary_self_types
,
1629 "`{receiver_ty}` cannot be used as the type of `self` without \
1630 the `arbitrary_self_types` feature",
1633 .help(HELP_FOR_SELF_TYPE
)
1636 // Report error; would not have worked with `arbitrary_self_types`.
1637 e0307(tcx
, span
, receiver_ty
);
1643 fn e0307
<'tcx
>(tcx
: TyCtxt
<'tcx
>, span
: Span
, receiver_ty
: Ty
<'_
>) {
1645 tcx
.sess
.diagnostic(),
1648 "invalid `self` parameter type: {receiver_ty}"
1650 .note("type of `self` must be `Self` or a type that dereferences to it")
1651 .help(HELP_FOR_SELF_TYPE
)
1655 /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
1656 /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
1657 /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
1658 /// strict: `receiver_ty` must implement `Receiver` and directly implement
1659 /// `Deref<Target = self_ty>`.
1661 /// N.B., there are cases this function returns `true` but causes an error to be emitted,
1662 /// particularly when `receiver_ty` derefs to a type that is the same as `self_ty` but has the
1663 /// wrong lifetime. Be careful of this if you are calling this function speculatively.
1664 fn receiver_is_valid
<'tcx
>(
1665 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1667 receiver_ty
: Ty
<'tcx
>,
1669 arbitrary_self_types_enabled
: bool
,
1671 let infcx
= wfcx
.infcx
;
1672 let tcx
= wfcx
.tcx();
1674 ObligationCause
::new(span
, wfcx
.body_id
, traits
::ObligationCauseCode
::MethodReceiver
);
1676 let can_eq_self
= |ty
| infcx
.can_eq(wfcx
.param_env
, self_ty
, ty
).is_ok();
1678 // `self: Self` is always valid.
1679 if can_eq_self(receiver_ty
) {
1680 if let Err(err
) = wfcx
.equate_types(&cause
, wfcx
.param_env
, self_ty
, receiver_ty
) {
1681 infcx
.report_mismatched_types(&cause
, self_ty
, receiver_ty
, err
).emit();
1687 Autoderef
::new(infcx
, wfcx
.param_env
, wfcx
.body_id
, span
, receiver_ty
, span
);
1689 // The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`.
1690 if arbitrary_self_types_enabled
{
1691 autoderef
= autoderef
.include_raw_pointers();
1694 // The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
1697 let receiver_trait_def_id
= tcx
.require_lang_item(LangItem
::Receiver
, None
);
1699 // Keep dereferencing `receiver_ty` until we get to `self_ty`.
1701 if let Some((potential_self_ty
, _
)) = autoderef
.next() {
1703 "receiver_is_valid: potential self type `{:?}` to match `{:?}`",
1704 potential_self_ty
, self_ty
1707 if can_eq_self(potential_self_ty
) {
1708 wfcx
.register_obligations(autoderef
.into_obligations());
1711 wfcx
.equate_types(&cause
, wfcx
.param_env
, self_ty
, potential_self_ty
)
1713 infcx
.report_mismatched_types(&cause
, self_ty
, potential_self_ty
, err
).emit();
1718 // Without `feature(arbitrary_self_types)`, we require that each step in the
1719 // deref chain implement `receiver`
1720 if !arbitrary_self_types_enabled
1721 && !receiver_is_implemented(
1723 receiver_trait_def_id
,
1732 debug
!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty
, self_ty
);
1733 // If the receiver already has errors reported due to it, consider it valid to avoid
1734 // unnecessary errors (#58712).
1735 return receiver_ty
.references_error();
1739 // Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`.
1740 if !arbitrary_self_types_enabled
1741 && !receiver_is_implemented(wfcx
, receiver_trait_def_id
, cause
.clone(), receiver_ty
)
1749 fn receiver_is_implemented
<'tcx
>(
1750 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1751 receiver_trait_def_id
: DefId
,
1752 cause
: ObligationCause
<'tcx
>,
1753 receiver_ty
: Ty
<'tcx
>,
1755 let tcx
= wfcx
.tcx();
1756 let trait_ref
= ty
::Binder
::dummy(ty
::TraitRef
{
1757 def_id
: receiver_trait_def_id
,
1758 substs
: tcx
.mk_substs_trait(receiver_ty
, &[]),
1762 traits
::Obligation
::new(cause
, wfcx
.param_env
, trait_ref
.without_const().to_predicate(tcx
));
1764 if wfcx
.infcx
.predicate_must_hold_modulo_regions(&obligation
) {
1768 "receiver_is_implemented: type `{:?}` does not implement `Receiver` trait",
1775 fn check_variances_for_type_defn
<'tcx
>(
1777 item
: &hir
::Item
<'tcx
>,
1778 hir_generics
: &hir
::Generics
<'_
>,
1780 let ty
= tcx
.type_of(item
.def_id
);
1781 if tcx
.has_error_field(ty
) {
1785 let ty_predicates
= tcx
.predicates_of(item
.def_id
);
1786 assert_eq
!(ty_predicates
.parent
, None
);
1787 let variances
= tcx
.variances_of(item
.def_id
);
1789 let mut constrained_parameters
: FxHashSet
<_
> = variances
1792 .filter(|&(_
, &variance
)| variance
!= ty
::Bivariant
)
1793 .map(|(index
, _
)| Parameter(index
as u32))
1796 identify_constrained_generic_params(tcx
, ty_predicates
, None
, &mut constrained_parameters
);
1798 // Lazily calculated because it is only needed in case of an error.
1799 let explicitly_bounded_params
= LazyCell
::new(|| {
1800 let icx
= crate::collect
::ItemCtxt
::new(tcx
, item
.def_id
.to_def_id());
1804 .filter_map(|predicate
| match predicate
{
1805 hir
::WherePredicate
::BoundPredicate(predicate
) => {
1806 match icx
.to_ty(predicate
.bounded_ty
).kind() {
1807 ty
::Param(data
) => Some(Parameter(data
.index
)),
1813 .collect
::<FxHashSet
<_
>>()
1816 for (index
, _
) in variances
.iter().enumerate() {
1817 let parameter
= Parameter(index
as u32);
1819 if constrained_parameters
.contains(¶meter
) {
1823 let param
= &hir_generics
.params
[index
];
1826 hir
::ParamName
::Error
=> {}
1828 let has_explicit_bounds
= explicitly_bounded_params
.contains(¶meter
);
1829 report_bivariance(tcx
, param
, has_explicit_bounds
);
1835 fn report_bivariance(
1837 param
: &rustc_hir
::GenericParam
<'_
>,
1838 has_explicit_bounds
: bool
,
1839 ) -> ErrorGuaranteed
{
1840 let span
= param
.span
;
1841 let param_name
= param
.name
.ident().name
;
1842 let mut err
= error_392(tcx
, span
, param_name
);
1844 let suggested_marker_id
= tcx
.lang_items().phantom_data();
1845 // Help is available only in presence of lang items.
1846 let msg
= if let Some(def_id
) = suggested_marker_id
{
1848 "consider removing `{}`, referring to it in a field, or using a marker such as `{}`",
1850 tcx
.def_path_str(def_id
),
1853 format
!("consider removing `{param_name}` or referring to it in a field")
1857 if matches
!(param
.kind
, hir
::GenericParamKind
::Type { .. }
) && !has_explicit_bounds
{
1859 "if you intended `{0}` to be a const parameter, use `const {0}: usize` instead",
1866 impl<'tcx
> WfCheckingCtxt
<'_
, 'tcx
> {
1867 /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
1869 #[instrument(level = "debug", skip(self))]
1870 fn check_false_global_bounds(&mut self) {
1871 let tcx
= self.ocx
.infcx
.tcx
;
1872 let mut span
= self.span
;
1873 let empty_env
= ty
::ParamEnv
::empty();
1875 let def_id
= tcx
.hir().local_def_id(self.body_id
);
1876 let predicates_with_span
= tcx
.predicates_of(def_id
).predicates
.iter().copied();
1877 // Check elaborated bounds.
1878 let implied_obligations
= traits
::elaborate_predicates_with_span(tcx
, predicates_with_span
);
1880 for obligation
in implied_obligations
{
1881 // We lower empty bounds like `Vec<dyn Copy>:` as
1882 // `WellFormed(Vec<dyn Copy>)`, which will later get checked by
1883 // regular WF checking
1884 if let ty
::PredicateKind
::WellFormed(..) = obligation
.predicate
.kind().skip_binder() {
1887 let pred
= obligation
.predicate
;
1888 // Match the existing behavior.
1889 if pred
.is_global() && !pred
.has_late_bound_regions() {
1890 let pred
= self.normalize(span
, None
, pred
);
1891 let hir_node
= tcx
.hir().find(self.body_id
);
1893 // only use the span of the predicate clause (#90869)
1895 if let Some(hir
::Generics { predicates, .. }
) =
1896 hir_node
.and_then(|node
| node
.generics())
1898 let obligation_span
= obligation
.cause
.span();
1902 // There seems to be no better way to find out which predicate we are in
1903 .find(|pred
| pred
.span().contains(obligation_span
))
1904 .map(|pred
| pred
.span())
1905 .unwrap_or(obligation_span
);
1908 let obligation
= traits
::Obligation
::new(
1909 traits
::ObligationCause
::new(span
, self.body_id
, traits
::TrivialBound
),
1913 self.ocx
.register_obligation(obligation
);
1919 fn check_mod_type_wf(tcx
: TyCtxt
<'_
>, module
: LocalDefId
) {
1920 let items
= tcx
.hir_module_items(module
);
1921 items
.par_items(|item
| tcx
.ensure().check_well_formed(item
.def_id
));
1922 items
.par_impl_items(|item
| tcx
.ensure().check_well_formed(item
.def_id
));
1923 items
.par_trait_items(|item
| tcx
.ensure().check_well_formed(item
.def_id
));
1924 items
.par_foreign_items(|item
| tcx
.ensure().check_well_formed(item
.def_id
));
1927 ///////////////////////////////////////////////////////////////////////////
1930 // FIXME(eddyb) replace this with getting fields/discriminants through `ty::AdtDef`.
1931 struct AdtVariant
<'tcx
> {
1932 /// Types of fields in the variant, that must be well-formed.
1933 fields
: Vec
<AdtField
<'tcx
>>,
1935 /// Explicit discriminant of this variant (e.g. `A = 123`),
1936 /// that must evaluate to a constant value.
1937 explicit_discr
: Option
<LocalDefId
>,
1940 struct AdtField
<'tcx
> {
1946 impl<'a
, 'tcx
> WfCheckingCtxt
<'a
, 'tcx
> {
1947 // FIXME(eddyb) replace this with getting fields through `ty::AdtDef`.
1948 fn non_enum_variant(&self, struct_def
: &hir
::VariantData
<'_
>) -> AdtVariant
<'tcx
> {
1949 let fields
= struct_def
1953 let def_id
= self.tcx().hir().local_def_id(field
.hir_id
);
1954 let field_ty
= self.tcx().type_of(def_id
);
1955 let field_ty
= self.normalize(field
.ty
.span
, None
, field_ty
);
1956 debug
!("non_enum_variant: type of field {:?} is {:?}", field
, field_ty
);
1957 AdtField { ty: field_ty, span: field.ty.span, def_id }
1960 AdtVariant { fields, explicit_discr: None }
1963 fn enum_variants(&self, enum_def
: &hir
::EnumDef
<'_
>) -> Vec
<AdtVariant
<'tcx
>> {
1967 .map(|variant
| AdtVariant
{
1968 fields
: self.non_enum_variant(&variant
.data
).fields
,
1969 explicit_discr
: variant
1971 .map(|explicit_discr
| self.tcx().hir().local_def_id(explicit_discr
.hir_id
)),
1981 ) -> DiagnosticBuilder
<'_
, ErrorGuaranteed
> {
1982 let mut err
= struct_span_err
!(tcx
.sess
, span
, E0392
, "parameter `{param_name}` is never used");
1983 err
.span_label(span
, "unused parameter");
1987 pub fn provide(providers
: &mut Providers
) {
1988 *providers
= Providers { check_mod_type_wf, check_well_formed, ..*providers }
;