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
::trait_def
::TraitSpecializationKind
;
16 use rustc_middle
::ty
::{
17 self, AdtKind
, DefIdTree
, GenericParamDefKind
, ToPredicate
, Ty
, TyCtxt
, TypeFoldable
,
18 TypeSuperVisitable
, TypeVisitable
, TypeVisitor
,
20 use rustc_middle
::ty
::{GenericArgKind, InternalSubsts}
;
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
::TypeErrCtxtExt
;
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 let infcx
= &tcx
.infer_ctxt().build();
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
.err_ctxt().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
);
118 fn check_well_formed(tcx
: TyCtxt
<'_
>, def_id
: hir
::OwnerId
) {
119 let node
= tcx
.hir().expect_owner(def_id
);
121 hir
::OwnerNode
::Crate(_
) => {}
122 hir
::OwnerNode
::Item(item
) => check_item(tcx
, item
),
123 hir
::OwnerNode
::TraitItem(item
) => check_trait_item(tcx
, item
),
124 hir
::OwnerNode
::ImplItem(item
) => check_impl_item(tcx
, item
),
125 hir
::OwnerNode
::ForeignItem(item
) => check_foreign_item(tcx
, item
),
128 if let Some(generics
) = node
.generics() {
129 for param
in generics
.params
{
130 check_param_wf(tcx
, param
)
135 /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
136 /// well-formed, meaning that they do not require any constraints not declared in the struct
137 /// definition itself. For example, this definition would be illegal:
140 /// struct Ref<'a, T> { x: &'a T }
143 /// because the type did not declare that `T:'a`.
145 /// We do this check as a pre-pass before checking fn bodies because if these constraints are
146 /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
148 #[instrument(skip(tcx), level = "debug")]
149 fn check_item
<'tcx
>(tcx
: TyCtxt
<'tcx
>, item
: &'tcx hir
::Item
<'tcx
>) {
150 let def_id
= item
.owner_id
.def_id
;
154 item
.name
= ? tcx
.def_path_str(def_id
.to_def_id())
158 // Right now we check that every default trait implementation
159 // has an implementation of itself. Basically, a case like:
161 // impl Trait for T {}
163 // has a requirement of `T: Trait` which was required for default
164 // method implementations. Although this could be improved now that
165 // there's a better infrastructure in place for this, it's being left
166 // for a follow-up work.
168 // Since there's such a requirement, we need to check *just* positive
169 // implementations, otherwise things like:
171 // impl !Send for T {}
173 // won't be allowed unless there's an *explicit* implementation of `Send`
175 hir
::ItemKind
::Impl(ref impl_
) => {
177 .impl_trait_ref(def_id
)
178 .map_or(false, |trait_ref
| tcx
.trait_is_auto(trait_ref
.def_id
));
179 if let (hir
::Defaultness
::Default { .. }
, true) = (impl_
.defaultness
, is_auto
) {
180 let sp
= impl_
.of_trait
.as_ref().map_or(item
.span
, |t
| t
.path
.span
);
182 tcx
.sess
.struct_span_err(sp
, "impls of auto traits cannot be default");
183 err
.span_labels(impl_
.defaultness_span
, "default because of this");
184 err
.span_label(sp
, "auto trait");
187 // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
188 match (tcx
.impl_polarity(def_id
), impl_
.polarity
) {
189 (ty
::ImplPolarity
::Positive
, _
) => {
190 check_impl(tcx
, item
, impl_
.self_ty
, &impl_
.of_trait
, impl_
.constness
);
192 (ty
::ImplPolarity
::Negative
, ast
::ImplPolarity
::Negative(span
)) => {
193 // FIXME(#27579): what amount of WF checking do we need for neg impls?
194 if let hir
::Defaultness
::Default { .. }
= impl_
.defaultness
{
195 let mut spans
= vec
![span
];
196 spans
.extend(impl_
.defaultness_span
);
201 "negative impls cannot be default impls"
206 (ty
::ImplPolarity
::Reservation
, _
) => {
207 // FIXME: what amount of WF checking do we need for reservation impls?
212 hir
::ItemKind
::Fn(ref sig
, ..) => {
213 check_item_fn(tcx
, def_id
, item
.ident
, item
.span
, sig
.decl
);
215 hir
::ItemKind
::Static(ty
, ..) => {
216 check_item_type(tcx
, def_id
, ty
.span
, false);
218 hir
::ItemKind
::Const(ty
, ..) => {
219 check_item_type(tcx
, def_id
, ty
.span
, false);
221 hir
::ItemKind
::Struct(ref struct_def
, ref ast_generics
) => {
222 check_type_defn(tcx
, item
, false, |wfcx
| vec
![wfcx
.non_enum_variant(struct_def
)]);
224 check_variances_for_type_defn(tcx
, item
, ast_generics
);
226 hir
::ItemKind
::Union(ref struct_def
, ref ast_generics
) => {
227 check_type_defn(tcx
, item
, true, |wfcx
| vec
![wfcx
.non_enum_variant(struct_def
)]);
229 check_variances_for_type_defn(tcx
, item
, ast_generics
);
231 hir
::ItemKind
::Enum(ref enum_def
, ref ast_generics
) => {
232 check_type_defn(tcx
, item
, true, |wfcx
| wfcx
.enum_variants(enum_def
));
234 check_variances_for_type_defn(tcx
, item
, ast_generics
);
236 hir
::ItemKind
::Trait(..) => {
237 check_trait(tcx
, item
);
239 hir
::ItemKind
::TraitAlias(..) => {
240 check_trait(tcx
, item
);
242 // `ForeignItem`s are handled separately.
243 hir
::ItemKind
::ForeignMod { .. }
=> {}
248 fn check_foreign_item(tcx
: TyCtxt
<'_
>, item
: &hir
::ForeignItem
<'_
>) {
249 let def_id
= item
.owner_id
.def_id
;
253 item
.name
= ? tcx
.def_path_str(def_id
.to_def_id())
257 hir
::ForeignItemKind
::Fn(decl
, ..) => {
258 check_item_fn(tcx
, def_id
, item
.ident
, item
.span
, decl
)
260 hir
::ForeignItemKind
::Static(ty
, ..) => check_item_type(tcx
, def_id
, ty
.span
, true),
261 hir
::ForeignItemKind
::Type
=> (),
265 fn check_trait_item(tcx
: TyCtxt
<'_
>, trait_item
: &hir
::TraitItem
<'_
>) {
266 let def_id
= trait_item
.owner_id
.def_id
;
268 let (method_sig
, span
) = match trait_item
.kind
{
269 hir
::TraitItemKind
::Fn(ref sig
, _
) => (Some(sig
), trait_item
.span
),
270 hir
::TraitItemKind
::Type(_bounds
, Some(ty
)) => (None
, ty
.span
),
271 _
=> (None
, trait_item
.span
),
273 check_object_unsafe_self_trait_by_name(tcx
, trait_item
);
274 check_associated_item(tcx
, def_id
, span
, method_sig
);
276 let encl_trait_def_id
= tcx
.local_parent(def_id
);
277 let encl_trait
= tcx
.hir().expect_item(encl_trait_def_id
);
278 let encl_trait_def_id
= encl_trait
.owner_id
.to_def_id();
279 let fn_lang_item_name
= if Some(encl_trait_def_id
) == tcx
.lang_items().fn_trait() {
281 } else if Some(encl_trait_def_id
) == tcx
.lang_items().fn_mut_trait() {
287 if let (Some(fn_lang_item_name
), "call") =
288 (fn_lang_item_name
, trait_item
.ident
.name
.to_ident_string().as_str())
290 // We are looking at the `call` function of the `fn` or `fn_mut` lang item.
291 // Do some rudimentary sanity checking to avoid an ICE later (issue #83471).
292 if let Some(hir
::FnSig { decl, span, .. }
) = method_sig
{
293 if let [self_ty
, _
] = decl
.inputs
{
294 if !matches
!(self_ty
.kind
, hir
::TyKind
::Rptr(_
, _
)) {
299 "first argument of `call` in `{fn_lang_item_name}` lang item must be a reference",
309 "`call` function in `{fn_lang_item_name}` lang item takes exactly two arguments",
319 "`call` trait item in `{fn_lang_item_name}` lang item must be a function",
327 /// Require that the user writes where clauses on GATs for the implicit
328 /// outlives bounds involving trait parameters in trait functions and
329 /// lifetimes passed as GAT substs. See `self-outlives-lint` test.
331 /// We use the following trait as an example throughout this function:
332 /// ```rust,ignore (this code fails due to this lint)
334 /// type Iter<'a>: Iterator<Item = Self::Item<'a>>;
336 /// fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
339 fn check_gat_where_clauses(tcx
: TyCtxt
<'_
>, associated_items
: &[hir
::TraitItemRef
]) {
340 // Associates every GAT's def_id to a list of possibly missing bounds detected by this lint.
341 let mut required_bounds_by_item
= FxHashMap
::default();
343 // Loop over all GATs together, because if this lint suggests adding a where-clause bound
344 // to one GAT, it might then require us to an additional bound on another GAT.
345 // In our `IntoIter` example, we discover a missing `Self: 'a` bound on `Iter<'a>`, which
346 // then in a second loop adds a `Self: 'a` bound to `Item` due to the relationship between
349 let mut should_continue
= false;
350 for gat_item
in associated_items
{
351 let gat_def_id
= gat_item
.id
.owner_id
;
352 let gat_item
= tcx
.associated_item(gat_def_id
);
353 // If this item is not an assoc ty, or has no substs, then it's not a GAT
354 if gat_item
.kind
!= ty
::AssocKind
::Type
{
357 let gat_generics
= tcx
.generics_of(gat_def_id
);
358 // FIXME(jackh726): we can also warn in the more general case
359 if gat_generics
.params
.is_empty() {
363 // Gather the bounds with which all other items inside of this trait constrain the GAT.
364 // This is calculated by taking the intersection of the bounds that each item
365 // constrains the GAT with individually.
366 let mut new_required_bounds
: Option
<FxHashSet
<ty
::Predicate
<'_
>>> = None
;
367 for item
in associated_items
{
368 let item_def_id
= item
.id
.owner_id
;
369 // Skip our own GAT, since it does not constrain itself at all.
370 if item_def_id
== gat_def_id
{
374 let item_hir_id
= item
.id
.hir_id();
375 let param_env
= tcx
.param_env(item_def_id
);
377 let item_required_bounds
= match item
.kind
{
378 // In our example, this corresponds to `into_iter` method
379 hir
::AssocItemKind
::Fn { .. }
=> {
380 // For methods, we check the function signature's return type for any GATs
381 // to constrain. In the `into_iter` case, we see that the return type
382 // `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
383 let sig
: ty
::FnSig
<'_
> = tcx
.liberate_late_bound_regions(
384 item_def_id
.to_def_id(),
385 tcx
.fn_sig(item_def_id
),
391 sig
.inputs_and_output
,
392 // We also assume that all of the function signature's parameter types
394 &sig
.inputs().iter().copied().collect(),
399 // In our example, this corresponds to the `Iter` and `Item` associated types
400 hir
::AssocItemKind
::Type
=> {
401 // If our associated item is a GAT with missing bounds, add them to
402 // the param-env here. This allows this GAT to propagate missing bounds
404 let param_env
= augment_param_env(
407 required_bounds_by_item
.get(&item_def_id
),
413 tcx
.explicit_item_bounds(item_def_id
)
416 .collect
::<Vec
<_
>>(),
417 &FxHashSet
::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
::RegionOutlives(ty
::OutlivesPredicate(a
, b
)) => {
467 !region_known_to_outlive(tcx
, gat_hir
, param_env
, &FxHashSet
::default(), a
, b
)
469 ty
::PredicateKind
::TypeOutlives(ty
::OutlivesPredicate(a
, b
)) => {
470 !ty_known_to_outlive(tcx
, gat_hir
, param_env
, &FxHashSet
::default(), a
, b
)
472 _
=> bug
!("Unexpected PredicateKind"),
474 .map(|clause
| clause
.to_string())
477 // We sort so that order is predictable
478 unsatisfied_bounds
.sort();
480 if !unsatisfied_bounds
.is_empty() {
481 let plural
= pluralize
!(unsatisfied_bounds
.len());
482 let mut err
= tcx
.sess
.struct_span_err(
484 &format
!("missing required bound{} on `{}`", plural
, gat_item_hir
.ident
),
487 let suggestion
= format
!(
489 gat_item_hir
.generics
.add_where_or_trailing_comma(),
490 unsatisfied_bounds
.join(", "),
493 gat_item_hir
.generics
.tail_span_for_predicate_suggestion(),
494 &format
!("add the required where clause{plural}"),
496 Applicability
::MachineApplicable
,
500 if unsatisfied_bounds
.len() > 1 { "these bounds are" }
else { "this bound is" }
;
502 "{} currently required to ensure that impls have maximum flexibility",
506 "we are soliciting feedback, see issue #87479 \
507 <https://github.com/rust-lang/rust/issues/87479> \
508 for more information",
516 /// Add a new set of predicates to the caller_bounds of an existing param_env.
517 fn augment_param_env
<'tcx
>(
519 param_env
: ty
::ParamEnv
<'tcx
>,
520 new_predicates
: Option
<&FxHashSet
<ty
::Predicate
<'tcx
>>>,
521 ) -> ty
::ParamEnv
<'tcx
> {
522 let Some(new_predicates
) = new_predicates
else {
526 if new_predicates
.is_empty() {
531 tcx
.mk_predicates(param_env
.caller_bounds().iter().chain(new_predicates
.iter().cloned()));
532 // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
533 // i.e. traits::normalize_param_env_or_error
534 ty
::ParamEnv
::new(bounds
, param_env
.reveal(), param_env
.constness())
537 /// We use the following trait as an example throughout this function.
538 /// Specifically, let's assume that `to_check` here is the return type
539 /// of `into_iter`, and the GAT we are checking this for is `Iter`.
540 /// ```rust,ignore (this code fails due to this lint)
542 /// type Iter<'a>: Iterator<Item = Self::Item<'a>>;
544 /// fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
547 fn gather_gat_bounds
<'tcx
, T
: TypeFoldable
<'tcx
>>(
549 param_env
: ty
::ParamEnv
<'tcx
>,
550 item_hir
: hir
::HirId
,
552 wf_tys
: &FxHashSet
<Ty
<'tcx
>>,
553 gat_def_id
: LocalDefId
,
554 gat_generics
: &'tcx ty
::Generics
,
555 ) -> Option
<FxHashSet
<ty
::Predicate
<'tcx
>>> {
556 // The bounds we that we would require from `to_check`
557 let mut bounds
= FxHashSet
::default();
559 let (regions
, types
) = GATSubstCollector
::visit(gat_def_id
.to_def_id(), to_check
);
561 // If both regions and types are empty, then this GAT isn't in the
562 // set of types we are checking, and we shouldn't try to do clause analysis
563 // (particularly, doing so would end up with an empty set of clauses,
564 // since the current method would require none, and we take the
565 // intersection of requirements of all methods)
566 if types
.is_empty() && regions
.is_empty() {
570 for (region_a
, region_a_idx
) in ®ions
{
571 // Ignore `'static` lifetimes for the purpose of this lint: it's
572 // because we know it outlives everything and so doesn't give meaningful
574 if let ty
::ReStatic
= **region_a
{
577 // For each region argument (e.g., `'a` in our example), check for a
578 // relationship to the type arguments (e.g., `Self`). If there is an
579 // outlives relationship (`Self: 'a`), then we want to ensure that is
580 // reflected in a where clause on the GAT itself.
581 for (ty
, ty_idx
) in &types
{
582 // In our example, requires that `Self: 'a`
583 if ty_known_to_outlive(tcx
, item_hir
, param_env
, &wf_tys
, *ty
, *region_a
) {
584 debug
!(?ty_idx
, ?region_a_idx
);
585 debug
!("required clause: {ty} must outlive {region_a}");
586 // Translate into the generic parameters of the GAT. In
587 // our example, the type was `Self`, which will also be
588 // `Self` in the GAT.
589 let ty_param
= gat_generics
.param_at(*ty_idx
, tcx
);
591 .mk_ty(ty
::Param(ty
::ParamTy { index: ty_param.index, name: ty_param.name }
));
592 // Same for the region. In our example, 'a corresponds
593 // to the 'me parameter.
594 let region_param
= gat_generics
.param_at(*region_a_idx
, tcx
);
596 tcx
.mk_region(ty
::RegionKind
::ReEarlyBound(ty
::EarlyBoundRegion
{
597 def_id
: region_param
.def_id
,
598 index
: region_param
.index
,
599 name
: region_param
.name
,
601 // The predicate we expect to see. (In our example,
604 ty
::PredicateKind
::TypeOutlives(ty
::OutlivesPredicate(ty_param
, region_param
));
605 let clause
= tcx
.mk_predicate(ty
::Binder
::dummy(clause
));
606 bounds
.insert(clause
);
610 // For each region argument (e.g., `'a` in our example), also check for a
611 // relationship to the other region arguments. If there is an outlives
612 // relationship, then we want to ensure that is reflected in the where clause
613 // on the GAT itself.
614 for (region_b
, region_b_idx
) in ®ions
{
615 // Again, skip `'static` because it outlives everything. Also, we trivially
616 // know that a region outlives itself.
617 if ty
::ReStatic
== **region_b
|| region_a
== region_b
{
620 if region_known_to_outlive(tcx
, item_hir
, param_env
, &wf_tys
, *region_a
, *region_b
) {
621 debug
!(?region_a_idx
, ?region_b_idx
);
622 debug
!("required clause: {region_a} must outlive {region_b}");
623 // Translate into the generic parameters of the GAT.
624 let region_a_param
= gat_generics
.param_at(*region_a_idx
, tcx
);
626 tcx
.mk_region(ty
::RegionKind
::ReEarlyBound(ty
::EarlyBoundRegion
{
627 def_id
: region_a_param
.def_id
,
628 index
: region_a_param
.index
,
629 name
: region_a_param
.name
,
631 // Same for the region.
632 let region_b_param
= gat_generics
.param_at(*region_b_idx
, tcx
);
634 tcx
.mk_region(ty
::RegionKind
::ReEarlyBound(ty
::EarlyBoundRegion
{
635 def_id
: region_b_param
.def_id
,
636 index
: region_b_param
.index
,
637 name
: region_b_param
.name
,
639 // The predicate we expect to see.
640 let clause
= ty
::PredicateKind
::RegionOutlives(ty
::OutlivesPredicate(
644 let clause
= tcx
.mk_predicate(ty
::Binder
::dummy(clause
));
645 bounds
.insert(clause
);
653 /// Given a known `param_env` and a set of well formed types, can we prove that
654 /// `ty` outlives `region`.
655 fn ty_known_to_outlive
<'tcx
>(
658 param_env
: ty
::ParamEnv
<'tcx
>,
659 wf_tys
: &FxHashSet
<Ty
<'tcx
>>,
661 region
: ty
::Region
<'tcx
>,
663 resolve_regions_with_wf_tys(tcx
, id
, param_env
, &wf_tys
, |infcx
, region_bound_pairs
| {
664 let origin
= infer
::RelateParamBound(DUMMY_SP
, ty
, None
);
665 let outlives
= &mut TypeOutlives
::new(infcx
, tcx
, region_bound_pairs
, None
, param_env
);
666 outlives
.type_must_outlive(origin
, ty
, region
, ConstraintCategory
::BoringNoLocation
);
670 /// Given a known `param_env` and a set of well formed types, can we prove that
671 /// `region_a` outlives `region_b`
672 fn region_known_to_outlive
<'tcx
>(
675 param_env
: ty
::ParamEnv
<'tcx
>,
676 wf_tys
: &FxHashSet
<Ty
<'tcx
>>,
677 region_a
: ty
::Region
<'tcx
>,
678 region_b
: ty
::Region
<'tcx
>,
680 resolve_regions_with_wf_tys(tcx
, id
, param_env
, &wf_tys
, |mut infcx
, _
| {
681 use rustc_infer
::infer
::outlives
::obligations
::TypeOutlivesDelegate
;
682 let origin
= infer
::RelateRegionParamBound(DUMMY_SP
);
683 // `region_a: region_b` -> `region_b <= region_a`
684 infcx
.push_sub_region_constraint(
688 ConstraintCategory
::BoringNoLocation
,
693 /// Given a known `param_env` and a set of well formed types, set up an
694 /// `InferCtxt`, call the passed function (to e.g. set up region constraints
695 /// to be tested), then resolve region and return errors
696 fn resolve_regions_with_wf_tys
<'tcx
>(
699 param_env
: ty
::ParamEnv
<'tcx
>,
700 wf_tys
: &FxHashSet
<Ty
<'tcx
>>,
701 add_constraints
: impl for<'a
> FnOnce(&'a InferCtxt
<'tcx
>, &'a RegionBoundPairs
<'tcx
>),
703 // Unfortunately, we have to use a new `InferCtxt` each call, because
704 // region constraints get added and solved there and we need to test each
705 // call individually.
706 let infcx
= tcx
.infer_ctxt().build();
707 let outlives_environment
= OutlivesEnvironment
::with_bounds(
710 infcx
.implied_bounds_tys(param_env
, id
, wf_tys
.clone()),
712 let region_bound_pairs
= outlives_environment
.region_bound_pairs();
714 add_constraints(&infcx
, region_bound_pairs
);
716 infcx
.process_registered_region_obligations(
717 outlives_environment
.region_bound_pairs(),
720 let errors
= infcx
.resolve_regions(&outlives_environment
);
722 debug
!(?errors
, "errors");
724 // If we were able to prove that the type outlives the region without
725 // an error, it must be because of the implied or explicit bounds...
729 /// TypeVisitor that looks for uses of GATs like
730 /// `<P0 as Trait<P1..Pn>>::GAT<Pn..Pm>` and adds the arguments `P0..Pm` into
731 /// the two vectors, `regions` and `types` (depending on their kind). For each
732 /// parameter `Pi` also track the index `i`.
733 struct GATSubstCollector
<'tcx
> {
735 // Which region appears and which parameter index its substituted for
736 regions
: FxHashSet
<(ty
::Region
<'tcx
>, usize)>,
737 // Which params appears and which parameter index its substituted for
738 types
: FxHashSet
<(Ty
<'tcx
>, usize)>,
741 impl<'tcx
> GATSubstCollector
<'tcx
> {
742 fn visit
<T
: TypeFoldable
<'tcx
>>(
745 ) -> (FxHashSet
<(ty
::Region
<'tcx
>, usize)>, FxHashSet
<(Ty
<'tcx
>, usize)>) {
747 GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() }
;
748 t
.visit_with(&mut visitor
);
749 (visitor
.regions
, visitor
.types
)
753 impl<'tcx
> TypeVisitor
<'tcx
> for GATSubstCollector
<'tcx
> {
756 fn visit_ty(&mut self, t
: Ty
<'tcx
>) -> ControlFlow
<Self::BreakTy
> {
758 ty
::Projection(p
) if p
.item_def_id
== self.gat
=> {
759 for (idx
, subst
) in p
.substs
.iter().enumerate() {
760 match subst
.unpack() {
761 GenericArgKind
::Lifetime(lt
) if !lt
.is_late_bound() => {
762 self.regions
.insert((lt
, idx
));
764 GenericArgKind
::Type(t
) => {
765 self.types
.insert((t
, idx
));
773 t
.super_visit_with(self)
777 fn could_be_self(trait_def_id
: LocalDefId
, ty
: &hir
::Ty
<'_
>) -> bool
{
779 hir
::TyKind
::TraitObject([trait_ref
], ..) => match trait_ref
.trait_ref
.path
.segments
{
780 [s
] => s
.res
.opt_def_id() == Some(trait_def_id
.to_def_id()),
787 /// Detect when an object unsafe trait is referring to itself in one of its associated items.
788 /// When this is done, suggest using `Self` instead.
789 fn check_object_unsafe_self_trait_by_name(tcx
: TyCtxt
<'_
>, item
: &hir
::TraitItem
<'_
>) {
790 let (trait_name
, trait_def_id
) =
791 match tcx
.hir().get_by_def_id(tcx
.hir().get_parent_item(item
.hir_id()).def_id
) {
792 hir
::Node
::Item(item
) => match item
.kind
{
793 hir
::ItemKind
::Trait(..) => (item
.ident
, item
.owner_id
),
798 let mut trait_should_be_self
= vec
![];
800 hir
::TraitItemKind
::Const(ty
, _
) | hir
::TraitItemKind
::Type(_
, Some(ty
))
801 if could_be_self(trait_def_id
.def_id
, ty
) =>
803 trait_should_be_self
.push(ty
.span
)
805 hir
::TraitItemKind
::Fn(sig
, _
) => {
806 for ty
in sig
.decl
.inputs
{
807 if could_be_self(trait_def_id
.def_id
, ty
) {
808 trait_should_be_self
.push(ty
.span
);
811 match sig
.decl
.output
{
812 hir
::FnRetTy
::Return(ty
) if could_be_self(trait_def_id
.def_id
, ty
) => {
813 trait_should_be_self
.push(ty
.span
);
820 if !trait_should_be_self
.is_empty() {
821 if tcx
.object_safety_violations(trait_def_id
).is_empty() {
824 let sugg
= trait_should_be_self
.iter().map(|span
| (*span
, "Self".to_string())).collect();
827 trait_should_be_self
,
828 "associated item referring to unboxed trait object for its own trait",
830 .span_label(trait_name
.span
, "in this trait")
831 .multipart_suggestion(
832 "you might have meant to use `Self` to refer to the implementing type",
834 Applicability
::MachineApplicable
,
840 fn check_impl_item(tcx
: TyCtxt
<'_
>, impl_item
: &hir
::ImplItem
<'_
>) {
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
::Type(ty
) if ty
.span
!= DUMMY_SP
=> (None
, ty
.span
),
845 _
=> (None
, impl_item
.span
),
848 check_associated_item(tcx
, impl_item
.owner_id
.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 let _
= tcx
.representability(item
.owner_id
.def_id
);
1050 enter_wf_checking_ctxt(tcx
, item
.span
, item
.owner_id
.def_id
, |wfcx
| {
1051 let variants
= lookup_fields(wfcx
);
1052 let packed
= tcx
.adt_def(item
.owner_id
).repr().packed();
1054 for variant
in &variants
{
1055 // All field types must be well-formed.
1056 for field
in &variant
.fields
{
1057 wfcx
.register_wf_obligation(
1059 Some(WellFormedLoc
::Ty(field
.def_id
)),
1064 // For DST, or when drop needs to copy things around, all
1065 // intermediate types must be sized.
1066 let needs_drop_copy
= || {
1068 let ty
= variant
.fields
.last().unwrap().ty
;
1069 let ty
= tcx
.erase_regions(ty
);
1070 if ty
.needs_infer() {
1072 .delay_span_bug(item
.span
, &format
!("inference variables in {:?}", ty
));
1073 // Just treat unresolved type expression as if it needs drop.
1076 ty
.needs_drop(tcx
, tcx
.param_env(item
.owner_id
))
1080 // All fields (except for possibly the last) should be sized.
1081 let all_sized
= all_sized
|| variant
.fields
.is_empty() || needs_drop_copy();
1082 let unsized_len
= if all_sized { 0 }
else { 1 }
;
1084 variant
.fields
[..variant
.fields
.len() - unsized_len
].iter().enumerate()
1086 let last
= idx
== variant
.fields
.len() - 1;
1087 wfcx
.register_bound(
1088 traits
::ObligationCause
::new(
1091 traits
::FieldSized
{
1092 adt_kind
: match item_adt_kind(&item
.kind
) {
1102 tcx
.require_lang_item(LangItem
::Sized
, None
),
1106 // Explicit `enum` discriminant values must const-evaluate successfully.
1107 if let Some(discr_def_id
) = variant
.explicit_discr
{
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(
1117 ty
::Const
::from_anon_const(tcx
, discr_def_id
),
1124 check_where_clauses(wfcx
, item
.span
, item
.owner_id
.def_id
);
1128 #[instrument(skip(tcx, item))]
1129 fn check_trait(tcx
: TyCtxt
<'_
>, item
: &hir
::Item
<'_
>) {
1130 debug
!(?item
.owner_id
);
1132 let def_id
= item
.owner_id
.def_id
;
1133 let trait_def
= tcx
.trait_def(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(def_id
) {
1140 tcx
.def_span(*associated_def_id
),
1142 "marker traits cannot have associated items",
1148 enter_wf_checking_ctxt(tcx
, item
.span
, def_id
, |wfcx
| {
1149 check_where_clauses(wfcx
, item
.span
, 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
.owner_id
.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
.owner_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
.owner_id
);
1272 let self_ty
= wfcx
.normalize(
1274 Some(WellFormedLoc
::Ty(item
.hir_id().expect_owner().def_id
)),
1277 wfcx
.register_wf_obligation(
1279 Some(WellFormedLoc
::Ty(item
.hir_id().expect_owner().def_id
)),
1285 check_where_clauses(wfcx
, item
.span
, item
.owner_id
.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_non_region_param() || param_count
.params
.len() > 1 || has_region
1433 } else if predicates
.0.predicates
.iter().any(|&(p
, _
)| p
== substituted_pred
) {
1434 // Avoid duplication of predicates that contain no parameters, for example.
1437 Some((substituted_pred
, sp
))
1441 // Convert each of those into an obligation. So if you have
1442 // something like `struct Foo<T: Copy = String>`, we would
1443 // take that predicate `T: Copy`, substitute to `String: Copy`
1444 // (actually that happens in the previous `flat_map` call),
1445 // and then try to prove it (in this case, we'll fail).
1447 // Note the subtle difference from how we handle `predicates`
1448 // below: there, we are not trying to prove those predicates
1449 // to be *true* but merely *well-formed*.
1450 let pred
= wfcx
.normalize(sp
, None
, pred
);
1451 let cause
= traits
::ObligationCause
::new(
1454 traits
::ItemObligation(def_id
.to_def_id()),
1456 traits
::Obligation
::new(cause
, wfcx
.param_env
, pred
)
1459 let predicates
= predicates
.0.instantiate_identity
(tcx
);
1461 let predicates
= wfcx
.normalize(span
, None
, predicates
);
1463 debug
!(?predicates
.predicates
);
1464 assert_eq
!(predicates
.predicates
.len(), predicates
.spans
.len());
1465 let wf_obligations
=
1466 iter
::zip(&predicates
.predicates
, &predicates
.spans
).flat_map(|(&p
, &sp
)| {
1467 traits
::wf
::predicate_obligations(
1469 wfcx
.param_env
.without_const(),
1476 let obligations
: Vec
<_
> = wf_obligations
.chain(default_obligations
).collect();
1477 wfcx
.register_obligations(obligations
);
1480 #[instrument(level = "debug", skip(wfcx, span, hir_decl))]
1481 fn check_fn_or_method
<'tcx
>(
1482 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1484 sig
: ty
::PolyFnSig
<'tcx
>,
1485 hir_decl
: &hir
::FnDecl
<'_
>,
1488 let tcx
= wfcx
.tcx();
1489 let sig
= tcx
.liberate_late_bound_regions(def_id
.to_def_id(), sig
);
1491 // Normalize the input and output types one at a time, using a different
1492 // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
1493 // on the entire `FnSig`, since this would use the same `WellFormedLoc`
1494 // for each type, preventing the HIR wf check from generating
1495 // a nice error message.
1496 let ty
::FnSig { mut inputs_and_output, c_variadic, unsafety, abi }
= sig
;
1497 inputs_and_output
= tcx
.mk_type_list(inputs_and_output
.iter().enumerate().map(|(i
, ty
)| {
1500 Some(WellFormedLoc
::Param
{
1502 // Note that the `param_idx` of the output type is
1503 // one greater than the index of the last input type.
1504 param_idx
: i
.try_into().unwrap(),
1509 // Manually call `normalize_associated_types_in` on the other types
1510 // in `FnSig`. This ensures that if the types of these fields
1511 // ever change to include projections, we will start normalizing
1512 // them automatically.
1513 let sig
= ty
::FnSig
{
1515 c_variadic
: wfcx
.normalize(span
, None
, c_variadic
),
1516 unsafety
: wfcx
.normalize(span
, None
, unsafety
),
1517 abi
: wfcx
.normalize(span
, None
, abi
),
1520 for (i
, (&input_ty
, ty
)) in iter
::zip(sig
.inputs(), hir_decl
.inputs
).enumerate() {
1521 wfcx
.register_wf_obligation(
1523 Some(WellFormedLoc
::Param { function: def_id, param_idx: i.try_into().unwrap() }
),
1528 wfcx
.register_wf_obligation(
1529 hir_decl
.output
.span(),
1530 Some(WellFormedLoc
::Param
{
1532 param_idx
: sig
.inputs().len().try_into().unwrap(),
1534 sig
.output().into(),
1537 check_where_clauses(wfcx
, span
, def_id
);
1539 check_return_position_impl_trait_in_trait_bounds(
1544 hir_decl
.output
.span(),
1548 /// Basically `check_associated_type_bounds`, but separated for now and should be
1549 /// deduplicated when RPITITs get lowered into real associated items.
1550 fn check_return_position_impl_trait_in_trait_bounds
<'tcx
>(
1552 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1553 fn_def_id
: LocalDefId
,
1554 fn_output
: Ty
<'tcx
>,
1557 if let Some(assoc_item
) = tcx
.opt_associated_item(fn_def_id
.to_def_id())
1558 && assoc_item
.container
== ty
::AssocItemContainer
::TraitContainer
1560 for arg
in fn_output
.walk() {
1561 if let ty
::GenericArgKind
::Type(ty
) = arg
.unpack()
1562 && let ty
::Projection(proj
) = ty
.kind()
1563 && tcx
.def_kind(proj
.item_def_id
) == DefKind
::ImplTraitPlaceholder
1564 && tcx
.impl_trait_in_trait_parent(proj
.item_def_id
) == fn_def_id
.to_def_id()
1566 let bounds
= wfcx
.tcx().explicit_item_bounds(proj
.item_def_id
);
1567 let wf_obligations
= bounds
.iter().flat_map(|&(bound
, bound_span
)| {
1568 let normalized_bound
= wfcx
.normalize(span
, None
, bound
);
1569 traits
::wf
::predicate_obligations(
1577 wfcx
.register_obligations(wf_obligations
);
1583 const HELP_FOR_SELF_TYPE
: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
1584 `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
1585 of the previous types except `Self`)";
1587 #[instrument(level = "debug", skip(wfcx))]
1588 fn check_method_receiver
<'tcx
>(
1589 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1590 fn_sig
: &hir
::FnSig
<'_
>,
1591 method
: &ty
::AssocItem
,
1594 let tcx
= wfcx
.tcx();
1596 if !method
.fn_has_self_parameter
{
1600 let span
= fn_sig
.decl
.inputs
[0].span
;
1602 let sig
= tcx
.fn_sig(method
.def_id
);
1603 let sig
= tcx
.liberate_late_bound_regions(method
.def_id
, sig
);
1604 let sig
= wfcx
.normalize(span
, None
, sig
);
1606 debug
!("check_method_receiver: sig={:?}", sig
);
1608 let self_ty
= wfcx
.normalize(span
, None
, self_ty
);
1610 let receiver_ty
= sig
.inputs()[0];
1611 let receiver_ty
= wfcx
.normalize(span
, None
, receiver_ty
);
1613 if tcx
.features().arbitrary_self_types
{
1614 if !receiver_is_valid(wfcx
, span
, receiver_ty
, self_ty
, true) {
1615 // Report error; `arbitrary_self_types` was enabled.
1616 e0307(tcx
, span
, receiver_ty
);
1619 if !receiver_is_valid(wfcx
, span
, receiver_ty
, self_ty
, false) {
1620 if receiver_is_valid(wfcx
, span
, receiver_ty
, self_ty
, true) {
1621 // Report error; would have worked with `arbitrary_self_types`.
1623 &tcx
.sess
.parse_sess
,
1624 sym
::arbitrary_self_types
,
1627 "`{receiver_ty}` cannot be used as the type of `self` without \
1628 the `arbitrary_self_types` feature",
1631 .help(HELP_FOR_SELF_TYPE
)
1634 // Report error; would not have worked with `arbitrary_self_types`.
1635 e0307(tcx
, span
, receiver_ty
);
1641 fn e0307
<'tcx
>(tcx
: TyCtxt
<'tcx
>, span
: Span
, receiver_ty
: Ty
<'_
>) {
1643 tcx
.sess
.diagnostic(),
1646 "invalid `self` parameter type: {receiver_ty}"
1648 .note("type of `self` must be `Self` or a type that dereferences to it")
1649 .help(HELP_FOR_SELF_TYPE
)
1653 /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
1654 /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
1655 /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
1656 /// strict: `receiver_ty` must implement `Receiver` and directly implement
1657 /// `Deref<Target = self_ty>`.
1659 /// N.B., there are cases this function returns `true` but causes an error to be emitted,
1660 /// particularly when `receiver_ty` derefs to a type that is the same as `self_ty` but has the
1661 /// wrong lifetime. Be careful of this if you are calling this function speculatively.
1662 fn receiver_is_valid
<'tcx
>(
1663 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1665 receiver_ty
: Ty
<'tcx
>,
1667 arbitrary_self_types_enabled
: bool
,
1669 let infcx
= wfcx
.infcx
;
1670 let tcx
= wfcx
.tcx();
1672 ObligationCause
::new(span
, wfcx
.body_id
, traits
::ObligationCauseCode
::MethodReceiver
);
1674 let can_eq_self
= |ty
| infcx
.can_eq(wfcx
.param_env
, self_ty
, ty
).is_ok();
1676 // `self: Self` is always valid.
1677 if can_eq_self(receiver_ty
) {
1678 if let Err(err
) = wfcx
.equate_types(&cause
, wfcx
.param_env
, self_ty
, receiver_ty
) {
1679 infcx
.err_ctxt().report_mismatched_types(&cause
, self_ty
, receiver_ty
, err
).emit();
1685 Autoderef
::new(infcx
, wfcx
.param_env
, wfcx
.body_id
, span
, receiver_ty
, span
);
1687 // The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`.
1688 if arbitrary_self_types_enabled
{
1689 autoderef
= autoderef
.include_raw_pointers();
1692 // The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
1695 let receiver_trait_def_id
= tcx
.require_lang_item(LangItem
::Receiver
, None
);
1697 // Keep dereferencing `receiver_ty` until we get to `self_ty`.
1699 if let Some((potential_self_ty
, _
)) = autoderef
.next() {
1701 "receiver_is_valid: potential self type `{:?}` to match `{:?}`",
1702 potential_self_ty
, self_ty
1705 if can_eq_self(potential_self_ty
) {
1706 wfcx
.register_obligations(autoderef
.into_obligations());
1709 wfcx
.equate_types(&cause
, wfcx
.param_env
, self_ty
, potential_self_ty
)
1713 .report_mismatched_types(&cause
, self_ty
, potential_self_ty
, err
)
1719 // Without `feature(arbitrary_self_types)`, we require that each step in the
1720 // deref chain implement `receiver`
1721 if !arbitrary_self_types_enabled
1722 && !receiver_is_implemented(
1724 receiver_trait_def_id
,
1733 debug
!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty
, self_ty
);
1734 // If the receiver already has errors reported due to it, consider it valid to avoid
1735 // unnecessary errors (#58712).
1736 return receiver_ty
.references_error();
1740 // Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`.
1741 if !arbitrary_self_types_enabled
1742 && !receiver_is_implemented(wfcx
, receiver_trait_def_id
, cause
.clone(), receiver_ty
)
1750 fn receiver_is_implemented
<'tcx
>(
1751 wfcx
: &WfCheckingCtxt
<'_
, 'tcx
>,
1752 receiver_trait_def_id
: DefId
,
1753 cause
: ObligationCause
<'tcx
>,
1754 receiver_ty
: Ty
<'tcx
>,
1756 let tcx
= wfcx
.tcx();
1757 let trait_ref
= ty
::Binder
::dummy(ty
::TraitRef
{
1758 def_id
: receiver_trait_def_id
,
1759 substs
: tcx
.mk_substs_trait(receiver_ty
, &[]),
1763 traits
::Obligation
::new(cause
, wfcx
.param_env
, trait_ref
.without_const().to_predicate(tcx
));
1765 if wfcx
.infcx
.predicate_must_hold_modulo_regions(&obligation
) {
1769 "receiver_is_implemented: type `{:?}` does not implement `Receiver` trait",
1776 fn check_variances_for_type_defn
<'tcx
>(
1778 item
: &hir
::Item
<'tcx
>,
1779 hir_generics
: &hir
::Generics
<'_
>,
1781 let ty
= tcx
.type_of(item
.owner_id
);
1782 if tcx
.has_error_field(ty
) {
1786 let ty_predicates
= tcx
.predicates_of(item
.owner_id
);
1787 assert_eq
!(ty_predicates
.parent
, None
);
1788 let variances
= tcx
.variances_of(item
.owner_id
);
1790 let mut constrained_parameters
: FxHashSet
<_
> = variances
1793 .filter(|&(_
, &variance
)| variance
!= ty
::Bivariant
)
1794 .map(|(index
, _
)| Parameter(index
as u32))
1797 identify_constrained_generic_params(tcx
, ty_predicates
, None
, &mut constrained_parameters
);
1799 // Lazily calculated because it is only needed in case of an error.
1800 let explicitly_bounded_params
= LazyCell
::new(|| {
1801 let icx
= crate::collect
::ItemCtxt
::new(tcx
, item
.owner_id
.to_def_id());
1805 .filter_map(|predicate
| match predicate
{
1806 hir
::WherePredicate
::BoundPredicate(predicate
) => {
1807 match icx
.to_ty(predicate
.bounded_ty
).kind() {
1808 ty
::Param(data
) => Some(Parameter(data
.index
)),
1814 .collect
::<FxHashSet
<_
>>()
1817 for (index
, _
) in variances
.iter().enumerate() {
1818 let parameter
= Parameter(index
as u32);
1820 if constrained_parameters
.contains(¶meter
) {
1824 let param
= &hir_generics
.params
[index
];
1827 hir
::ParamName
::Error
=> {}
1829 let has_explicit_bounds
= explicitly_bounded_params
.contains(¶meter
);
1830 report_bivariance(tcx
, param
, has_explicit_bounds
);
1836 fn report_bivariance(
1838 param
: &rustc_hir
::GenericParam
<'_
>,
1839 has_explicit_bounds
: bool
,
1840 ) -> ErrorGuaranteed
{
1841 let span
= param
.span
;
1842 let param_name
= param
.name
.ident().name
;
1843 let mut err
= error_392(tcx
, span
, param_name
);
1845 let suggested_marker_id
= tcx
.lang_items().phantom_data();
1846 // Help is available only in presence of lang items.
1847 let msg
= if let Some(def_id
) = suggested_marker_id
{
1849 "consider removing `{}`, referring to it in a field, or using a marker such as `{}`",
1851 tcx
.def_path_str(def_id
),
1854 format
!("consider removing `{param_name}` or referring to it in a field")
1858 if matches
!(param
.kind
, hir
::GenericParamKind
::Type { .. }
) && !has_explicit_bounds
{
1860 "if you intended `{0}` to be a const parameter, use `const {0}: usize` instead",
1867 impl<'tcx
> WfCheckingCtxt
<'_
, 'tcx
> {
1868 /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
1870 #[instrument(level = "debug", skip(self))]
1871 fn check_false_global_bounds(&mut self) {
1872 let tcx
= self.ocx
.infcx
.tcx
;
1873 let mut span
= self.span
;
1874 let empty_env
= ty
::ParamEnv
::empty();
1876 let def_id
= tcx
.hir().local_def_id(self.body_id
);
1877 let predicates_with_span
= tcx
.predicates_of(def_id
).predicates
.iter().copied();
1878 // Check elaborated bounds.
1879 let implied_obligations
= traits
::elaborate_predicates_with_span(tcx
, predicates_with_span
);
1881 for obligation
in implied_obligations
{
1882 // We lower empty bounds like `Vec<dyn Copy>:` as
1883 // `WellFormed(Vec<dyn Copy>)`, which will later get checked by
1884 // regular WF checking
1885 if let ty
::PredicateKind
::WellFormed(..) = obligation
.predicate
.kind().skip_binder() {
1888 let pred
= obligation
.predicate
;
1889 // Match the existing behavior.
1890 if pred
.is_global() && !pred
.has_late_bound_regions() {
1891 let pred
= self.normalize(span
, None
, pred
);
1892 let hir_node
= tcx
.hir().find(self.body_id
);
1894 // only use the span of the predicate clause (#90869)
1896 if let Some(hir
::Generics { predicates, .. }
) =
1897 hir_node
.and_then(|node
| node
.generics())
1899 let obligation_span
= obligation
.cause
.span();
1903 // There seems to be no better way to find out which predicate we are in
1904 .find(|pred
| pred
.span().contains(obligation_span
))
1905 .map(|pred
| pred
.span())
1906 .unwrap_or(obligation_span
);
1909 let obligation
= traits
::Obligation
::new(
1910 traits
::ObligationCause
::new(span
, self.body_id
, traits
::TrivialBound
),
1914 self.ocx
.register_obligation(obligation
);
1920 fn check_mod_type_wf(tcx
: TyCtxt
<'_
>, module
: LocalDefId
) {
1921 let items
= tcx
.hir_module_items(module
);
1922 items
.par_items(|item
| tcx
.ensure().check_well_formed(item
.owner_id
));
1923 items
.par_impl_items(|item
| tcx
.ensure().check_well_formed(item
.owner_id
));
1924 items
.par_trait_items(|item
| tcx
.ensure().check_well_formed(item
.owner_id
));
1925 items
.par_foreign_items(|item
| tcx
.ensure().check_well_formed(item
.owner_id
));
1928 ///////////////////////////////////////////////////////////////////////////
1931 // FIXME(eddyb) replace this with getting fields/discriminants through `ty::AdtDef`.
1932 struct AdtVariant
<'tcx
> {
1933 /// Types of fields in the variant, that must be well-formed.
1934 fields
: Vec
<AdtField
<'tcx
>>,
1936 /// Explicit discriminant of this variant (e.g. `A = 123`),
1937 /// that must evaluate to a constant value.
1938 explicit_discr
: Option
<LocalDefId
>,
1941 struct AdtField
<'tcx
> {
1947 impl<'a
, 'tcx
> WfCheckingCtxt
<'a
, 'tcx
> {
1948 // FIXME(eddyb) replace this with getting fields through `ty::AdtDef`.
1949 fn non_enum_variant(&self, struct_def
: &hir
::VariantData
<'_
>) -> AdtVariant
<'tcx
> {
1950 let fields
= struct_def
1954 let def_id
= self.tcx().hir().local_def_id(field
.hir_id
);
1955 let field_ty
= self.tcx().type_of(def_id
);
1956 let field_ty
= self.normalize(field
.ty
.span
, None
, field_ty
);
1957 debug
!("non_enum_variant: type of field {:?} is {:?}", field
, field_ty
);
1958 AdtField { ty: field_ty, span: field.ty.span, def_id }
1961 AdtVariant { fields, explicit_discr: None }
1964 fn enum_variants(&self, enum_def
: &hir
::EnumDef
<'_
>) -> Vec
<AdtVariant
<'tcx
>> {
1968 .map(|variant
| AdtVariant
{
1969 fields
: self.non_enum_variant(&variant
.data
).fields
,
1970 explicit_discr
: variant
1972 .map(|explicit_discr
| self.tcx().hir().local_def_id(explicit_discr
.hir_id
)),
1982 ) -> DiagnosticBuilder
<'_
, ErrorGuaranteed
> {
1983 let mut err
= struct_span_err
!(tcx
.sess
, span
, E0392
, "parameter `{param_name}` is never used");
1984 err
.span_label(span
, "unused parameter");
1988 pub fn provide(providers
: &mut Providers
) {
1989 *providers
= Providers { check_mod_type_wf, check_well_formed, ..*providers }
;