1 use crate::check
::{FnCtxt, Inherited}
;
2 use crate::constrained_generic_params
::{identify_constrained_generic_params, Parameter}
;
5 use rustc_data_structures
::fx
::{FxHashMap, FxHashSet}
;
6 use rustc_errors
::{struct_span_err, Applicability, DiagnosticBuilder}
;
8 use rustc_hir
::def_id
::{DefId, LocalDefId}
;
9 use rustc_hir
::itemlikevisit
::ParItemLikeVisitor
;
10 use rustc_hir
::lang_items
;
11 use rustc_hir
::ItemKind
;
12 use rustc_middle
::ty
::subst
::{GenericArgKind, InternalSubsts, Subst}
;
13 use rustc_middle
::ty
::trait_def
::TraitSpecializationKind
;
14 use rustc_middle
::ty
::{
15 self, AdtKind
, GenericParamDefKind
, ToPredicate
, Ty
, TyCtxt
, TypeFoldable
, WithConstness
,
17 use rustc_session
::parse
::feature_err
;
18 use rustc_span
::symbol
::{sym, Symbol}
;
20 use rustc_trait_selection
::opaque_types
::may_define_opaque_type
;
21 use rustc_trait_selection
::traits
::query
::evaluate_obligation
::InferCtxtExt
;
22 use rustc_trait_selection
::traits
::{self, ObligationCause, ObligationCauseCode}
;
24 /// Helper type of a temporary returned by `.for_item(...)`.
25 /// This is necessary because we can't write the following bound:
28 /// F: for<'b, 'tcx> where 'tcx FnOnce(FnCtxt<'b, 'tcx>)
30 struct CheckWfFcxBuilder
<'tcx
> {
31 inherited
: super::InheritedBuilder
<'tcx
>,
34 param_env
: ty
::ParamEnv
<'tcx
>,
37 impl<'tcx
> CheckWfFcxBuilder
<'tcx
> {
38 fn with_fcx
<F
>(&mut self, f
: F
)
40 F
: for<'b
> FnOnce(&FnCtxt
<'b
, 'tcx
>, TyCtxt
<'tcx
>) -> Vec
<Ty
<'tcx
>>,
44 let param_env
= self.param_env
;
45 self.inherited
.enter(|inh
| {
46 let fcx
= FnCtxt
::new(&inh
, param_env
, id
);
47 if !inh
.tcx
.features().trivial_bounds
{
48 // As predicates are cached rather than obligations, this
49 // needsto be called first so that they are checked with an
51 check_false_global_bounds(&fcx
, span
, id
);
53 let wf_tys
= f(&fcx
, fcx
.tcx
);
54 fcx
.select_all_obligations_or_error();
55 fcx
.regionck_item(id
, span
, &wf_tys
);
60 /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
61 /// well-formed, meaning that they do not require any constraints not declared in the struct
62 /// definition itself. For example, this definition would be illegal:
65 /// struct Ref<'a, T> { x: &'a T }
68 /// because the type did not declare that `T:'a`.
70 /// We do this check as a pre-pass before checking fn bodies because if these constraints are
71 /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
73 pub fn check_item_well_formed(tcx
: TyCtxt
<'_
>, def_id
: LocalDefId
) {
74 let hir_id
= tcx
.hir().as_local_hir_id(def_id
);
75 let item
= tcx
.hir().expect_item(hir_id
);
78 "check_item_well_formed(it.hir_id={:?}, it.name={})",
80 tcx
.def_path_str(def_id
.to_def_id())
84 // Right now we check that every default trait implementation
85 // has an implementation of itself. Basically, a case like:
87 // impl Trait for T {}
89 // has a requirement of `T: Trait` which was required for default
90 // method implementations. Although this could be improved now that
91 // there's a better infrastructure in place for this, it's being left
92 // for a follow-up work.
94 // Since there's such a requirement, we need to check *just* positive
95 // implementations, otherwise things like:
97 // impl !Send for T {}
99 // won't be allowed unless there's an *explicit* implementation of `Send`
101 hir
::ItemKind
::Impl
{
110 .impl_trait_ref(tcx
.hir().local_def_id(item
.hir_id
))
111 .map_or(false, |trait_ref
| tcx
.trait_is_auto(trait_ref
.def_id
));
112 if let (hir
::Defaultness
::Default { .. }
, true) = (defaultness
, is_auto
) {
113 let sp
= of_trait
.as_ref().map(|t
| t
.path
.span
).unwrap_or(item
.span
);
115 tcx
.sess
.struct_span_err(sp
, "impls of auto traits cannot be default");
116 err
.span_labels(defaultness_span
, "default because of this");
117 err
.span_label(sp
, "auto trait");
120 // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
121 match (tcx
.impl_polarity(def_id
), polarity
) {
122 (ty
::ImplPolarity
::Positive
, _
) => {
123 check_impl(tcx
, item
, self_ty
, of_trait
);
125 (ty
::ImplPolarity
::Negative
, ast
::ImplPolarity
::Negative(span
)) => {
126 // FIXME(#27579): what amount of WF checking do we need for neg impls?
127 if let hir
::Defaultness
::Default { .. }
= defaultness
{
128 let mut spans
= vec
![span
];
129 spans
.extend(defaultness_span
);
134 "negative impls cannot be default impls"
139 (ty
::ImplPolarity
::Reservation
, _
) => {
140 // FIXME: what amount of WF checking do we need for reservation impls?
145 hir
::ItemKind
::Fn(..) => {
146 check_item_fn(tcx
, item
);
148 hir
::ItemKind
::Static(ref ty
, ..) => {
149 check_item_type(tcx
, item
.hir_id
, ty
.span
, false);
151 hir
::ItemKind
::Const(ref ty
, ..) => {
152 check_item_type(tcx
, item
.hir_id
, ty
.span
, false);
154 hir
::ItemKind
::ForeignMod(ref module
) => {
155 for it
in module
.items
.iter() {
156 if let hir
::ForeignItemKind
::Static(ref ty
, ..) = it
.kind
{
157 check_item_type(tcx
, it
.hir_id
, ty
.span
, true);
161 hir
::ItemKind
::Struct(ref struct_def
, ref ast_generics
) => {
162 check_type_defn(tcx
, item
, false, |fcx
| vec
![fcx
.non_enum_variant(struct_def
)]);
164 check_variances_for_type_defn(tcx
, item
, ast_generics
);
166 hir
::ItemKind
::Union(ref struct_def
, ref ast_generics
) => {
167 check_type_defn(tcx
, item
, true, |fcx
| vec
![fcx
.non_enum_variant(struct_def
)]);
169 check_variances_for_type_defn(tcx
, item
, ast_generics
);
171 hir
::ItemKind
::Enum(ref enum_def
, ref ast_generics
) => {
172 check_type_defn(tcx
, item
, true, |fcx
| fcx
.enum_variants(enum_def
));
174 check_variances_for_type_defn(tcx
, item
, ast_generics
);
176 hir
::ItemKind
::Trait(..) => {
177 check_trait(tcx
, item
);
179 hir
::ItemKind
::TraitAlias(..) => {
180 check_trait(tcx
, item
);
186 pub fn check_trait_item(tcx
: TyCtxt
<'_
>, def_id
: LocalDefId
) {
187 let hir_id
= tcx
.hir().as_local_hir_id(def_id
);
188 let trait_item
= tcx
.hir().expect_trait_item(hir_id
);
190 let method_sig
= match trait_item
.kind
{
191 hir
::TraitItemKind
::Fn(ref sig
, _
) => Some(sig
),
194 check_object_unsafe_self_trait_by_name(tcx
, &trait_item
);
195 check_associated_item(tcx
, trait_item
.hir_id
, trait_item
.span
, method_sig
);
198 fn could_be_self(trait_def_id
: LocalDefId
, ty
: &hir
::Ty
<'_
>) -> bool
{
200 hir
::TyKind
::TraitObject([trait_ref
], ..) => match trait_ref
.trait_ref
.path
.segments
{
201 [s
] => s
.res
.and_then(|r
| r
.opt_def_id()) == Some(trait_def_id
.to_def_id()),
208 /// Detect when an object unsafe trait is referring to itself in one of its associated items.
209 /// When this is done, suggest using `Self` instead.
210 fn check_object_unsafe_self_trait_by_name(tcx
: TyCtxt
<'_
>, item
: &hir
::TraitItem
<'_
>) {
211 let (trait_name
, trait_def_id
) = match tcx
.hir().get(tcx
.hir().get_parent_item(item
.hir_id
)) {
212 hir
::Node
::Item(item
) => match item
.kind
{
213 hir
::ItemKind
::Trait(..) => (item
.ident
, tcx
.hir().local_def_id(item
.hir_id
)),
218 let mut trait_should_be_self
= vec
![];
220 hir
::TraitItemKind
::Const(ty
, _
) | hir
::TraitItemKind
::Type(_
, Some(ty
))
221 if could_be_self(trait_def_id
, ty
) =>
223 trait_should_be_self
.push(ty
.span
)
225 hir
::TraitItemKind
::Fn(sig
, _
) => {
226 for ty
in sig
.decl
.inputs
{
227 if could_be_self(trait_def_id
, ty
) {
228 trait_should_be_self
.push(ty
.span
);
231 match sig
.decl
.output
{
232 hir
::FnRetTy
::Return(ty
) if could_be_self(trait_def_id
, ty
) => {
233 trait_should_be_self
.push(ty
.span
);
240 if !trait_should_be_self
.is_empty() {
241 if tcx
.object_safety_violations(trait_def_id
).is_empty() {
244 let sugg
= trait_should_be_self
.iter().map(|span
| (*span
, "Self".to_string())).collect();
247 trait_should_be_self
,
248 "associated item referring to unboxed trait object for its own trait",
250 .span_label(trait_name
.span
, "in this trait")
251 .multipart_suggestion(
252 "you might have meant to use `Self` to refer to the implementing type",
254 Applicability
::MachineApplicable
,
260 pub fn check_impl_item(tcx
: TyCtxt
<'_
>, def_id
: LocalDefId
) {
261 let hir_id
= tcx
.hir().as_local_hir_id(def_id
);
262 let impl_item
= tcx
.hir().expect_impl_item(hir_id
);
264 let method_sig
= match impl_item
.kind
{
265 hir
::ImplItemKind
::Fn(ref sig
, _
) => Some(sig
),
269 check_associated_item(tcx
, impl_item
.hir_id
, impl_item
.span
, method_sig
);
272 fn check_associated_item(
276 sig_if_method
: Option
<&hir
::FnSig
<'_
>>,
278 debug
!("check_associated_item: {:?}", item_id
);
280 let code
= ObligationCauseCode
::MiscObligation
;
281 for_id(tcx
, item_id
, span
).with_fcx(|fcx
, tcx
| {
282 let item
= fcx
.tcx
.associated_item(fcx
.tcx
.hir().local_def_id(item_id
));
284 let (mut implied_bounds
, self_ty
) = match item
.container
{
285 ty
::TraitContainer(_
) => (vec
![], fcx
.tcx
.types
.self_param
),
286 ty
::ImplContainer(def_id
) => {
287 (fcx
.impl_implied_bounds(def_id
, span
), fcx
.tcx
.type_of(def_id
))
292 ty
::AssocKind
::Const
=> {
293 let ty
= fcx
.tcx
.type_of(item
.def_id
);
294 let ty
= fcx
.normalize_associated_types_in(span
, &ty
);
295 fcx
.register_wf_obligation(ty
.into(), span
, code
.clone());
297 ty
::AssocKind
::Fn
=> {
298 let sig
= fcx
.tcx
.fn_sig(item
.def_id
);
299 let sig
= fcx
.normalize_associated_types_in(span
, &sig
);
300 let hir_sig
= sig_if_method
.expect("bad signature for method");
310 check_method_receiver(fcx
, hir_sig
, &item
, self_ty
);
312 ty
::AssocKind
::Type
=> {
313 if item
.defaultness
.has_value() {
314 let ty
= fcx
.tcx
.type_of(item
.def_id
);
315 let ty
= fcx
.normalize_associated_types_in(span
, &ty
);
316 fcx
.register_wf_obligation(ty
.into(), span
, code
.clone());
325 fn for_item
<'tcx
>(tcx
: TyCtxt
<'tcx
>, item
: &hir
::Item
<'_
>) -> CheckWfFcxBuilder
<'tcx
> {
326 for_id(tcx
, item
.hir_id
, item
.span
)
329 fn for_id(tcx
: TyCtxt
<'_
>, id
: hir
::HirId
, span
: Span
) -> CheckWfFcxBuilder
<'_
> {
330 let def_id
= tcx
.hir().local_def_id(id
);
332 inherited
: Inherited
::build(tcx
, def_id
),
335 param_env
: tcx
.param_env(def_id
),
339 fn item_adt_kind(kind
: &ItemKind
<'_
>) -> Option
<AdtKind
> {
341 ItemKind
::Struct(..) => Some(AdtKind
::Struct
),
342 ItemKind
::Union(..) => Some(AdtKind
::Union
),
343 ItemKind
::Enum(..) => Some(AdtKind
::Enum
),
348 /// In a type definition, we check that to ensure that the types of the fields are well-formed.
349 fn check_type_defn
<'tcx
, F
>(
351 item
: &hir
::Item
<'tcx
>,
353 mut lookup_fields
: F
,
355 F
: for<'fcx
> FnMut(&FnCtxt
<'fcx
, 'tcx
>) -> Vec
<AdtVariant
<'tcx
>>,
357 for_item(tcx
, item
).with_fcx(|fcx
, fcx_tcx
| {
358 let variants
= lookup_fields(fcx
);
359 let def_id
= fcx
.tcx
.hir().local_def_id(item
.hir_id
);
360 let packed
= fcx
.tcx
.adt_def(def_id
).repr
.packed();
362 for variant
in &variants
{
363 // For DST, or when drop needs to copy things around, all
364 // intermediate types must be sized.
365 let needs_drop_copy
= || {
367 let ty
= variant
.fields
.last().unwrap().ty
;
368 let ty
= fcx
.tcx
.erase_regions(&ty
);
369 if ty
.needs_infer() {
372 .delay_span_bug(item
.span
, &format
!("inference variables in {:?}", ty
));
373 // Just treat unresolved type expression as if it needs drop.
376 ty
.needs_drop(fcx_tcx
, fcx_tcx
.param_env(def_id
))
380 let all_sized
= all_sized
|| variant
.fields
.is_empty() || needs_drop_copy();
381 let unsized_len
= if all_sized { 0 }
else { 1 }
;
383 variant
.fields
[..variant
.fields
.len() - unsized_len
].iter().enumerate()
385 let last
= idx
== variant
.fields
.len() - 1;
388 fcx
.tcx
.require_lang_item(lang_items
::SizedTraitLangItem
, None
),
389 traits
::ObligationCause
::new(
393 adt_kind
: match item_adt_kind(&item
.kind
) {
403 // All field types must be well-formed.
404 for field
in &variant
.fields
{
405 fcx
.register_wf_obligation(
408 ObligationCauseCode
::MiscObligation
,
412 // Explicit `enum` discriminant values must const-evaluate successfully.
413 if let Some(discr_def_id
) = variant
.explicit_discr
{
415 InternalSubsts
::identity_for_item(fcx
.tcx
, discr_def_id
.to_def_id());
417 let cause
= traits
::ObligationCause
::new(
418 fcx
.tcx
.def_span(discr_def_id
),
420 traits
::MiscObligation
,
422 fcx
.register_predicate(traits
::Obligation
::new(
425 ty
::PredicateKind
::ConstEvaluatable(discr_def_id
.to_def_id(), discr_substs
)
426 .to_predicate(fcx
.tcx
),
431 check_where_clauses(tcx
, fcx
, item
.span
, def_id
.to_def_id(), None
);
433 // No implied bounds in a struct definition.
438 fn check_trait(tcx
: TyCtxt
<'_
>, item
: &hir
::Item
<'_
>) {
439 debug
!("check_trait: {:?}", item
.hir_id
);
441 let trait_def_id
= tcx
.hir().local_def_id(item
.hir_id
);
443 let trait_def
= tcx
.trait_def(trait_def_id
);
444 if trait_def
.is_marker
445 || matches
!(trait_def
.specialization_kind
, TraitSpecializationKind
::Marker
)
447 for associated_def_id
in &*tcx
.associated_item_def_ids(trait_def_id
) {
450 tcx
.def_span(*associated_def_id
),
452 "marker traits cannot have associated items",
458 for_item(tcx
, item
).with_fcx(|fcx
, _
| {
459 check_where_clauses(tcx
, fcx
, item
.span
, trait_def_id
.to_def_id(), None
);
460 check_associated_type_defaults(fcx
, trait_def_id
.to_def_id());
466 /// Checks all associated type defaults of trait `trait_def_id`.
468 /// Assuming the defaults are used, check that all predicates (bounds on the
469 /// assoc type and where clauses on the trait) hold.
470 fn check_associated_type_defaults(fcx
: &FnCtxt
<'_
, '_
>, trait_def_id
: DefId
) {
472 let substs
= InternalSubsts
::identity_for_item(tcx
, trait_def_id
);
474 // For all assoc. types with defaults, build a map from
475 // `<Self as Trait<...>>::Assoc` to the default type.
477 .associated_items(trait_def_id
)
478 .in_definition_order()
480 if item
.kind
== ty
::AssocKind
::Type
&& item
.defaultness
.has_value() {
481 // `<Self as Trait<...>>::Assoc`
482 let proj
= ty
::ProjectionTy { substs, item_def_id: item.def_id }
;
483 let default_ty
= tcx
.type_of(item
.def_id
);
484 debug
!("assoc. type default mapping: {} -> {}", proj
, default_ty
);
485 Some((proj
, default_ty
))
490 .collect
::<FxHashMap
<_
, _
>>();
492 /// Replaces projections of associated types with their default types.
494 /// This does a "shallow substitution", meaning that defaults that refer to
495 /// other defaulted assoc. types will still refer to the projection
496 /// afterwards, not to the other default. For example:
500 /// type A: Clone = Vec<Self::B>;
505 /// This will end up replacing the bound `Self::A: Clone` with
506 /// `Vec<Self::B>: Clone`, not with `Vec<u8>: Clone`. If we did a deep
507 /// substitution and ended up with the latter, the trait would be accepted.
508 /// If an `impl` then replaced `B` with something that isn't `Clone`,
509 /// suddenly the default for `A` is no longer valid. The shallow
510 /// substitution forces the trait to add a `B: Clone` bound to be accepted,
511 /// which means that an `impl` can replace any default without breaking
514 /// Note that this isn't needed for soundness: The defaults would still be
515 /// checked in any impl that doesn't override them.
516 struct DefaultNormalizer
<'tcx
> {
518 map
: FxHashMap
<ty
::ProjectionTy
<'tcx
>, Ty
<'tcx
>>,
521 impl<'tcx
> ty
::fold
::TypeFolder
<'tcx
> for DefaultNormalizer
<'tcx
> {
522 fn tcx
<'a
>(&'a
self) -> TyCtxt
<'tcx
> {
526 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
528 ty
::Projection(proj_ty
) => {
529 if let Some(default) = self.map
.get(&proj_ty
) {
532 t
.super_fold_with(self)
535 _
=> t
.super_fold_with(self),
540 // Now take all predicates defined on the trait, replace any mention of
541 // the assoc. types with their default, and prove them.
542 // We only consider predicates that directly mention the assoc. type.
543 let mut norm
= DefaultNormalizer { tcx, map }
;
544 let predicates
= fcx
.tcx
.predicates_of(trait_def_id
);
545 for &(orig_pred
, span
) in predicates
.predicates
.iter() {
546 let pred
= orig_pred
.fold_with(&mut norm
);
547 if pred
!= orig_pred
{
548 // Mentions one of the defaulted assoc. types
549 debug
!("default suitability check: proving predicate: {} -> {}", orig_pred
, pred
);
550 let pred
= fcx
.normalize_associated_types_in(span
, &pred
);
551 let cause
= traits
::ObligationCause
::new(
554 traits
::ItemObligation(trait_def_id
),
556 let obligation
= traits
::Obligation
::new(cause
, fcx
.param_env
, pred
);
558 fcx
.register_predicate(obligation
);
563 fn check_item_fn(tcx
: TyCtxt
<'_
>, item
: &hir
::Item
<'_
>) {
564 for_item(tcx
, item
).with_fcx(|fcx
, tcx
| {
565 let def_id
= fcx
.tcx
.hir().local_def_id(item
.hir_id
);
566 let sig
= fcx
.tcx
.fn_sig(def_id
);
567 let sig
= fcx
.normalize_associated_types_in(item
.span
, &sig
);
568 let mut implied_bounds
= vec
![];
569 let hir_sig
= match &item
.kind
{
570 ItemKind
::Fn(sig
, ..) => sig
,
571 _
=> bug
!("expected `ItemKind::Fn`, found `{:?}`", item
.kind
),
586 fn check_item_type(tcx
: TyCtxt
<'_
>, item_id
: hir
::HirId
, ty_span
: Span
, allow_foreign_ty
: bool
) {
587 debug
!("check_item_type: {:?}", item_id
);
589 for_id(tcx
, item_id
, ty_span
).with_fcx(|fcx
, tcx
| {
590 let ty
= tcx
.type_of(tcx
.hir().local_def_id(item_id
));
591 let item_ty
= fcx
.normalize_associated_types_in(ty_span
, &ty
);
593 let mut forbid_unsized
= true;
594 if allow_foreign_ty
{
595 let tail
= fcx
.tcx
.struct_tail_erasing_lifetimes(item_ty
, fcx
.param_env
);
596 if let ty
::Foreign(_
) = tail
.kind
{
597 forbid_unsized
= false;
601 fcx
.register_wf_obligation(item_ty
.into(), ty_span
, ObligationCauseCode
::MiscObligation
);
605 fcx
.tcx
.require_lang_item(lang_items
::SizedTraitLangItem
, None
),
606 traits
::ObligationCause
::new(ty_span
, fcx
.body_id
, traits
::MiscObligation
),
610 // No implied bounds in a const, etc.
617 item
: &'tcx hir
::Item
<'tcx
>,
618 ast_self_ty
: &hir
::Ty
<'_
>,
619 ast_trait_ref
: &Option
<hir
::TraitRef
<'_
>>,
621 debug
!("check_impl: {:?}", item
);
623 for_item(tcx
, item
).with_fcx(|fcx
, tcx
| {
624 let item_def_id
= fcx
.tcx
.hir().local_def_id(item
.hir_id
);
626 match *ast_trait_ref
{
627 Some(ref ast_trait_ref
) => {
628 // `#[rustc_reservation_impl]` impls are not real impls and
629 // therefore don't need to be WF (the trait's `Self: Trait` predicate
631 let trait_ref
= fcx
.tcx
.impl_trait_ref(item_def_id
).unwrap();
633 fcx
.normalize_associated_types_in(ast_trait_ref
.path
.span
, &trait_ref
);
634 let obligations
= traits
::wf
::trait_obligations(
639 ast_trait_ref
.path
.span
,
642 for obligation
in obligations
{
643 fcx
.register_predicate(obligation
);
647 let self_ty
= fcx
.tcx
.type_of(item_def_id
);
648 let self_ty
= fcx
.normalize_associated_types_in(item
.span
, &self_ty
);
649 fcx
.register_wf_obligation(
652 ObligationCauseCode
::MiscObligation
,
657 check_where_clauses(tcx
, fcx
, item
.span
, item_def_id
.to_def_id(), None
);
659 fcx
.impl_implied_bounds(item_def_id
.to_def_id(), item
.span
)
663 /// Checks where-clauses and inline bounds that are declared on `def_id`.
664 fn check_where_clauses
<'tcx
, 'fcx
>(
666 fcx
: &FnCtxt
<'fcx
, 'tcx
>,
669 return_ty
: Option
<(Ty
<'tcx
>, Span
)>,
671 debug
!("check_where_clauses(def_id={:?}, return_ty={:?})", def_id
, return_ty
);
673 let predicates
= fcx
.tcx
.predicates_of(def_id
);
674 let generics
= tcx
.generics_of(def_id
);
676 let is_our_default
= |def
: &ty
::GenericParamDef
| match def
.kind
{
677 GenericParamDefKind
::Type { has_default, .. }
=> {
678 has_default
&& def
.index
>= generics
.parent_count
as u32
683 // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
684 // For example, this forbids the declaration:
686 // struct Foo<T = Vec<[u32]>> { .. }
688 // Here, the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
689 for param
in &generics
.params
{
690 if let GenericParamDefKind
::Type { .. }
= param
.kind
{
691 if is_our_default(¶m
) {
692 let ty
= fcx
.tcx
.type_of(param
.def_id
);
693 // Ignore dependent defaults -- that is, where the default of one type
694 // parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
695 // be sure if it will error or not as user might always specify the other.
696 if !ty
.needs_subst() {
697 fcx
.register_wf_obligation(
699 fcx
.tcx
.def_span(param
.def_id
),
700 ObligationCauseCode
::MiscObligation
,
707 // Check that trait predicates are WF when params are substituted by their defaults.
708 // We don't want to overly constrain the predicates that may be written but we want to
709 // catch cases where a default my never be applied such as `struct Foo<T: Copy = String>`.
710 // Therefore we check if a predicate which contains a single type param
711 // with a concrete default is WF with that default substituted.
712 // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
714 // First we build the defaulted substitution.
715 let substs
= InternalSubsts
::for_item(fcx
.tcx
, def_id
, |param
, _
| {
717 GenericParamDefKind
::Lifetime
=> {
718 // All regions are identity.
719 fcx
.tcx
.mk_param_from_def(param
)
722 GenericParamDefKind
::Type { .. }
=> {
723 // If the param has a default, ...
724 if is_our_default(param
) {
725 let default_ty
= fcx
.tcx
.type_of(param
.def_id
);
726 // ... and it's not a dependent default, ...
727 if !default_ty
.needs_subst() {
728 // ... then substitute it with the default.
729 return default_ty
.into();
733 fcx
.tcx
.mk_param_from_def(param
)
736 GenericParamDefKind
::Const
=> {
737 // FIXME(const_generics:defaults)
738 fcx
.tcx
.mk_param_from_def(param
)
743 // Now we build the substituted predicates.
744 let default_obligations
= predicates
747 .flat_map(|&(pred
, sp
)| {
750 params
: FxHashSet
<u32>,
752 impl<'tcx
> ty
::fold
::TypeVisitor
<'tcx
> for CountParams
{
753 fn visit_ty(&mut self, t
: Ty
<'tcx
>) -> bool
{
754 if let ty
::Param(param
) = t
.kind
{
755 self.params
.insert(param
.index
);
757 t
.super_visit_with(self)
760 fn visit_region(&mut self, _
: ty
::Region
<'tcx
>) -> bool
{
764 fn visit_const(&mut self, c
: &'tcx ty
::Const
<'tcx
>) -> bool
{
765 if let ty
::ConstKind
::Param(param
) = c
.val
{
766 self.params
.insert(param
.index
);
768 c
.super_visit_with(self)
771 let mut param_count
= CountParams
::default();
772 let has_region
= pred
.visit_with(&mut param_count
);
773 let substituted_pred
= pred
.subst(fcx
.tcx
, substs
);
774 // Don't check non-defaulted params, dependent defaults (including lifetimes)
775 // or preds with multiple params.
776 if substituted_pred
.has_param_types_or_consts()
777 || param_count
.params
.len() > 1
781 } else if predicates
.predicates
.iter().any(|&(p
, _
)| p
== substituted_pred
) {
782 // Avoid duplication of predicates that contain no parameters, for example.
785 Some((substituted_pred
, sp
))
789 // Convert each of those into an obligation. So if you have
790 // something like `struct Foo<T: Copy = String>`, we would
791 // take that predicate `T: Copy`, substitute to `String: Copy`
792 // (actually that happens in the previous `flat_map` call),
793 // and then try to prove it (in this case, we'll fail).
795 // Note the subtle difference from how we handle `predicates`
796 // below: there, we are not trying to prove those predicates
797 // to be *true* but merely *well-formed*.
798 let pred
= fcx
.normalize_associated_types_in(sp
, &pred
);
800 traits
::ObligationCause
::new(sp
, fcx
.body_id
, traits
::ItemObligation(def_id
));
801 traits
::Obligation
::new(cause
, fcx
.param_env
, pred
)
804 let predicates
= predicates
.instantiate_identity(fcx
.tcx
);
806 if let Some((mut return_ty
, span
)) = return_ty
{
807 if return_ty
.has_infer_types_or_consts() {
808 fcx
.select_obligations_where_possible(false, |_
| {}
);
809 return_ty
= fcx
.resolve_vars_if_possible(&return_ty
);
811 check_opaque_types(tcx
, fcx
, def_id
.expect_local(), span
, return_ty
);
814 let predicates
= fcx
.normalize_associated_types_in(span
, &predicates
);
816 debug
!("check_where_clauses: predicates={:?}", predicates
.predicates
);
817 assert_eq
!(predicates
.predicates
.len(), predicates
.spans
.len());
819 predicates
.predicates
.iter().zip(predicates
.spans
.iter()).flat_map(|(&p
, &sp
)| {
820 traits
::wf
::predicate_obligations(fcx
, fcx
.param_env
, fcx
.body_id
, p
, sp
)
823 for obligation
in wf_obligations
.chain(default_obligations
) {
824 debug
!("next obligation cause: {:?}", obligation
.cause
);
825 fcx
.register_predicate(obligation
);
829 fn check_fn_or_method
<'fcx
, 'tcx
>(
831 fcx
: &FnCtxt
<'fcx
, 'tcx
>,
833 sig
: ty
::PolyFnSig
<'tcx
>,
834 hir_sig
: &hir
::FnSig
<'_
>,
836 implied_bounds
: &mut Vec
<Ty
<'tcx
>>,
838 let sig
= fcx
.normalize_associated_types_in(span
, &sig
);
839 let sig
= fcx
.tcx
.liberate_late_bound_regions(def_id
, &sig
);
841 for (&input_ty
, span
) in sig
.inputs().iter().zip(hir_sig
.decl
.inputs
.iter().map(|t
| t
.span
)) {
842 fcx
.register_wf_obligation(input_ty
.into(), span
, ObligationCauseCode
::MiscObligation
);
844 implied_bounds
.extend(sig
.inputs());
846 fcx
.register_wf_obligation(
848 hir_sig
.decl
.output
.span(),
849 ObligationCauseCode
::ReturnType
,
852 // FIXME(#25759) return types should not be implied bounds
853 implied_bounds
.push(sig
.output());
855 check_where_clauses(tcx
, fcx
, span
, def_id
, Some((sig
.output(), hir_sig
.decl
.output
.span())));
858 /// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions
859 /// laid for "higher-order pattern unification".
860 /// This ensures that inference is tractable.
861 /// In particular, definitions of opaque types can only use other generics as arguments,
862 /// and they cannot repeat an argument. Example:
865 /// type Foo<A, B> = impl Bar<A, B>;
867 /// // Okay -- `Foo` is applied to two distinct, generic types.
868 /// fn a<T, U>() -> Foo<T, U> { .. }
870 /// // Not okay -- `Foo` is applied to `T` twice.
871 /// fn b<T>() -> Foo<T, T> { .. }
873 /// // Not okay -- `Foo` is applied to a non-generic type.
874 /// fn b<T>() -> Foo<T, u32> { .. }
877 fn check_opaque_types
<'fcx
, 'tcx
>(
879 fcx
: &FnCtxt
<'fcx
, 'tcx
>,
880 fn_def_id
: LocalDefId
,
884 trace
!("check_opaque_types(ty={:?})", ty
);
885 ty
.fold_with(&mut ty
::fold
::BottomUpFolder
{
888 if let ty
::Opaque(def_id
, substs
) = ty
.kind
{
889 trace
!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id
, substs
);
890 let generics
= tcx
.generics_of(def_id
);
892 let opaque_hir_id
= if let Some(local_id
) = def_id
.as_local() {
893 tcx
.hir().as_local_hir_id(local_id
)
895 // Opaque types from other crates won't have defining uses in this crate.
898 if let hir
::ItemKind
::OpaqueTy(hir
::OpaqueTy { impl_trait_fn: Some(_), .. }
) =
899 tcx
.hir().expect_item(opaque_hir_id
).kind
901 // No need to check return position impl trait (RPIT)
902 // because for type and const parameters they are correct
903 // by construction: we convert
905 // fn foo<P0..Pn>() -> impl Trait
910 // fn foo<P0..Pn>() -> Foo<P0...Pn>.
912 // For lifetime parameters we convert
914 // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
918 // type foo::<'p0..'pn>::Foo<'q0..'qm>
919 // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
921 // which would error here on all of the `'static` args.
924 if !may_define_opaque_type(tcx
, fn_def_id
, opaque_hir_id
) {
927 trace
!("check_opaque_types: may define, generics={:#?}", generics
);
928 let mut seen_params
: FxHashMap
<_
, Vec
<_
>> = FxHashMap
::default();
929 for (i
, arg
) in substs
.iter().enumerate() {
930 let arg_is_param
= match arg
.unpack() {
931 GenericArgKind
::Type(ty
) => matches
!(ty
.kind
, ty
::Param(_
)),
933 GenericArgKind
::Lifetime(region
) => {
934 if let ty
::ReStatic
= region
{
938 "non-defining opaque type use in defining scope",
941 tcx
.def_span(generics
.param_at(i
, tcx
).def_id
),
942 "cannot use static lifetime; use a bound lifetime \
943 instead or remove the lifetime parameter from the \
953 GenericArgKind
::Const(ct
) => matches
!(ct
.val
, ty
::ConstKind
::Param(_
)),
957 seen_params
.entry(arg
).or_default().push(i
);
959 // Prevent `fn foo() -> Foo<u32>` from being defining.
960 let opaque_param
= generics
.param_at(i
, tcx
);
962 .struct_span_err(span
, "non-defining opaque type use in defining scope")
964 tcx
.def_span(opaque_param
.def_id
),
966 "used non-generic {} `{}` for generic parameter",
967 opaque_param
.kind
.descr(),
973 } // for (arg, param)
975 for (_
, indices
) in seen_params
{
976 if indices
.len() > 1 {
977 let descr
= generics
.param_at(indices
[0], tcx
).kind
.descr();
978 let spans
: Vec
<_
> = indices
980 .map(|i
| tcx
.def_span(generics
.param_at(i
, tcx
).def_id
))
983 .struct_span_err(span
, "non-defining opaque type use in defining scope")
984 .span_note(spans
, &format
!("{} used multiple times", descr
))
996 const HELP_FOR_SELF_TYPE
: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
997 `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
998 of the previous types except `Self`)";
1000 fn check_method_receiver
<'fcx
, 'tcx
>(
1001 fcx
: &FnCtxt
<'fcx
, 'tcx
>,
1002 fn_sig
: &hir
::FnSig
<'_
>,
1003 method
: &ty
::AssocItem
,
1006 // Check that the method has a valid receiver type, given the type `Self`.
1007 debug
!("check_method_receiver({:?}, self_ty={:?})", method
, self_ty
);
1009 if !method
.fn_has_self_parameter
{
1013 let span
= fn_sig
.decl
.inputs
[0].span
;
1015 let sig
= fcx
.tcx
.fn_sig(method
.def_id
);
1016 let sig
= fcx
.normalize_associated_types_in(span
, &sig
);
1017 let sig
= fcx
.tcx
.liberate_late_bound_regions(method
.def_id
, &sig
);
1019 debug
!("check_method_receiver: sig={:?}", sig
);
1021 let self_ty
= fcx
.normalize_associated_types_in(span
, &self_ty
);
1022 let self_ty
= fcx
.tcx
.liberate_late_bound_regions(method
.def_id
, &ty
::Binder
::bind(self_ty
));
1024 let receiver_ty
= sig
.inputs()[0];
1026 let receiver_ty
= fcx
.normalize_associated_types_in(span
, &receiver_ty
);
1028 fcx
.tcx
.liberate_late_bound_regions(method
.def_id
, &ty
::Binder
::bind(receiver_ty
));
1030 if fcx
.tcx
.features().arbitrary_self_types
{
1031 if !receiver_is_valid(fcx
, span
, receiver_ty
, self_ty
, true) {
1032 // Report error; `arbitrary_self_types` was enabled.
1033 e0307(fcx
, span
, receiver_ty
);
1036 if !receiver_is_valid(fcx
, span
, receiver_ty
, self_ty
, false) {
1037 if receiver_is_valid(fcx
, span
, receiver_ty
, self_ty
, true) {
1038 // Report error; would have worked with `arbitrary_self_types`.
1040 &fcx
.tcx
.sess
.parse_sess
,
1041 sym
::arbitrary_self_types
,
1044 "`{}` cannot be used as the type of `self` without \
1045 the `arbitrary_self_types` feature",
1049 .help(HELP_FOR_SELF_TYPE
)
1052 // Report error; would not have worked with `arbitrary_self_types`.
1053 e0307(fcx
, span
, receiver_ty
);
1059 fn e0307(fcx
: &FnCtxt
<'fcx
, 'tcx
>, span
: Span
, receiver_ty
: Ty
<'_
>) {
1061 fcx
.tcx
.sess
.diagnostic(),
1064 "invalid `self` parameter type: {:?}",
1067 .note("type of `self` must be `Self` or a type that dereferences to it")
1068 .help(HELP_FOR_SELF_TYPE
)
1072 /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
1073 /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
1074 /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
1075 /// strict: `receiver_ty` must implement `Receiver` and directly implement
1076 /// `Deref<Target = self_ty>`.
1078 /// N.B., there are cases this function returns `true` but causes an error to be emitted,
1079 /// particularly when `receiver_ty` derefs to a type that is the same as `self_ty` but has the
1080 /// wrong lifetime. Be careful of this if you are calling this function speculatively.
1081 fn receiver_is_valid
<'fcx
, 'tcx
>(
1082 fcx
: &FnCtxt
<'fcx
, 'tcx
>,
1084 receiver_ty
: Ty
<'tcx
>,
1086 arbitrary_self_types_enabled
: bool
,
1088 let cause
= fcx
.cause(span
, traits
::ObligationCauseCode
::MethodReceiver
);
1090 let can_eq_self
= |ty
| fcx
.infcx
.can_eq(fcx
.param_env
, self_ty
, ty
).is_ok();
1092 // `self: Self` is always valid.
1093 if can_eq_self(receiver_ty
) {
1094 if let Some(mut err
) = fcx
.demand_eqtype_with_origin(&cause
, self_ty
, receiver_ty
) {
1100 let mut autoderef
= fcx
.autoderef(span
, receiver_ty
);
1102 // The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`.
1103 if arbitrary_self_types_enabled
{
1104 autoderef
= autoderef
.include_raw_pointers();
1107 // The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
1110 let receiver_trait_def_id
= fcx
.tcx
.require_lang_item(lang_items
::ReceiverTraitLangItem
, None
);
1112 // Keep dereferencing `receiver_ty` until we get to `self_ty`.
1114 if let Some((potential_self_ty
, _
)) = autoderef
.next() {
1116 "receiver_is_valid: potential self type `{:?}` to match `{:?}`",
1117 potential_self_ty
, self_ty
1120 if can_eq_self(potential_self_ty
) {
1121 fcx
.register_predicates(autoderef
.into_obligations());
1123 if let Some(mut err
) =
1124 fcx
.demand_eqtype_with_origin(&cause
, self_ty
, potential_self_ty
)
1131 // Without `feature(arbitrary_self_types)`, we require that each step in the
1132 // deref chain implement `receiver`
1133 if !arbitrary_self_types_enabled
1134 && !receiver_is_implemented(
1136 receiver_trait_def_id
,
1145 debug
!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty
, self_ty
);
1146 // If he receiver already has errors reported due to it, consider it valid to avoid
1147 // unnecessary errors (#58712).
1148 return receiver_ty
.references_error();
1152 // Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`.
1153 if !arbitrary_self_types_enabled
1154 && !receiver_is_implemented(fcx
, receiver_trait_def_id
, cause
.clone(), receiver_ty
)
1162 fn receiver_is_implemented(
1163 fcx
: &FnCtxt
<'_
, 'tcx
>,
1164 receiver_trait_def_id
: DefId
,
1165 cause
: ObligationCause
<'tcx
>,
1166 receiver_ty
: Ty
<'tcx
>,
1168 let trait_ref
= ty
::TraitRef
{
1169 def_id
: receiver_trait_def_id
,
1170 substs
: fcx
.tcx
.mk_substs_trait(receiver_ty
, &[]),
1173 let obligation
= traits
::Obligation
::new(
1176 trait_ref
.without_const().to_predicate(fcx
.tcx
),
1179 if fcx
.predicate_must_hold_modulo_regions(&obligation
) {
1183 "receiver_is_implemented: type `{:?}` does not implement `Receiver` trait",
1190 fn check_variances_for_type_defn
<'tcx
>(
1192 item
: &hir
::Item
<'tcx
>,
1193 hir_generics
: &hir
::Generics
<'_
>,
1195 let item_def_id
= tcx
.hir().local_def_id(item
.hir_id
);
1196 let ty
= tcx
.type_of(item_def_id
);
1197 if tcx
.has_error_field(ty
) {
1201 let ty_predicates
= tcx
.predicates_of(item_def_id
);
1202 assert_eq
!(ty_predicates
.parent
, None
);
1203 let variances
= tcx
.variances_of(item_def_id
);
1205 let mut constrained_parameters
: FxHashSet
<_
> = variances
1208 .filter(|&(_
, &variance
)| variance
!= ty
::Bivariant
)
1209 .map(|(index
, _
)| Parameter(index
as u32))
1212 identify_constrained_generic_params(tcx
, ty_predicates
, None
, &mut constrained_parameters
);
1214 for (index
, _
) in variances
.iter().enumerate() {
1215 if constrained_parameters
.contains(&Parameter(index
as u32)) {
1219 let param
= &hir_generics
.params
[index
];
1222 hir
::ParamName
::Error
=> {}
1223 _
=> report_bivariance(tcx
, param
.span
, param
.name
.ident().name
),
1228 fn report_bivariance(tcx
: TyCtxt
<'_
>, span
: Span
, param_name
: Symbol
) {
1229 let mut err
= error_392(tcx
, span
, param_name
);
1231 let suggested_marker_id
= tcx
.lang_items().phantom_data();
1232 // Help is available only in presence of lang items.
1233 let msg
= if let Some(def_id
) = suggested_marker_id
{
1235 "consider removing `{}`, referring to it in a field, or using a marker such as `{}`",
1237 tcx
.def_path_str(def_id
),
1240 format
!("consider removing `{}` or referring to it in a field", param_name
)
1246 /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
1248 fn check_false_global_bounds(fcx
: &FnCtxt
<'_
, '_
>, span
: Span
, id
: hir
::HirId
) {
1249 let empty_env
= ty
::ParamEnv
::empty();
1251 let def_id
= fcx
.tcx
.hir().local_def_id(id
);
1252 let predicates
= fcx
.tcx
.predicates_of(def_id
).predicates
.iter().map(|(p
, _
)| *p
);
1253 // Check elaborated bounds.
1254 let implied_obligations
= traits
::elaborate_predicates(fcx
.tcx
, predicates
);
1256 for obligation
in implied_obligations
{
1257 let pred
= obligation
.predicate
;
1258 // Match the existing behavior.
1259 if pred
.is_global() && !pred
.has_late_bound_regions() {
1260 let pred
= fcx
.normalize_associated_types_in(span
, &pred
);
1261 let obligation
= traits
::Obligation
::new(
1262 traits
::ObligationCause
::new(span
, id
, traits
::TrivialBound
),
1266 fcx
.register_predicate(obligation
);
1270 fcx
.select_all_obligations_or_error();
1273 pub struct CheckTypeWellFormedVisitor
<'tcx
> {
1277 impl CheckTypeWellFormedVisitor
<'tcx
> {
1278 pub fn new(tcx
: TyCtxt
<'tcx
>) -> CheckTypeWellFormedVisitor
<'tcx
> {
1279 CheckTypeWellFormedVisitor { tcx }
1283 impl ParItemLikeVisitor
<'tcx
> for CheckTypeWellFormedVisitor
<'tcx
> {
1284 fn visit_item(&self, i
: &'tcx hir
::Item
<'tcx
>) {
1285 debug
!("visit_item: {:?}", i
);
1286 let def_id
= self.tcx
.hir().local_def_id(i
.hir_id
);
1287 self.tcx
.ensure().check_item_well_formed(def_id
);
1290 fn visit_trait_item(&self, trait_item
: &'tcx hir
::TraitItem
<'tcx
>) {
1291 debug
!("visit_trait_item: {:?}", trait_item
);
1292 let def_id
= self.tcx
.hir().local_def_id(trait_item
.hir_id
);
1293 self.tcx
.ensure().check_trait_item_well_formed(def_id
);
1296 fn visit_impl_item(&self, impl_item
: &'tcx hir
::ImplItem
<'tcx
>) {
1297 debug
!("visit_impl_item: {:?}", impl_item
);
1298 let def_id
= self.tcx
.hir().local_def_id(impl_item
.hir_id
);
1299 self.tcx
.ensure().check_impl_item_well_formed(def_id
);
1303 ///////////////////////////////////////////////////////////////////////////
1306 // FIXME(eddyb) replace this with getting fields/discriminants through `ty::AdtDef`.
1307 struct AdtVariant
<'tcx
> {
1308 /// Types of fields in the variant, that must be well-formed.
1309 fields
: Vec
<AdtField
<'tcx
>>,
1311 /// Explicit discriminant of this variant (e.g. `A = 123`),
1312 /// that must evaluate to a constant value.
1313 explicit_discr
: Option
<LocalDefId
>,
1316 struct AdtField
<'tcx
> {
1321 impl<'a
, 'tcx
> FnCtxt
<'a
, 'tcx
> {
1322 // FIXME(eddyb) replace this with getting fields through `ty::AdtDef`.
1323 fn non_enum_variant(&self, struct_def
: &hir
::VariantData
<'_
>) -> AdtVariant
<'tcx
> {
1324 let fields
= struct_def
1328 let field_ty
= self.tcx
.type_of(self.tcx
.hir().local_def_id(field
.hir_id
));
1329 let field_ty
= self.normalize_associated_types_in(field
.span
, &field_ty
);
1330 let field_ty
= self.resolve_vars_if_possible(&field_ty
);
1331 debug
!("non_enum_variant: type of field {:?} is {:?}", field
, field_ty
);
1332 AdtField { ty: field_ty, span: field.span }
1335 AdtVariant { fields, explicit_discr: None }
1338 fn enum_variants(&self, enum_def
: &hir
::EnumDef
<'_
>) -> Vec
<AdtVariant
<'tcx
>> {
1342 .map(|variant
| AdtVariant
{
1343 fields
: self.non_enum_variant(&variant
.data
).fields
,
1344 explicit_discr
: variant
1346 .map(|explicit_discr
| self.tcx
.hir().local_def_id(explicit_discr
.hir_id
)),
1351 fn impl_implied_bounds(&self, impl_def_id
: DefId
, span
: Span
) -> Vec
<Ty
<'tcx
>> {
1352 match self.tcx
.impl_trait_ref(impl_def_id
) {
1353 Some(ref trait_ref
) => {
1354 // Trait impl: take implied bounds from all types that
1355 // appear in the trait reference.
1356 let trait_ref
= self.normalize_associated_types_in(span
, trait_ref
);
1357 trait_ref
.substs
.types().collect()
1361 // Inherent impl: take implied bounds from the `self` type.
1362 let self_ty
= self.tcx
.type_of(impl_def_id
);
1363 let self_ty
= self.normalize_associated_types_in(span
, &self_ty
);
1370 fn error_392(tcx
: TyCtxt
<'_
>, span
: Span
, param_name
: Symbol
) -> DiagnosticBuilder
<'_
> {
1372 struct_span_err
!(tcx
.sess
, span
, E0392
, "parameter `{}` is never used", param_name
);
1373 err
.span_label(span
, "unused parameter");