1 // ignore-tidy-filelength
2 //! "Collection" is the process of determining the type and other external
3 //! details of each item in Rust. Collection is specifically concerned
4 //! with *inter-procedural* things -- for example, for a function
5 //! definition, collection will figure out the type and signature of the
6 //! function, but it will not visit the *body* of the function in any way,
7 //! nor examine type annotations on local variables (that's the job of
10 //! Collecting is ultimately defined by a bundle of queries that
11 //! inquire after various facts about the items in the crate (e.g.,
12 //! `type_of`, `generics_of`, `predicates_of`, etc). See the `provide` function
15 //! At present, however, we do run collection across all items in the
16 //! crate as a kind of pass. This should eventually be factored away.
18 use crate::astconv
::{AstConv, SizedByDefault}
;
19 use crate::bounds
::Bounds
;
20 use crate::check
::intrinsic
::intrinsic_operation_unsafety
;
21 use crate::constrained_generic_params
as cgp
;
23 use crate::middle
::resolve_lifetime
as rl
;
25 use rustc_ast
::{MetaItemKind, NestedMetaItem}
;
26 use rustc_attr
::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr}
;
27 use rustc_data_structures
::captures
::Captures
;
28 use rustc_data_structures
::fx
::{FxHashMap, FxHashSet, FxIndexSet}
;
29 use rustc_errors
::{struct_span_err, Applicability}
;
31 use rustc_hir
::def
::{CtorKind, DefKind, Res}
;
32 use rustc_hir
::def_id
::{DefId, LocalDefId, LOCAL_CRATE}
;
33 use rustc_hir
::intravisit
::{self, NestedVisitorMap, Visitor}
;
34 use rustc_hir
::weak_lang_items
;
35 use rustc_hir
::{GenericParamKind, HirId, Node}
;
36 use rustc_middle
::hir
::map
::blocks
::FnLikeNode
;
37 use rustc_middle
::hir
::map
::Map
;
38 use rustc_middle
::middle
::codegen_fn_attrs
::{CodegenFnAttrFlags, CodegenFnAttrs}
;
39 use rustc_middle
::mir
::mono
::Linkage
;
40 use rustc_middle
::ty
::query
::Providers
;
41 use rustc_middle
::ty
::subst
::InternalSubsts
;
42 use rustc_middle
::ty
::util
::Discr
;
43 use rustc_middle
::ty
::util
::IntTypeExt
;
44 use rustc_middle
::ty
::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt}
;
45 use rustc_middle
::ty
::{ReprOptions, ToPredicate, WithConstness}
;
46 use rustc_session
::config
::SanitizerSet
;
47 use rustc_session
::lint
;
48 use rustc_session
::parse
::feature_err
;
49 use rustc_span
::symbol
::{kw, sym, Ident, Symbol}
;
50 use rustc_span
::{Span, DUMMY_SP}
;
51 use rustc_target
::spec
::abi
;
52 use rustc_trait_selection
::traits
::error_reporting
::suggestions
::NextTypeParamName
;
57 struct OnlySelfBounds(bool
);
59 ///////////////////////////////////////////////////////////////////////////
62 fn collect_mod_item_types(tcx
: TyCtxt
<'_
>, module_def_id
: LocalDefId
) {
63 tcx
.hir().visit_item_likes_in_module(
65 &mut CollectItemTypesVisitor { tcx }
.as_deep_visitor(),
69 pub fn provide(providers
: &mut Providers
) {
70 *providers
= Providers
{
71 opt_const_param_of
: type_of
::opt_const_param_of
,
72 type_of
: type_of
::type_of
,
73 item_bounds
: item_bounds
::item_bounds
,
74 explicit_item_bounds
: item_bounds
::explicit_item_bounds
,
77 predicates_defined_on
,
78 projection_ty_from_predicates
,
79 explicit_predicates_of
,
81 super_predicates_that_define_assoc_type
,
82 trait_explicit_predicates_and_bounds
,
83 type_param_predicates
,
93 collect_mod_item_types
,
98 ///////////////////////////////////////////////////////////////////////////
100 /// Context specific to some particular item. This is what implements
101 /// `AstConv`. It has information about the predicates that are defined
102 /// on the trait. Unfortunately, this predicate information is
103 /// available in various different forms at various points in the
104 /// process. So we can't just store a pointer to e.g., the AST or the
105 /// parsed ty form, we have to be more flexible. To this end, the
106 /// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
107 /// `get_type_parameter_bounds` requests, drawing the information from
108 /// the AST (`hir::Generics`), recursively.
109 pub struct ItemCtxt
<'tcx
> {
114 ///////////////////////////////////////////////////////////////////////////
117 crate struct PlaceholderHirTyCollector(crate Vec
<Span
>);
119 impl<'v
> Visitor
<'v
> for PlaceholderHirTyCollector
{
120 type Map
= intravisit
::ErasedMap
<'v
>;
122 fn nested_visit_map(&mut self) -> NestedVisitorMap
<Self::Map
> {
123 NestedVisitorMap
::None
125 fn visit_ty(&mut self, t
: &'v hir
::Ty
<'v
>) {
126 if let hir
::TyKind
::Infer
= t
.kind
{
129 intravisit
::walk_ty(self, t
)
133 struct CollectItemTypesVisitor
<'tcx
> {
137 /// If there are any placeholder types (`_`), emit an error explaining that this is not allowed
138 /// and suggest adding type parameters in the appropriate place, taking into consideration any and
139 /// all already existing generic type parameters to avoid suggesting a name that is already in use.
140 crate fn placeholder_type_error(
143 generics
: &[hir
::GenericParam
<'_
>],
144 placeholder_types
: Vec
<Span
>,
146 hir_ty
: Option
<&hir
::Ty
<'_
>>,
148 if placeholder_types
.is_empty() {
152 let type_name
= generics
.next_type_param_name(None
);
153 let mut sugg
: Vec
<_
> =
154 placeholder_types
.iter().map(|sp
| (*sp
, (*type_name
).to_string())).collect();
156 if generics
.is_empty() {
157 if let Some(span
) = span
{
158 sugg
.push((span
, format
!("<{}>", type_name
)));
160 } else if let Some(arg
) = generics
162 .find(|arg
| matches
!(arg
.name
, hir
::ParamName
::Plain(Ident { name: kw::Underscore, .. }
)))
164 // Account for `_` already present in cases like `struct S<_>(_);` and suggest
165 // `struct S<T>(T);` instead of `struct S<_, T>(T);`.
166 sugg
.push((arg
.span
, (*type_name
).to_string()));
168 let last
= generics
.iter().last().unwrap();
170 // Account for bounds, we want `fn foo<T: E, K>(_: K)` not `fn foo<T, K: E>(_: K)`.
171 last
.bounds_span().unwrap_or(last
.span
).shrink_to_hi(),
172 format
!(", {}", type_name
),
176 let mut err
= bad_placeholder_type(tcx
, placeholder_types
);
178 // Suggest, but only if it is not a function in const or static
180 let mut is_fn
= false;
181 let mut is_const
= false;
182 let mut is_static
= false;
184 if let Some(hir_ty
) = hir_ty
{
185 if let hir
::TyKind
::BareFn(_
) = hir_ty
.kind
{
188 // Check if parent is const or static
189 let parent_id
= tcx
.hir().get_parent_node(hir_ty
.hir_id
);
190 let parent_node
= tcx
.hir().get(parent_id
);
192 if let hir
::Node
::Item(item
) = parent_node
{
193 if let hir
::ItemKind
::Const(_
, _
) = item
.kind
{
195 } else if let hir
::ItemKind
::Static(_
, _
, _
) = item
.kind
{
202 // if function is wrapped around a const or static,
203 // then don't show the suggestion
204 if !(is_fn
&& (is_const
|| is_static
)) {
205 err
.multipart_suggestion(
206 "use type parameters instead",
208 Applicability
::HasPlaceholders
,
215 fn reject_placeholder_type_signatures_in_item(tcx
: TyCtxt
<'tcx
>, item
: &'tcx hir
::Item
<'tcx
>) {
216 let (generics
, suggest
) = match &item
.kind
{
217 hir
::ItemKind
::Union(_
, generics
)
218 | hir
::ItemKind
::Enum(_
, generics
)
219 | hir
::ItemKind
::TraitAlias(generics
, _
)
220 | hir
::ItemKind
::Trait(_
, _
, generics
, ..)
221 | hir
::ItemKind
::Impl(hir
::Impl { generics, .. }
)
222 | hir
::ItemKind
::Struct(_
, generics
) => (generics
, true),
223 hir
::ItemKind
::OpaqueTy(hir
::OpaqueTy { generics, .. }
)
224 | hir
::ItemKind
::TyAlias(_
, generics
) => (generics
, false),
225 // `static`, `fn` and `const` are handled elsewhere to suggest appropriate type.
229 let mut visitor
= PlaceholderHirTyCollector
::default();
230 visitor
.visit_item(item
);
232 placeholder_type_error(tcx
, Some(generics
.span
), generics
.params
, visitor
.0, suggest
, None
);
235 impl Visitor
<'tcx
> for CollectItemTypesVisitor
<'tcx
> {
236 type Map
= Map
<'tcx
>;
238 fn nested_visit_map(&mut self) -> NestedVisitorMap
<Self::Map
> {
239 NestedVisitorMap
::OnlyBodies(self.tcx
.hir())
242 fn visit_item(&mut self, item
: &'tcx hir
::Item
<'tcx
>) {
243 convert_item(self.tcx
, item
.item_id());
244 reject_placeholder_type_signatures_in_item(self.tcx
, item
);
245 intravisit
::walk_item(self, item
);
248 fn visit_generics(&mut self, generics
: &'tcx hir
::Generics
<'tcx
>) {
249 for param
in generics
.params
{
251 hir
::GenericParamKind
::Lifetime { .. }
=> {}
252 hir
::GenericParamKind
::Type { default: Some(_), .. }
=> {
253 let def_id
= self.tcx
.hir().local_def_id(param
.hir_id
);
254 self.tcx
.ensure().type_of(def_id
);
256 hir
::GenericParamKind
::Type { .. }
=> {}
257 hir
::GenericParamKind
::Const { .. }
=> {
258 let def_id
= self.tcx
.hir().local_def_id(param
.hir_id
);
259 self.tcx
.ensure().type_of(def_id
);
260 // FIXME(const_generics_defaults)
264 intravisit
::walk_generics(self, generics
);
267 fn visit_expr(&mut self, expr
: &'tcx hir
::Expr
<'tcx
>) {
268 if let hir
::ExprKind
::Closure(..) = expr
.kind
{
269 let def_id
= self.tcx
.hir().local_def_id(expr
.hir_id
);
270 self.tcx
.ensure().generics_of(def_id
);
271 self.tcx
.ensure().type_of(def_id
);
273 intravisit
::walk_expr(self, expr
);
276 fn visit_trait_item(&mut self, trait_item
: &'tcx hir
::TraitItem
<'tcx
>) {
277 convert_trait_item(self.tcx
, trait_item
.trait_item_id());
278 intravisit
::walk_trait_item(self, trait_item
);
281 fn visit_impl_item(&mut self, impl_item
: &'tcx hir
::ImplItem
<'tcx
>) {
282 convert_impl_item(self.tcx
, impl_item
.impl_item_id());
283 intravisit
::walk_impl_item(self, impl_item
);
287 ///////////////////////////////////////////////////////////////////////////
288 // Utility types and common code for the above passes.
290 fn bad_placeholder_type(
292 mut spans
: Vec
<Span
>,
293 ) -> rustc_errors
::DiagnosticBuilder
<'tcx
> {
295 let mut err
= struct_span_err
!(
299 "the type placeholder `_` is not allowed within types on item signatures",
302 err
.span_label(span
, "not allowed in type signatures");
307 impl ItemCtxt
<'tcx
> {
308 pub fn new(tcx
: TyCtxt
<'tcx
>, item_def_id
: DefId
) -> ItemCtxt
<'tcx
> {
309 ItemCtxt { tcx, item_def_id }
312 pub fn to_ty(&self, ast_ty
: &hir
::Ty
<'_
>) -> Ty
<'tcx
> {
313 <dyn AstConv
<'_
>>::ast_ty_to_ty(self, ast_ty
)
316 pub fn hir_id(&self) -> hir
::HirId
{
317 self.tcx
.hir().local_def_id_to_hir_id(self.item_def_id
.expect_local())
320 pub fn node(&self) -> hir
::Node
<'tcx
> {
321 self.tcx
.hir().get(self.hir_id())
325 impl AstConv
<'tcx
> for ItemCtxt
<'tcx
> {
326 fn tcx(&self) -> TyCtxt
<'tcx
> {
330 fn item_def_id(&self) -> Option
<DefId
> {
331 Some(self.item_def_id
)
334 fn default_constness_for_trait_bounds(&self) -> hir
::Constness
{
335 if let Some(fn_like
) = FnLikeNode
::from_node(self.node()) {
338 hir
::Constness
::NotConst
342 fn get_type_parameter_bounds(
347 ) -> ty
::GenericPredicates
<'tcx
> {
348 self.tcx
.at(span
).type_param_predicates((
350 def_id
.expect_local(),
355 fn re_infer(&self, _
: Option
<&ty
::GenericParamDef
>, _
: Span
) -> Option
<ty
::Region
<'tcx
>> {
359 fn allow_ty_infer(&self) -> bool
{
363 fn ty_infer(&self, _
: Option
<&ty
::GenericParamDef
>, span
: Span
) -> Ty
<'tcx
> {
364 self.tcx().ty_error_with_message(span
, "bad_placeholder_type")
370 _
: Option
<&ty
::GenericParamDef
>,
372 ) -> &'tcx Const
<'tcx
> {
373 bad_placeholder_type(self.tcx(), vec
![span
]).emit();
374 // Typeck doesn't expect erased regions to be returned from `type_of`.
375 let ty
= self.tcx
.fold_regions(ty
, &mut false, |r
, _
| match r
{
376 ty
::ReErased
=> self.tcx
.lifetimes
.re_static
,
379 self.tcx().const_error(ty
)
382 fn projected_ty_from_poly_trait_ref(
386 item_segment
: &hir
::PathSegment
<'_
>,
387 poly_trait_ref
: ty
::PolyTraitRef
<'tcx
>,
389 if let Some(trait_ref
) = poly_trait_ref
.no_bound_vars() {
390 let item_substs
= <dyn AstConv
<'tcx
>>::create_substs_for_associated_item(
398 self.tcx().mk_projection(item_def_id
, item_substs
)
400 // There are no late-bound regions; we can just ignore the binder.
401 let mut err
= struct_span_err
!(
405 "cannot use the associated type of a trait \
406 with uninferred generic parameters"
410 hir
::Node
::Field(_
) | hir
::Node
::Ctor(_
) | hir
::Node
::Variant(_
) => {
412 self.tcx
.hir().expect_item(self.tcx
.hir().get_parent_item(self.hir_id()));
414 hir
::ItemKind
::Enum(_
, generics
)
415 | hir
::ItemKind
::Struct(_
, generics
)
416 | hir
::ItemKind
::Union(_
, generics
) => {
417 let lt_name
= get_new_lifetime_name(self.tcx
, poly_trait_ref
, generics
);
418 let (lt_sp
, sugg
) = match generics
.params
{
419 [] => (generics
.span
, format
!("<{}>", lt_name
)),
421 (bound
.span
.shrink_to_lo(), format
!("{}, ", lt_name
))
424 let suggestions
= vec
![
430 // Replace the existing lifetimes with a new named lifetime.
432 .replace_late_bound_regions(poly_trait_ref
, |_
| {
433 self.tcx
.mk_region(ty
::ReEarlyBound(
434 ty
::EarlyBoundRegion
{
437 name
: Symbol
::intern(<_name
),
446 err
.multipart_suggestion(
447 "use a fully qualified path with explicit lifetimes",
449 Applicability
::MaybeIncorrect
,
455 hir
::Node
::Item(hir
::Item
{
457 hir
::ItemKind
::Struct(..) | hir
::ItemKind
::Enum(..) | hir
::ItemKind
::Union(..),
461 | hir
::Node
::ForeignItem(_
)
462 | hir
::Node
::TraitItem(_
)
463 | hir
::Node
::ImplItem(_
) => {
466 "use a fully qualified path with inferred lifetimes",
469 // Erase named lt, we want `<A as B<'_>::C`, not `<A as B<'a>::C`.
470 self.tcx
.anonymize_late_bound_regions(poly_trait_ref
).skip_binder(),
473 Applicability
::MaybeIncorrect
,
479 self.tcx().ty_error()
483 fn normalize_ty(&self, _span
: Span
, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
484 // Types in item signatures are not normalized to avoid undue dependencies.
488 fn set_tainted_by_errors(&self) {
489 // There's no obvious place to track this, so just let it go.
492 fn record_ty(&self, _hir_id
: hir
::HirId
, _ty
: Ty
<'tcx
>, _span
: Span
) {
493 // There's no place to record types from signatures?
497 /// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.
498 fn get_new_lifetime_name
<'tcx
>(
500 poly_trait_ref
: ty
::PolyTraitRef
<'tcx
>,
501 generics
: &hir
::Generics
<'tcx
>,
503 let existing_lifetimes
= tcx
504 .collect_referenced_late_bound_regions(&poly_trait_ref
)
507 if let ty
::BoundRegionKind
::BrNamed(_
, name
) = lt
{
508 Some(name
.as_str().to_string())
513 .chain(generics
.params
.iter().filter_map(|param
| {
514 if let hir
::GenericParamKind
::Lifetime { .. }
= ¶m
.kind
{
515 Some(param
.name
.ident().as_str().to_string())
520 .collect
::<FxHashSet
<String
>>();
522 let a_to_z_repeat_n
= |n
| {
523 (b'a'
..=b'z'
).map(move |c
| {
524 let mut s
= '
\''
.to_string();
525 s
.extend(std
::iter
::repeat(char::from(c
)).take(n
));
530 // If all single char lifetime names are present, we wrap around and double the chars.
531 (1..).flat_map(a_to_z_repeat_n
).find(|lt
| !existing_lifetimes
.contains(lt
.as_str())).unwrap()
534 /// Returns the predicates defined on `item_def_id` of the form
535 /// `X: Foo` where `X` is the type parameter `def_id`.
536 fn type_param_predicates(
538 (item_def_id
, def_id
, assoc_name
): (DefId
, LocalDefId
, Ident
),
539 ) -> ty
::GenericPredicates
<'_
> {
542 // In the AST, bounds can derive from two places. Either
543 // written inline like `<T: Foo>` or in a where-clause like
546 let param_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
547 let param_owner
= tcx
.hir().ty_param_owner(param_id
);
548 let param_owner_def_id
= tcx
.hir().local_def_id(param_owner
);
549 let generics
= tcx
.generics_of(param_owner_def_id
);
550 let index
= generics
.param_def_id_to_index
[&def_id
.to_def_id()];
551 let ty
= tcx
.mk_ty_param(index
, tcx
.hir().ty_param_name(param_id
));
553 // Don't look for bounds where the type parameter isn't in scope.
554 let parent
= if item_def_id
== param_owner_def_id
.to_def_id() {
557 tcx
.generics_of(item_def_id
).parent
560 let mut result
= parent
562 let icx
= ItemCtxt
::new(tcx
, parent
);
563 icx
.get_type_parameter_bounds(DUMMY_SP
, def_id
.to_def_id(), assoc_name
)
565 .unwrap_or_default();
566 let mut extend
= None
;
568 let item_hir_id
= tcx
.hir().local_def_id_to_hir_id(item_def_id
.expect_local());
569 let ast_generics
= match tcx
.hir().get(item_hir_id
) {
570 Node
::TraitItem(item
) => &item
.generics
,
572 Node
::ImplItem(item
) => &item
.generics
,
574 Node
::Item(item
) => {
576 ItemKind
::Fn(.., ref generics
, _
)
577 | ItemKind
::Impl(hir
::Impl { ref generics, .. }
)
578 | ItemKind
::TyAlias(_
, ref generics
)
579 | ItemKind
::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }
)
580 | ItemKind
::Enum(_
, ref generics
)
581 | ItemKind
::Struct(_
, ref generics
)
582 | ItemKind
::Union(_
, ref generics
) => generics
,
583 ItemKind
::Trait(_
, _
, ref generics
, ..) => {
584 // Implied `Self: Trait` and supertrait bounds.
585 if param_id
== item_hir_id
{
586 let identity_trait_ref
= ty
::TraitRef
::identity(tcx
, item_def_id
);
588 Some((identity_trait_ref
.without_const().to_predicate(tcx
), item
.span
));
596 Node
::ForeignItem(item
) => match item
.kind
{
597 ForeignItemKind
::Fn(_
, _
, ref generics
) => generics
,
604 let icx
= ItemCtxt
::new(tcx
, item_def_id
);
605 let extra_predicates
= extend
.into_iter().chain(
606 icx
.type_parameter_bounds_in_generics(
610 OnlySelfBounds(true),
614 .filter(|(predicate
, _
)| match predicate
.kind().skip_binder() {
615 ty
::PredicateKind
::Trait(data
, _
) => data
.self_ty().is_param(index
),
620 tcx
.arena
.alloc_from_iter(result
.predicates
.iter().copied().chain(extra_predicates
));
624 impl ItemCtxt
<'tcx
> {
625 /// Finds bounds from `hir::Generics`. This requires scanning through the
626 /// AST. We do this to avoid having to convert *all* the bounds, which
627 /// would create artificial cycles. Instead, we can only convert the
628 /// bounds for a type parameter `X` if `X::Foo` is used.
629 fn type_parameter_bounds_in_generics(
631 ast_generics
: &'tcx hir
::Generics
<'tcx
>,
632 param_id
: hir
::HirId
,
634 only_self_bounds
: OnlySelfBounds
,
635 assoc_name
: Option
<Ident
>,
636 ) -> Vec
<(ty
::Predicate
<'tcx
>, Span
)> {
637 let constness
= self.default_constness_for_trait_bounds();
638 let from_ty_params
= ast_generics
641 .filter_map(|param
| match param
.kind
{
642 GenericParamKind
::Type { .. }
if param
.hir_id
== param_id
=> Some(¶m
.bounds
),
645 .flat_map(|bounds
| bounds
.iter())
646 .filter(|b
| match assoc_name
{
647 Some(assoc_name
) => self.bound_defines_assoc_item(b
, assoc_name
),
650 .flat_map(|b
| predicates_from_bound(self, ty
, b
, constness
));
652 let from_where_clauses
= ast_generics
656 .filter_map(|wp
| match *wp
{
657 hir
::WherePredicate
::BoundPredicate(ref bp
) => Some(bp
),
661 let bt
= if is_param(self.tcx
, &bp
.bounded_ty
, param_id
) {
663 } else if !only_self_bounds
.0 {
664 Some(self.to_ty(&bp
.bounded_ty
))
670 .filter(|b
| match assoc_name
{
671 Some(assoc_name
) => self.bound_defines_assoc_item(b
, assoc_name
),
674 .filter_map(move |b
| bt
.map(|bt
| (bt
, b
)))
676 .flat_map(|(bt
, b
)| predicates_from_bound(self, bt
, b
, constness
));
678 from_ty_params
.chain(from_where_clauses
).collect()
681 fn bound_defines_assoc_item(&self, b
: &hir
::GenericBound
<'_
>, assoc_name
: Ident
) -> bool
{
682 debug
!("bound_defines_assoc_item(b={:?}, assoc_name={:?})", b
, assoc_name
);
685 hir
::GenericBound
::Trait(poly_trait_ref
, _
) => {
686 let trait_ref
= &poly_trait_ref
.trait_ref
;
687 if let Some(trait_did
) = trait_ref
.trait_def_id() {
688 self.tcx
.trait_may_define_assoc_type(trait_did
, assoc_name
)
698 /// Tests whether this is the AST for a reference to the type
699 /// parameter with ID `param_id`. We use this so as to avoid running
700 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
701 /// conversion of the type to avoid inducing unnecessary cycles.
702 fn is_param(tcx
: TyCtxt
<'_
>, ast_ty
: &hir
::Ty
<'_
>, param_id
: hir
::HirId
) -> bool
{
703 if let hir
::TyKind
::Path(hir
::QPath
::Resolved(None
, ref path
)) = ast_ty
.kind
{
705 Res
::SelfTy(Some(def_id
), None
) | Res
::Def(DefKind
::TyParam
, def_id
) => {
706 def_id
== tcx
.hir().local_def_id(param_id
).to_def_id()
715 fn convert_item(tcx
: TyCtxt
<'_
>, item_id
: hir
::ItemId
) {
716 let it
= tcx
.hir().item(item_id
);
717 debug
!("convert: item {} with id {}", it
.ident
, it
.hir_id());
718 let def_id
= item_id
.def_id
;
721 // These don't define types.
722 hir
::ItemKind
::ExternCrate(_
)
723 | hir
::ItemKind
::Use(..)
724 | hir
::ItemKind
::Mod(_
)
725 | hir
::ItemKind
::GlobalAsm(_
) => {}
726 hir
::ItemKind
::ForeignMod { items, .. }
=> {
728 let item
= tcx
.hir().foreign_item(item
.id
);
729 tcx
.ensure().generics_of(item
.def_id
);
730 tcx
.ensure().type_of(item
.def_id
);
731 tcx
.ensure().predicates_of(item
.def_id
);
732 if let hir
::ForeignItemKind
::Fn(..) = item
.kind
{
733 tcx
.ensure().fn_sig(item
.def_id
);
737 hir
::ItemKind
::Enum(ref enum_definition
, _
) => {
738 tcx
.ensure().generics_of(def_id
);
739 tcx
.ensure().type_of(def_id
);
740 tcx
.ensure().predicates_of(def_id
);
741 convert_enum_variant_types(tcx
, def_id
.to_def_id(), &enum_definition
.variants
);
743 hir
::ItemKind
::Impl { .. }
=> {
744 tcx
.ensure().generics_of(def_id
);
745 tcx
.ensure().type_of(def_id
);
746 tcx
.ensure().impl_trait_ref(def_id
);
747 tcx
.ensure().predicates_of(def_id
);
749 hir
::ItemKind
::Trait(..) => {
750 tcx
.ensure().generics_of(def_id
);
751 tcx
.ensure().trait_def(def_id
);
752 tcx
.at(it
.span
).super_predicates_of(def_id
);
753 tcx
.ensure().predicates_of(def_id
);
755 hir
::ItemKind
::TraitAlias(..) => {
756 tcx
.ensure().generics_of(def_id
);
757 tcx
.at(it
.span
).super_predicates_of(def_id
);
758 tcx
.ensure().predicates_of(def_id
);
760 hir
::ItemKind
::Struct(ref struct_def
, _
) | hir
::ItemKind
::Union(ref struct_def
, _
) => {
761 tcx
.ensure().generics_of(def_id
);
762 tcx
.ensure().type_of(def_id
);
763 tcx
.ensure().predicates_of(def_id
);
765 for f
in struct_def
.fields() {
766 let def_id
= tcx
.hir().local_def_id(f
.hir_id
);
767 tcx
.ensure().generics_of(def_id
);
768 tcx
.ensure().type_of(def_id
);
769 tcx
.ensure().predicates_of(def_id
);
772 if let Some(ctor_hir_id
) = struct_def
.ctor_hir_id() {
773 convert_variant_ctor(tcx
, ctor_hir_id
);
777 // Desugared from `impl Trait`, so visited by the function's return type.
778 hir
::ItemKind
::OpaqueTy(hir
::OpaqueTy { impl_trait_fn: Some(_), .. }
) => {}
780 // Don't call `type_of` on opaque types, since that depends on type
781 // checking function bodies. `check_item_type` ensures that it's called
783 hir
::ItemKind
::OpaqueTy(..) => {
784 tcx
.ensure().generics_of(def_id
);
785 tcx
.ensure().predicates_of(def_id
);
786 tcx
.ensure().explicit_item_bounds(def_id
);
788 hir
::ItemKind
::TyAlias(..)
789 | hir
::ItemKind
::Static(..)
790 | hir
::ItemKind
::Const(..)
791 | hir
::ItemKind
::Fn(..) => {
792 tcx
.ensure().generics_of(def_id
);
793 tcx
.ensure().type_of(def_id
);
794 tcx
.ensure().predicates_of(def_id
);
796 hir
::ItemKind
::Fn(..) => tcx
.ensure().fn_sig(def_id
),
797 hir
::ItemKind
::OpaqueTy(..) => tcx
.ensure().item_bounds(def_id
),
804 fn convert_trait_item(tcx
: TyCtxt
<'_
>, trait_item_id
: hir
::TraitItemId
) {
805 let trait_item
= tcx
.hir().trait_item(trait_item_id
);
806 tcx
.ensure().generics_of(trait_item_id
.def_id
);
808 match trait_item
.kind
{
809 hir
::TraitItemKind
::Fn(..) => {
810 tcx
.ensure().type_of(trait_item_id
.def_id
);
811 tcx
.ensure().fn_sig(trait_item_id
.def_id
);
814 hir
::TraitItemKind
::Const(.., Some(_
)) => {
815 tcx
.ensure().type_of(trait_item_id
.def_id
);
818 hir
::TraitItemKind
::Const(..) => {
819 tcx
.ensure().type_of(trait_item_id
.def_id
);
820 // Account for `const C: _;`.
821 let mut visitor
= PlaceholderHirTyCollector
::default();
822 visitor
.visit_trait_item(trait_item
);
823 placeholder_type_error(tcx
, None
, &[], visitor
.0, false, None
);
826 hir
::TraitItemKind
::Type(_
, Some(_
)) => {
827 tcx
.ensure().item_bounds(trait_item_id
.def_id
);
828 tcx
.ensure().type_of(trait_item_id
.def_id
);
829 // Account for `type T = _;`.
830 let mut visitor
= PlaceholderHirTyCollector
::default();
831 visitor
.visit_trait_item(trait_item
);
832 placeholder_type_error(tcx
, None
, &[], visitor
.0, false, None
);
835 hir
::TraitItemKind
::Type(_
, None
) => {
836 tcx
.ensure().item_bounds(trait_item_id
.def_id
);
837 // #74612: Visit and try to find bad placeholders
838 // even if there is no concrete type.
839 let mut visitor
= PlaceholderHirTyCollector
::default();
840 visitor
.visit_trait_item(trait_item
);
842 placeholder_type_error(tcx
, None
, &[], visitor
.0, false, None
);
846 tcx
.ensure().predicates_of(trait_item_id
.def_id
);
849 fn convert_impl_item(tcx
: TyCtxt
<'_
>, impl_item_id
: hir
::ImplItemId
) {
850 let def_id
= impl_item_id
.def_id
;
851 tcx
.ensure().generics_of(def_id
);
852 tcx
.ensure().type_of(def_id
);
853 tcx
.ensure().predicates_of(def_id
);
854 let impl_item
= tcx
.hir().impl_item(impl_item_id
);
855 match impl_item
.kind
{
856 hir
::ImplItemKind
::Fn(..) => {
857 tcx
.ensure().fn_sig(def_id
);
859 hir
::ImplItemKind
::TyAlias(_
) => {
860 // Account for `type T = _;`
861 let mut visitor
= PlaceholderHirTyCollector
::default();
862 visitor
.visit_impl_item(impl_item
);
864 placeholder_type_error(tcx
, None
, &[], visitor
.0, false, None
);
866 hir
::ImplItemKind
::Const(..) => {}
870 fn convert_variant_ctor(tcx
: TyCtxt
<'_
>, ctor_id
: hir
::HirId
) {
871 let def_id
= tcx
.hir().local_def_id(ctor_id
);
872 tcx
.ensure().generics_of(def_id
);
873 tcx
.ensure().type_of(def_id
);
874 tcx
.ensure().predicates_of(def_id
);
877 fn convert_enum_variant_types(tcx
: TyCtxt
<'_
>, def_id
: DefId
, variants
: &[hir
::Variant
<'_
>]) {
878 let def
= tcx
.adt_def(def_id
);
879 let repr_type
= def
.repr
.discr_type();
880 let initial
= repr_type
.initial_discriminant(tcx
);
881 let mut prev_discr
= None
::<Discr
<'_
>>;
883 // fill the discriminant values and field types
884 for variant
in variants
{
885 let wrapped_discr
= prev_discr
.map_or(initial
, |d
| d
.wrap_incr(tcx
));
887 if let Some(ref e
) = variant
.disr_expr
{
888 let expr_did
= tcx
.hir().local_def_id(e
.hir_id
);
889 def
.eval_explicit_discr(tcx
, expr_did
.to_def_id())
890 } else if let Some(discr
) = repr_type
.disr_incr(tcx
, prev_discr
) {
893 struct_span_err
!(tcx
.sess
, variant
.span
, E0370
, "enum discriminant overflowed")
896 format
!("overflowed on value after {}", prev_discr
.unwrap()),
899 "explicitly set `{} = {}` if that is desired outcome",
900 variant
.ident
, wrapped_discr
905 .unwrap_or(wrapped_discr
),
908 for f
in variant
.data
.fields() {
909 let def_id
= tcx
.hir().local_def_id(f
.hir_id
);
910 tcx
.ensure().generics_of(def_id
);
911 tcx
.ensure().type_of(def_id
);
912 tcx
.ensure().predicates_of(def_id
);
915 // Convert the ctor, if any. This also registers the variant as
917 if let Some(ctor_hir_id
) = variant
.data
.ctor_hir_id() {
918 convert_variant_ctor(tcx
, ctor_hir_id
);
925 variant_did
: Option
<LocalDefId
>,
926 ctor_did
: Option
<LocalDefId
>,
928 discr
: ty
::VariantDiscr
,
929 def
: &hir
::VariantData
<'_
>,
930 adt_kind
: ty
::AdtKind
,
931 parent_did
: LocalDefId
,
932 ) -> ty
::VariantDef
{
933 let mut seen_fields
: FxHashMap
<Ident
, Span
> = Default
::default();
938 let fid
= tcx
.hir().local_def_id(f
.hir_id
);
939 let dup_span
= seen_fields
.get(&f
.ident
.normalize_to_macros_2_0()).cloned();
940 if let Some(prev_span
) = dup_span
{
941 tcx
.sess
.emit_err(errors
::FieldAlreadyDeclared
{
947 seen_fields
.insert(f
.ident
.normalize_to_macros_2_0(), f
.span
);
950 ty
::FieldDef { did: fid.to_def_id(), ident: f.ident, vis: tcx.visibility(fid) }
953 let recovered
= match def
{
954 hir
::VariantData
::Struct(_
, r
) => *r
,
959 variant_did
.map(LocalDefId
::to_def_id
),
960 ctor_did
.map(LocalDefId
::to_def_id
),
963 CtorKind
::from_hir(def
),
965 parent_did
.to_def_id(),
967 adt_kind
== AdtKind
::Struct
&& tcx
.has_attr(parent_did
.to_def_id(), sym
::non_exhaustive
)
968 || variant_did
.map_or(false, |variant_did
| {
969 tcx
.has_attr(variant_did
.to_def_id(), sym
::non_exhaustive
)
974 fn adt_def(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> &ty
::AdtDef
{
977 let def_id
= def_id
.expect_local();
978 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
979 let item
= match tcx
.hir().get(hir_id
) {
980 Node
::Item(item
) => item
,
984 let repr
= ReprOptions
::new(tcx
, def_id
.to_def_id());
985 let (kind
, variants
) = match item
.kind
{
986 ItemKind
::Enum(ref def
, _
) => {
987 let mut distance_from_explicit
= 0;
992 let variant_did
= Some(tcx
.hir().local_def_id(v
.id
));
994 v
.data
.ctor_hir_id().map(|hir_id
| tcx
.hir().local_def_id(hir_id
));
996 let discr
= if let Some(ref e
) = v
.disr_expr
{
997 distance_from_explicit
= 0;
998 ty
::VariantDiscr
::Explicit(tcx
.hir().local_def_id(e
.hir_id
).to_def_id())
1000 ty
::VariantDiscr
::Relative(distance_from_explicit
)
1002 distance_from_explicit
+= 1;
1017 (AdtKind
::Enum
, variants
)
1019 ItemKind
::Struct(ref def
, _
) => {
1020 let variant_did
= None
::<LocalDefId
>;
1021 let ctor_did
= def
.ctor_hir_id().map(|hir_id
| tcx
.hir().local_def_id(hir_id
));
1023 let variants
= std
::iter
::once(convert_variant(
1028 ty
::VariantDiscr
::Relative(0),
1035 (AdtKind
::Struct
, variants
)
1037 ItemKind
::Union(ref def
, _
) => {
1038 let variant_did
= None
;
1039 let ctor_did
= def
.ctor_hir_id().map(|hir_id
| tcx
.hir().local_def_id(hir_id
));
1041 let variants
= std
::iter
::once(convert_variant(
1046 ty
::VariantDiscr
::Relative(0),
1053 (AdtKind
::Union
, variants
)
1057 tcx
.alloc_adt_def(def_id
.to_def_id(), kind
, variants
, repr
)
1060 /// Ensures that the super-predicates of the trait with a `DefId`
1061 /// of `trait_def_id` are converted and stored. This also ensures that
1062 /// the transitive super-predicates are converted.
1063 fn super_predicates_of(tcx
: TyCtxt
<'_
>, trait_def_id
: DefId
) -> ty
::GenericPredicates
<'_
> {
1064 debug
!("super_predicates(trait_def_id={:?})", trait_def_id
);
1065 tcx
.super_predicates_that_define_assoc_type((trait_def_id
, None
))
1068 /// Ensures that the super-predicates of the trait with a `DefId`
1069 /// of `trait_def_id` are converted and stored. This also ensures that
1070 /// the transitive super-predicates are converted.
1071 fn super_predicates_that_define_assoc_type(
1073 (trait_def_id
, assoc_name
): (DefId
, Option
<Ident
>),
1074 ) -> ty
::GenericPredicates
<'_
> {
1076 "super_predicates_that_define_assoc_type(trait_def_id={:?}, assoc_name={:?})",
1077 trait_def_id
, assoc_name
1079 if trait_def_id
.is_local() {
1080 debug
!("super_predicates_that_define_assoc_type: local trait_def_id={:?}", trait_def_id
);
1081 let trait_hir_id
= tcx
.hir().local_def_id_to_hir_id(trait_def_id
.expect_local());
1083 let item
= match tcx
.hir().get(trait_hir_id
) {
1084 Node
::Item(item
) => item
,
1085 _
=> bug
!("trait_node_id {} is not an item", trait_hir_id
),
1088 let (generics
, bounds
) = match item
.kind
{
1089 hir
::ItemKind
::Trait(.., ref generics
, ref supertraits
, _
) => (generics
, supertraits
),
1090 hir
::ItemKind
::TraitAlias(ref generics
, ref supertraits
) => (generics
, supertraits
),
1091 _
=> span_bug
!(item
.span
, "super_predicates invoked on non-trait"),
1094 let icx
= ItemCtxt
::new(tcx
, trait_def_id
);
1096 // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
1097 let self_param_ty
= tcx
.types
.self_param
;
1098 let superbounds1
= if let Some(assoc_name
) = assoc_name
{
1099 <dyn AstConv
<'_
>>::compute_bounds_that_match_assoc_type(
1108 <dyn AstConv
<'_
>>::compute_bounds(
1117 let superbounds1
= superbounds1
.predicates(tcx
, self_param_ty
);
1119 // Convert any explicit superbounds in the where-clause,
1120 // e.g., `trait Foo where Self: Bar`.
1121 // In the case of trait aliases, however, we include all bounds in the where-clause,
1122 // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
1123 // as one of its "superpredicates".
1124 let is_trait_alias
= tcx
.is_trait_alias(trait_def_id
);
1125 let superbounds2
= icx
.type_parameter_bounds_in_generics(
1129 OnlySelfBounds(!is_trait_alias
),
1133 // Combine the two lists to form the complete set of superbounds:
1134 let superbounds
= &*tcx
.arena
.alloc_from_iter(superbounds1
.into_iter().chain(superbounds2
));
1136 // Now require that immediate supertraits are converted,
1137 // which will, in turn, reach indirect supertraits.
1138 if assoc_name
.is_none() {
1139 // Now require that immediate supertraits are converted,
1140 // which will, in turn, reach indirect supertraits.
1141 for &(pred
, span
) in superbounds
{
1142 debug
!("superbound: {:?}", pred
);
1143 if let ty
::PredicateKind
::Trait(bound
, _
) = pred
.kind().skip_binder() {
1144 tcx
.at(span
).super_predicates_of(bound
.def_id());
1149 ty
::GenericPredicates { parent: None, predicates: superbounds }
1151 // if `assoc_name` is None, then the query should've been redirected to an
1152 // external provider
1153 assert
!(assoc_name
.is_some());
1154 tcx
.super_predicates_of(trait_def_id
)
1158 fn trait_def(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> ty
::TraitDef
{
1159 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
.expect_local());
1160 let item
= tcx
.hir().expect_item(hir_id
);
1162 let (is_auto
, unsafety
) = match item
.kind
{
1163 hir
::ItemKind
::Trait(is_auto
, unsafety
, ..) => (is_auto
== hir
::IsAuto
::Yes
, unsafety
),
1164 hir
::ItemKind
::TraitAlias(..) => (false, hir
::Unsafety
::Normal
),
1165 _
=> span_bug
!(item
.span
, "trait_def_of_item invoked on non-trait"),
1168 let paren_sugar
= tcx
.has_attr(def_id
, sym
::rustc_paren_sugar
);
1169 if paren_sugar
&& !tcx
.features().unboxed_closures
{
1173 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1174 which traits can use parenthetical notation",
1176 .help("add `#![feature(unboxed_closures)]` to the crate attributes to use it")
1180 let is_marker
= tcx
.has_attr(def_id
, sym
::marker
);
1181 let spec_kind
= if tcx
.has_attr(def_id
, sym
::rustc_unsafe_specialization_marker
) {
1182 ty
::trait_def
::TraitSpecializationKind
::Marker
1183 } else if tcx
.has_attr(def_id
, sym
::rustc_specialization_trait
) {
1184 ty
::trait_def
::TraitSpecializationKind
::AlwaysApplicable
1186 ty
::trait_def
::TraitSpecializationKind
::None
1188 let def_path_hash
= tcx
.def_path_hash(def_id
);
1189 ty
::TraitDef
::new(def_id
, unsafety
, paren_sugar
, is_auto
, is_marker
, spec_kind
, def_path_hash
)
1192 fn has_late_bound_regions
<'tcx
>(tcx
: TyCtxt
<'tcx
>, node
: Node
<'tcx
>) -> Option
<Span
> {
1193 struct LateBoundRegionsDetector
<'tcx
> {
1195 outer_index
: ty
::DebruijnIndex
,
1196 has_late_bound_regions
: Option
<Span
>,
1199 impl Visitor
<'tcx
> for LateBoundRegionsDetector
<'tcx
> {
1200 type Map
= intravisit
::ErasedMap
<'tcx
>;
1202 fn nested_visit_map(&mut self) -> NestedVisitorMap
<Self::Map
> {
1203 NestedVisitorMap
::None
1206 fn visit_ty(&mut self, ty
: &'tcx hir
::Ty
<'tcx
>) {
1207 if self.has_late_bound_regions
.is_some() {
1211 hir
::TyKind
::BareFn(..) => {
1212 self.outer_index
.shift_in(1);
1213 intravisit
::walk_ty(self, ty
);
1214 self.outer_index
.shift_out(1);
1216 _
=> intravisit
::walk_ty(self, ty
),
1220 fn visit_poly_trait_ref(
1222 tr
: &'tcx hir
::PolyTraitRef
<'tcx
>,
1223 m
: hir
::TraitBoundModifier
,
1225 if self.has_late_bound_regions
.is_some() {
1228 self.outer_index
.shift_in(1);
1229 intravisit
::walk_poly_trait_ref(self, tr
, m
);
1230 self.outer_index
.shift_out(1);
1233 fn visit_lifetime(&mut self, lt
: &'tcx hir
::Lifetime
) {
1234 if self.has_late_bound_regions
.is_some() {
1238 match self.tcx
.named_region(lt
.hir_id
) {
1239 Some(rl
::Region
::Static
| rl
::Region
::EarlyBound(..)) => {}
1241 rl
::Region
::LateBound(debruijn
, _
, _
) | rl
::Region
::LateBoundAnon(debruijn
, _
),
1242 ) if debruijn
< self.outer_index
=> {}
1244 rl
::Region
::LateBound(..)
1245 | rl
::Region
::LateBoundAnon(..)
1246 | rl
::Region
::Free(..),
1249 self.has_late_bound_regions
= Some(lt
.span
);
1255 fn has_late_bound_regions
<'tcx
>(
1257 generics
: &'tcx hir
::Generics
<'tcx
>,
1258 decl
: &'tcx hir
::FnDecl
<'tcx
>,
1260 let mut visitor
= LateBoundRegionsDetector
{
1262 outer_index
: ty
::INNERMOST
,
1263 has_late_bound_regions
: None
,
1265 for param
in generics
.params
{
1266 if let GenericParamKind
::Lifetime { .. }
= param
.kind
{
1267 if tcx
.is_late_bound(param
.hir_id
) {
1268 return Some(param
.span
);
1272 visitor
.visit_fn_decl(decl
);
1273 visitor
.has_late_bound_regions
1277 Node
::TraitItem(item
) => match item
.kind
{
1278 hir
::TraitItemKind
::Fn(ref sig
, _
) => {
1279 has_late_bound_regions(tcx
, &item
.generics
, &sig
.decl
)
1283 Node
::ImplItem(item
) => match item
.kind
{
1284 hir
::ImplItemKind
::Fn(ref sig
, _
) => {
1285 has_late_bound_regions(tcx
, &item
.generics
, &sig
.decl
)
1289 Node
::ForeignItem(item
) => match item
.kind
{
1290 hir
::ForeignItemKind
::Fn(ref fn_decl
, _
, ref generics
) => {
1291 has_late_bound_regions(tcx
, generics
, fn_decl
)
1295 Node
::Item(item
) => match item
.kind
{
1296 hir
::ItemKind
::Fn(ref sig
, .., ref generics
, _
) => {
1297 has_late_bound_regions(tcx
, generics
, &sig
.decl
)
1305 struct AnonConstInParamListDetector
{
1306 in_param_list
: bool
,
1307 found_anon_const_in_list
: bool
,
1311 impl<'v
> Visitor
<'v
> for AnonConstInParamListDetector
{
1312 type Map
= intravisit
::ErasedMap
<'v
>;
1314 fn nested_visit_map(&mut self) -> NestedVisitorMap
<Self::Map
> {
1315 NestedVisitorMap
::None
1318 fn visit_generic_param(&mut self, p
: &'v hir
::GenericParam
<'v
>) {
1319 let prev
= self.in_param_list
;
1320 self.in_param_list
= true;
1321 intravisit
::walk_generic_param(self, p
);
1322 self.in_param_list
= prev
;
1325 fn visit_anon_const(&mut self, c
: &'v hir
::AnonConst
) {
1326 if self.in_param_list
&& self.ct
== c
.hir_id
{
1327 self.found_anon_const_in_list
= true;
1329 intravisit
::walk_anon_const(self, c
)
1334 fn generics_of(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> ty
::Generics
{
1337 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
.expect_local());
1339 let node
= tcx
.hir().get(hir_id
);
1340 let parent_def_id
= match node
{
1342 | Node
::TraitItem(_
)
1345 | Node
::Field(_
) => {
1346 let parent_id
= tcx
.hir().get_parent_item(hir_id
);
1347 Some(tcx
.hir().local_def_id(parent_id
).to_def_id())
1349 // FIXME(#43408) always enable this once `lazy_normalization` is
1350 // stable enough and does not need a feature gate anymore.
1351 Node
::AnonConst(_
) => {
1352 let parent_id
= tcx
.hir().get_parent_item(hir_id
);
1353 let parent_def_id
= tcx
.hir().local_def_id(parent_id
);
1355 let mut in_param_list
= false;
1356 for (_parent
, node
) in tcx
.hir().parent_iter(hir_id
) {
1357 if let Some(generics
) = node
.generics() {
1358 let mut visitor
= AnonConstInParamListDetector
{
1359 in_param_list
: false,
1360 found_anon_const_in_list
: false,
1364 visitor
.visit_generics(generics
);
1365 in_param_list
= visitor
.found_anon_const_in_list
;
1371 // We do not allow generic parameters in anon consts if we are inside
1374 // This affects both default type bindings, e.g. `struct<T, U = [u8; std::mem::size_of::<T>()]>(T, U)`,
1375 // and the types of const parameters, e.g. `struct V<const N: usize, const M: [u8; N]>();`.
1377 } else if tcx
.lazy_normalization() {
1378 // HACK(eddyb) this provides the correct generics when
1379 // `feature(const_generics)` is enabled, so that const expressions
1380 // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
1382 // Note that we do not supply the parent generics when using
1383 // `min_const_generics`.
1384 Some(parent_def_id
.to_def_id())
1386 let parent_node
= tcx
.hir().get(tcx
.hir().get_parent_node(hir_id
));
1388 // HACK(eddyb) this provides the correct generics for repeat
1389 // expressions' count (i.e. `N` in `[x; N]`), and explicit
1390 // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
1391 // as they shouldn't be able to cause query cycle errors.
1392 Node
::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }
)
1393 | Node
::Variant(Variant { disr_expr: Some(ref constant), .. }
)
1394 if constant
.hir_id
== hir_id
=>
1396 Some(parent_def_id
.to_def_id())
1403 Node
::Expr(&hir
::Expr { kind: hir::ExprKind::Closure(..), .. }
) => {
1404 Some(tcx
.closure_base_def_id(def_id
))
1406 Node
::Item(item
) => match item
.kind
{
1407 ItemKind
::OpaqueTy(hir
::OpaqueTy { impl_trait_fn, .. }
) => {
1408 impl_trait_fn
.or_else(|| {
1409 let parent_id
= tcx
.hir().get_parent_item(hir_id
);
1410 assert
!(parent_id
!= hir_id
&& parent_id
!= CRATE_HIR_ID
);
1411 debug
!("generics_of: parent of opaque ty {:?} is {:?}", def_id
, parent_id
);
1412 // Opaque types are always nested within another item, and
1413 // inherit the generics of the item.
1414 Some(tcx
.hir().local_def_id(parent_id
).to_def_id())
1422 let mut opt_self
= None
;
1423 let mut allow_defaults
= false;
1425 let no_generics
= hir
::Generics
::empty();
1426 let ast_generics
= match node
{
1427 Node
::TraitItem(item
) => &item
.generics
,
1429 Node
::ImplItem(item
) => &item
.generics
,
1431 Node
::Item(item
) => {
1433 ItemKind
::Fn(.., ref generics
, _
)
1434 | ItemKind
::Impl(hir
::Impl { ref generics, .. }
) => generics
,
1436 ItemKind
::TyAlias(_
, ref generics
)
1437 | ItemKind
::Enum(_
, ref generics
)
1438 | ItemKind
::Struct(_
, ref generics
)
1439 | ItemKind
::OpaqueTy(hir
::OpaqueTy { ref generics, .. }
)
1440 | ItemKind
::Union(_
, ref generics
) => {
1441 allow_defaults
= true;
1445 ItemKind
::Trait(_
, _
, ref generics
, ..)
1446 | ItemKind
::TraitAlias(ref generics
, ..) => {
1447 // Add in the self type parameter.
1449 // Something of a hack: use the node id for the trait, also as
1450 // the node id for the Self type parameter.
1451 let param_id
= item
.def_id
;
1453 opt_self
= Some(ty
::GenericParamDef
{
1455 name
: kw
::SelfUpper
,
1456 def_id
: param_id
.to_def_id(),
1457 pure_wrt_drop
: false,
1458 kind
: ty
::GenericParamDefKind
::Type
{
1460 object_lifetime_default
: rl
::Set1
::Empty
,
1465 allow_defaults
= true;
1473 Node
::ForeignItem(item
) => match item
.kind
{
1474 ForeignItemKind
::Static(..) => &no_generics
,
1475 ForeignItemKind
::Fn(_
, _
, ref generics
) => generics
,
1476 ForeignItemKind
::Type
=> &no_generics
,
1482 let has_self
= opt_self
.is_some();
1483 let mut parent_has_self
= false;
1484 let mut own_start
= has_self
as u32;
1485 let parent_count
= parent_def_id
.map_or(0, |def_id
| {
1486 let generics
= tcx
.generics_of(def_id
);
1487 assert_eq
!(has_self
, false);
1488 parent_has_self
= generics
.has_self
;
1489 own_start
= generics
.count() as u32;
1490 generics
.parent_count
+ generics
.params
.len()
1493 let mut params
: Vec
<_
> = Vec
::with_capacity(ast_generics
.params
.len() + has_self
as usize);
1495 if let Some(opt_self
) = opt_self
{
1496 params
.push(opt_self
);
1499 let early_lifetimes
= early_bound_lifetimes_from_generics(tcx
, ast_generics
);
1500 params
.extend(early_lifetimes
.enumerate().map(|(i
, param
)| ty
::GenericParamDef
{
1501 name
: param
.name
.ident().name
,
1502 index
: own_start
+ i
as u32,
1503 def_id
: tcx
.hir().local_def_id(param
.hir_id
).to_def_id(),
1504 pure_wrt_drop
: param
.pure_wrt_drop
,
1505 kind
: ty
::GenericParamDefKind
::Lifetime
,
1508 let object_lifetime_defaults
= tcx
.object_lifetime_defaults(hir_id
);
1510 // Now create the real type and const parameters.
1511 let type_start
= own_start
- has_self
as u32 + params
.len() as u32;
1514 params
.extend(ast_generics
.params
.iter().filter_map(|param
| match param
.kind
{
1515 GenericParamKind
::Lifetime { .. }
=> None
,
1516 GenericParamKind
::Type { ref default, synthetic, .. }
=> {
1517 if !allow_defaults
&& default.is_some() {
1518 if !tcx
.features().default_type_parameter_fallback
{
1519 tcx
.struct_span_lint_hir(
1520 lint
::builtin
::INVALID_TYPE_PARAM_DEFAULT
,
1525 "defaults for type parameters are only allowed in \
1526 `struct`, `enum`, `type`, or `trait` definitions.",
1534 let kind
= ty
::GenericParamDefKind
::Type
{
1535 has_default
: default.is_some(),
1536 object_lifetime_default
: object_lifetime_defaults
1538 .map_or(rl
::Set1
::Empty
, |o
| o
[i
]),
1542 let param_def
= ty
::GenericParamDef
{
1543 index
: type_start
+ i
as u32,
1544 name
: param
.name
.ident().name
,
1545 def_id
: tcx
.hir().local_def_id(param
.hir_id
).to_def_id(),
1546 pure_wrt_drop
: param
.pure_wrt_drop
,
1552 GenericParamKind
::Const { .. }
=> {
1553 let param_def
= ty
::GenericParamDef
{
1554 index
: type_start
+ i
as u32,
1555 name
: param
.name
.ident().name
,
1556 def_id
: tcx
.hir().local_def_id(param
.hir_id
).to_def_id(),
1557 pure_wrt_drop
: param
.pure_wrt_drop
,
1558 kind
: ty
::GenericParamDefKind
::Const
,
1565 // provide junk type parameter defs - the only place that
1566 // cares about anything but the length is instantiation,
1567 // and we don't do that for closures.
1568 if let Node
::Expr(&hir
::Expr { kind: hir::ExprKind::Closure(.., gen), .. }
) = node
{
1569 let dummy_args
= if gen
.is_some() {
1570 &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
1572 &["<closure_kind>", "<closure_signature>", "<upvars>"][..]
1575 params
.extend(dummy_args
.iter().enumerate().map(|(i
, &arg
)| ty
::GenericParamDef
{
1576 index
: type_start
+ i
as u32,
1577 name
: Symbol
::intern(arg
),
1579 pure_wrt_drop
: false,
1580 kind
: ty
::GenericParamDefKind
::Type
{
1582 object_lifetime_default
: rl
::Set1
::Empty
,
1588 let param_def_id_to_index
= params
.iter().map(|param
| (param
.def_id
, param
.index
)).collect();
1591 parent
: parent_def_id
,
1594 param_def_id_to_index
,
1595 has_self
: has_self
|| parent_has_self
,
1596 has_late_bound_regions
: has_late_bound_regions(tcx
, node
),
1600 fn are_suggestable_generic_args(generic_args
: &[hir
::GenericArg
<'_
>]) -> bool
{
1603 .filter_map(|arg
| match arg
{
1604 hir
::GenericArg
::Type(ty
) => Some(ty
),
1607 .any(is_suggestable_infer_ty
)
1610 /// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
1611 /// use inference to provide suggestions for the appropriate type if possible.
1612 fn is_suggestable_infer_ty(ty
: &hir
::Ty
<'_
>) -> bool
{
1616 Slice(ty
) | Array(ty
, _
) => is_suggestable_infer_ty(ty
),
1617 Tup(tys
) => tys
.iter().any(is_suggestable_infer_ty
),
1618 Ptr(mut_ty
) | Rptr(_
, mut_ty
) => is_suggestable_infer_ty(mut_ty
.ty
),
1619 OpaqueDef(_
, generic_args
) => are_suggestable_generic_args(generic_args
),
1620 Path(hir
::QPath
::TypeRelative(ty
, segment
)) => {
1621 is_suggestable_infer_ty(ty
) || are_suggestable_generic_args(segment
.args().args
)
1623 Path(hir
::QPath
::Resolved(ty_opt
, hir
::Path { segments, .. }
)) => {
1624 ty_opt
.map_or(false, is_suggestable_infer_ty
)
1625 || segments
.iter().any(|segment
| are_suggestable_generic_args(segment
.args().args
))
1631 pub fn get_infer_ret_ty(output
: &'hir hir
::FnRetTy
<'hir
>) -> Option
<&'hir hir
::Ty
<'hir
>> {
1632 if let hir
::FnRetTy
::Return(ref ty
) = output
{
1633 if is_suggestable_infer_ty(ty
) {
1640 fn fn_sig(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> ty
::PolyFnSig
<'_
> {
1641 use rustc_hir
::Node
::*;
1644 let def_id
= def_id
.expect_local();
1645 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
1647 let icx
= ItemCtxt
::new(tcx
, def_id
.to_def_id());
1649 match tcx
.hir().get(hir_id
) {
1650 TraitItem(hir
::TraitItem
{
1651 kind
: TraitItemKind
::Fn(sig
, TraitFn
::Provided(_
)),
1656 | ImplItem(hir
::ImplItem { kind: ImplItemKind::Fn(sig, _), ident, generics, .. }
)
1657 | Item(hir
::Item { kind: ItemKind::Fn(sig, generics, _), ident, .. }
) => {
1658 match get_infer_ret_ty(&sig
.decl
.output
) {
1660 let fn_sig
= tcx
.typeck(def_id
).liberated_fn_sigs()[hir_id
];
1661 // Typeck doesn't expect erased regions to be returned from `type_of`.
1662 let fn_sig
= tcx
.fold_regions(fn_sig
, &mut false, |r
, _
| match r
{
1663 ty
::ReErased
=> tcx
.lifetimes
.re_static
,
1667 let mut visitor
= PlaceholderHirTyCollector
::default();
1668 visitor
.visit_ty(ty
);
1669 let mut diag
= bad_placeholder_type(tcx
, visitor
.0);
1670 let ret_ty
= fn_sig
.output();
1671 if ret_ty
!= tcx
.ty_error() {
1672 if !ret_ty
.is_closure() {
1673 let ret_ty_str
= match ret_ty
.kind() {
1674 // Suggest a function pointer return type instead of a unique function definition
1675 // (e.g. `fn() -> i32` instead of `fn() -> i32 { f }`, the latter of which is invalid
1677 ty
::FnDef(..) => ret_ty
.fn_sig(tcx
).to_string(),
1678 _
=> ret_ty
.to_string(),
1680 diag
.span_suggestion(
1682 "replace with the correct return type",
1684 Applicability
::MaybeIncorrect
,
1687 // We're dealing with a closure, so we should suggest using `impl Fn` or trait bounds
1688 // to prevent the user from getting a papercut while trying to use the unique closure
1689 // syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`).
1690 diag
.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
1691 diag
.note("for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html");
1696 ty
::Binder
::bind(fn_sig
)
1698 None
=> <dyn AstConv
<'_
>>::ty_of_fn(
1700 sig
.header
.unsafety
,
1710 TraitItem(hir
::TraitItem
{
1711 kind
: TraitItemKind
::Fn(FnSig { header, decl, span: _ }
, _
),
1715 }) => <dyn AstConv
<'_
>>::ty_of_fn(
1725 ForeignItem(&hir
::ForeignItem
{
1726 kind
: ForeignItemKind
::Fn(ref fn_decl
, _
, _
),
1730 let abi
= tcx
.hir().get_foreign_abi(hir_id
);
1731 compute_sig_of_foreign_fn_decl(tcx
, def_id
.to_def_id(), fn_decl
, abi
, ident
)
1734 Ctor(data
) | Variant(hir
::Variant { data, .. }
) if data
.ctor_hir_id().is_some() => {
1735 let ty
= tcx
.type_of(tcx
.hir().get_parent_did(hir_id
).to_def_id());
1737 data
.fields().iter().map(|f
| tcx
.type_of(tcx
.hir().local_def_id(f
.hir_id
)));
1738 ty
::Binder
::bind(tcx
.mk_fn_sig(
1742 hir
::Unsafety
::Normal
,
1747 Expr(&hir
::Expr { kind: hir::ExprKind::Closure(..), .. }
) => {
1748 // Closure signatures are not like other function
1749 // signatures and cannot be accessed through `fn_sig`. For
1750 // example, a closure signature excludes the `self`
1751 // argument. In any case they are embedded within the
1752 // closure type as part of the `ClosureSubsts`.
1754 // To get the signature of a closure, you should use the
1755 // `sig` method on the `ClosureSubsts`:
1757 // substs.as_closure().sig(def_id, tcx)
1759 "to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
1764 bug
!("unexpected sort of node in fn_sig(): {:?}", x
);
1769 fn impl_trait_ref(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> Option
<ty
::TraitRef
<'_
>> {
1770 let icx
= ItemCtxt
::new(tcx
, def_id
);
1772 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
.expect_local());
1773 match tcx
.hir().expect_item(hir_id
).kind
{
1774 hir
::ItemKind
::Impl(ref impl_
) => impl_
.of_trait
.as_ref().map(|ast_trait_ref
| {
1775 let selfty
= tcx
.type_of(def_id
);
1776 <dyn AstConv
<'_
>>::instantiate_mono_trait_ref(&icx
, ast_trait_ref
, selfty
)
1782 fn impl_polarity(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> ty
::ImplPolarity
{
1783 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
.expect_local());
1784 let is_rustc_reservation
= tcx
.has_attr(def_id
, sym
::rustc_reservation_impl
);
1785 let item
= tcx
.hir().expect_item(hir_id
);
1787 hir
::ItemKind
::Impl(hir
::Impl
{
1788 polarity
: hir
::ImplPolarity
::Negative(span
),
1792 if is_rustc_reservation
{
1793 let span
= span
.to(of_trait
.as_ref().map_or(*span
, |t
| t
.path
.span
));
1794 tcx
.sess
.span_err(span
, "reservation impls can't be negative");
1796 ty
::ImplPolarity
::Negative
1798 hir
::ItemKind
::Impl(hir
::Impl
{
1799 polarity
: hir
::ImplPolarity
::Positive
,
1803 if is_rustc_reservation
{
1804 tcx
.sess
.span_err(item
.span
, "reservation impls can't be inherent");
1806 ty
::ImplPolarity
::Positive
1808 hir
::ItemKind
::Impl(hir
::Impl
{
1809 polarity
: hir
::ImplPolarity
::Positive
,
1813 if is_rustc_reservation
{
1814 ty
::ImplPolarity
::Reservation
1816 ty
::ImplPolarity
::Positive
1819 item
=> bug
!("impl_polarity: {:?} not an impl", item
),
1823 /// Returns the early-bound lifetimes declared in this generics
1824 /// listing. For anything other than fns/methods, this is just all
1825 /// the lifetimes that are declared. For fns or methods, we have to
1826 /// screen out those that do not appear in any where-clauses etc using
1827 /// `resolve_lifetime::early_bound_lifetimes`.
1828 fn early_bound_lifetimes_from_generics
<'a
, 'tcx
: 'a
>(
1830 generics
: &'a hir
::Generics
<'a
>,
1831 ) -> impl Iterator
<Item
= &'a hir
::GenericParam
<'a
>> + Captures
<'tcx
> {
1832 generics
.params
.iter().filter(move |param
| match param
.kind
{
1833 GenericParamKind
::Lifetime { .. }
=> !tcx
.is_late_bound(param
.hir_id
),
1838 /// Returns a list of type predicates for the definition with ID `def_id`, including inferred
1839 /// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus
1840 /// inferred constraints concerning which regions outlive other regions.
1841 fn predicates_defined_on(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> ty
::GenericPredicates
<'_
> {
1842 debug
!("predicates_defined_on({:?})", def_id
);
1843 let mut result
= tcx
.explicit_predicates_of(def_id
);
1844 debug
!("predicates_defined_on: explicit_predicates_of({:?}) = {:?}", def_id
, result
,);
1845 let inferred_outlives
= tcx
.inferred_outlives_of(def_id
);
1846 if !inferred_outlives
.is_empty() {
1848 "predicates_defined_on: inferred_outlives_of({:?}) = {:?}",
1849 def_id
, inferred_outlives
,
1851 if result
.predicates
.is_empty() {
1852 result
.predicates
= inferred_outlives
;
1854 result
.predicates
= tcx
1856 .alloc_from_iter(result
.predicates
.iter().chain(inferred_outlives
).copied());
1860 debug
!("predicates_defined_on({:?}) = {:?}", def_id
, result
);
1864 /// Returns a list of all type predicates (explicit and implicit) for the definition with
1865 /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
1866 /// `Self: Trait` predicates for traits.
1867 fn predicates_of(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> ty
::GenericPredicates
<'_
> {
1868 let mut result
= tcx
.predicates_defined_on(def_id
);
1870 if tcx
.is_trait(def_id
) {
1871 // For traits, add `Self: Trait` predicate. This is
1872 // not part of the predicates that a user writes, but it
1873 // is something that one must prove in order to invoke a
1874 // method or project an associated type.
1876 // In the chalk setup, this predicate is not part of the
1877 // "predicates" for a trait item. But it is useful in
1878 // rustc because if you directly (e.g.) invoke a trait
1879 // method like `Trait::method(...)`, you must naturally
1880 // prove that the trait applies to the types that were
1881 // used, and adding the predicate into this list ensures
1882 // that this is done.
1883 let span
= tcx
.sess
.source_map().guess_head_span(tcx
.def_span(def_id
));
1885 tcx
.arena
.alloc_from_iter(result
.predicates
.iter().copied().chain(std
::iter
::once((
1886 ty
::TraitRef
::identity(tcx
, def_id
).without_const().to_predicate(tcx
),
1890 debug
!("predicates_of(def_id={:?}) = {:?}", def_id
, result
);
1894 /// Returns a list of user-specified type predicates for the definition with ID `def_id`.
1895 /// N.B., this does not include any implied/inferred constraints.
1896 fn gather_explicit_predicates_of(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> ty
::GenericPredicates
<'_
> {
1899 debug
!("explicit_predicates_of(def_id={:?})", def_id
);
1901 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
.expect_local());
1902 let node
= tcx
.hir().get(hir_id
);
1904 let mut is_trait
= None
;
1905 let mut is_default_impl_trait
= None
;
1907 let icx
= ItemCtxt
::new(tcx
, def_id
);
1908 let constness
= icx
.default_constness_for_trait_bounds();
1910 const NO_GENERICS
: &hir
::Generics
<'_
> = &hir
::Generics
::empty();
1912 // We use an `IndexSet` to preserves order of insertion.
1913 // Preserving the order of insertion is important here so as not to break UI tests.
1914 let mut predicates
: FxIndexSet
<(ty
::Predicate
<'_
>, Span
)> = FxIndexSet
::default();
1916 let ast_generics
= match node
{
1917 Node
::TraitItem(item
) => &item
.generics
,
1919 Node
::ImplItem(item
) => &item
.generics
,
1921 Node
::Item(item
) => {
1923 ItemKind
::Impl(ref impl_
) => {
1924 if impl_
.defaultness
.is_default() {
1925 is_default_impl_trait
= tcx
.impl_trait_ref(def_id
);
1929 ItemKind
::Fn(.., ref generics
, _
)
1930 | ItemKind
::TyAlias(_
, ref generics
)
1931 | ItemKind
::Enum(_
, ref generics
)
1932 | ItemKind
::Struct(_
, ref generics
)
1933 | ItemKind
::Union(_
, ref generics
) => generics
,
1935 ItemKind
::Trait(_
, _
, ref generics
, ..) => {
1936 is_trait
= Some(ty
::TraitRef
::identity(tcx
, def_id
));
1939 ItemKind
::TraitAlias(ref generics
, _
) => {
1940 is_trait
= Some(ty
::TraitRef
::identity(tcx
, def_id
));
1943 ItemKind
::OpaqueTy(OpaqueTy
{
1949 if impl_trait_fn
.is_some() {
1950 // return-position impl trait
1952 // We don't inherit predicates from the parent here:
1953 // If we have, say `fn f<'a, T: 'a>() -> impl Sized {}`
1954 // then the return type is `f::<'static, T>::{{opaque}}`.
1956 // If we inherited the predicates of `f` then we would
1957 // require that `T: 'static` to show that the return
1958 // type is well-formed.
1960 // The only way to have something with this opaque type
1961 // is from the return type of the containing function,
1962 // which will ensure that the function's predicates
1964 return ty
::GenericPredicates { parent: None, predicates: &[] }
;
1966 // type-alias impl trait
1975 Node
::ForeignItem(item
) => match item
.kind
{
1976 ForeignItemKind
::Static(..) => NO_GENERICS
,
1977 ForeignItemKind
::Fn(_
, _
, ref generics
) => generics
,
1978 ForeignItemKind
::Type
=> NO_GENERICS
,
1984 let generics
= tcx
.generics_of(def_id
);
1985 let parent_count
= generics
.parent_count
as u32;
1986 let has_own_self
= generics
.has_self
&& parent_count
== 0;
1988 // Below we'll consider the bounds on the type parameters (including `Self`)
1989 // and the explicit where-clauses, but to get the full set of predicates
1990 // on a trait we need to add in the supertrait bounds and bounds found on
1991 // associated types.
1992 if let Some(_trait_ref
) = is_trait
{
1993 predicates
.extend(tcx
.super_predicates_of(def_id
).predicates
.iter().cloned());
1996 // In default impls, we can assume that the self type implements
1997 // the trait. So in:
1999 // default impl Foo for Bar { .. }
2001 // we add a default where clause `Foo: Bar`. We do a similar thing for traits
2002 // (see below). Recall that a default impl is not itself an impl, but rather a
2003 // set of defaults that can be incorporated into another impl.
2004 if let Some(trait_ref
) = is_default_impl_trait
{
2006 trait_ref
.to_poly_trait_ref().without_const().to_predicate(tcx
),
2007 tcx
.def_span(def_id
),
2011 // Collect the region predicates that were declared inline as
2012 // well. In the case of parameters declared on a fn or method, we
2013 // have to be careful to only iterate over early-bound regions.
2014 let mut index
= parent_count
+ has_own_self
as u32;
2015 for param
in early_bound_lifetimes_from_generics(tcx
, ast_generics
) {
2016 let region
= tcx
.mk_region(ty
::ReEarlyBound(ty
::EarlyBoundRegion
{
2017 def_id
: tcx
.hir().local_def_id(param
.hir_id
).to_def_id(),
2019 name
: param
.name
.ident().name
,
2024 GenericParamKind
::Lifetime { .. }
=> {
2025 param
.bounds
.iter().for_each(|bound
| match bound
{
2026 hir
::GenericBound
::Outlives(lt
) => {
2027 let bound
= <dyn AstConv
<'_
>>::ast_region_to_region(&icx
, <
, None
);
2028 let outlives
= ty
::Binder
::bind(ty
::OutlivesPredicate(region
, bound
));
2029 predicates
.insert((outlives
.to_predicate(tcx
), lt
.span
));
2038 // Collect the predicates that were written inline by the user on each
2039 // type parameter (e.g., `<T: Foo>`).
2040 for param
in ast_generics
.params
{
2042 // We already dealt with early bound lifetimes above.
2043 GenericParamKind
::Lifetime { .. }
=> (),
2044 GenericParamKind
::Type { .. }
=> {
2045 let name
= param
.name
.ident().name
;
2046 let param_ty
= ty
::ParamTy
::new(index
, name
).to_ty(tcx
);
2049 let sized
= SizedByDefault
::Yes
;
2050 let bounds
= <dyn AstConv
<'_
>>::compute_bounds(
2057 predicates
.extend(bounds
.predicates(tcx
, param_ty
));
2059 GenericParamKind
::Const { .. }
=> {
2060 // Bounds on const parameters are currently not possible.
2061 debug_assert
!(param
.bounds
.is_empty());
2067 // Add in the bounds that appear in the where-clause.
2068 let where_clause
= &ast_generics
.where_clause
;
2069 for predicate
in where_clause
.predicates
{
2071 hir
::WherePredicate
::BoundPredicate(bound_pred
) => {
2072 let ty
= icx
.to_ty(&bound_pred
.bounded_ty
);
2074 // Keep the type around in a dummy predicate, in case of no bounds.
2075 // That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
2076 // is still checked for WF.
2077 if bound_pred
.bounds
.is_empty() {
2078 if let ty
::Param(_
) = ty
.kind() {
2079 // This is a `where T:`, which can be in the HIR from the
2080 // transformation that moves `?Sized` to `T`'s declaration.
2081 // We can skip the predicate because type parameters are
2082 // trivially WF, but also we *should*, to avoid exposing
2083 // users who never wrote `where Type:,` themselves, to
2084 // compiler/tooling bugs from not handling WF predicates.
2086 let span
= bound_pred
.bounded_ty
.span
;
2087 let re_root_empty
= tcx
.lifetimes
.re_root_empty
;
2088 let predicate
= ty
::Binder
::bind(ty
::PredicateKind
::TypeOutlives(
2089 ty
::OutlivesPredicate(ty
, re_root_empty
),
2091 predicates
.insert((predicate
.to_predicate(tcx
), span
));
2095 for bound
in bound_pred
.bounds
.iter() {
2097 hir
::GenericBound
::Trait(poly_trait_ref
, modifier
) => {
2098 let constness
= match modifier
{
2099 hir
::TraitBoundModifier
::MaybeConst
=> hir
::Constness
::NotConst
,
2100 hir
::TraitBoundModifier
::None
=> constness
,
2101 hir
::TraitBoundModifier
::Maybe
=> bug
!("this wasn't handled"),
2104 let mut bounds
= Bounds
::default();
2105 let _
= <dyn AstConv
<'_
>>::instantiate_poly_trait_ref(
2112 predicates
.extend(bounds
.predicates(tcx
, ty
));
2115 &hir
::GenericBound
::LangItemTrait(lang_item
, span
, hir_id
, args
) => {
2116 let mut bounds
= Bounds
::default();
2117 <dyn AstConv
<'_
>>::instantiate_lang_item_trait_ref(
2126 predicates
.extend(bounds
.predicates(tcx
, ty
));
2129 hir
::GenericBound
::Outlives(lifetime
) => {
2131 <dyn AstConv
<'_
>>::ast_region_to_region(&icx
, lifetime
, None
);
2133 ty
::Binder
::bind(ty
::PredicateKind
::TypeOutlives(
2134 ty
::OutlivesPredicate(ty
, region
),
2144 hir
::WherePredicate
::RegionPredicate(region_pred
) => {
2145 let r1
= <dyn AstConv
<'_
>>::ast_region_to_region(&icx
, ®ion_pred
.lifetime
, None
);
2146 predicates
.extend(region_pred
.bounds
.iter().map(|bound
| {
2147 let (r2
, span
) = match bound
{
2148 hir
::GenericBound
::Outlives(lt
) => {
2149 (<dyn AstConv
<'_
>>::ast_region_to_region(&icx
, lt
, None
), lt
.span
)
2153 let pred
= ty
::PredicateKind
::RegionOutlives(ty
::OutlivesPredicate(r1
, r2
))
2154 .to_predicate(icx
.tcx
);
2160 hir
::WherePredicate
::EqPredicate(..) => {
2166 if tcx
.features().const_evaluatable_checked
{
2167 predicates
.extend(const_evaluatable_predicates_of(tcx
, def_id
.expect_local()));
2170 let mut predicates
: Vec
<_
> = predicates
.into_iter().collect();
2172 // Subtle: before we store the predicates into the tcx, we
2173 // sort them so that predicates like `T: Foo<Item=U>` come
2174 // before uses of `U`. This avoids false ambiguity errors
2175 // in trait checking. See `setup_constraining_predicates`
2177 if let Node
::Item(&Item { kind: ItemKind::Impl { .. }
, .. }) = node
{
2178 let self_ty
= tcx
.type_of(def_id
);
2179 let trait_ref
= tcx
.impl_trait_ref(def_id
);
2180 cgp
::setup_constraining_predicates(
2184 &mut cgp
::parameters_for_impl(self_ty
, trait_ref
),
2188 let result
= ty
::GenericPredicates
{
2189 parent
: generics
.parent
,
2190 predicates
: tcx
.arena
.alloc_from_iter(predicates
),
2192 debug
!("explicit_predicates_of(def_id={:?}) = {:?}", def_id
, result
);
2196 fn const_evaluatable_predicates_of
<'tcx
>(
2199 ) -> FxIndexSet
<(ty
::Predicate
<'tcx
>, Span
)> {
2200 struct ConstCollector
<'tcx
> {
2202 preds
: FxIndexSet
<(ty
::Predicate
<'tcx
>, Span
)>,
2205 impl<'tcx
> intravisit
::Visitor
<'tcx
> for ConstCollector
<'tcx
> {
2206 type Map
= Map
<'tcx
>;
2208 fn nested_visit_map(&mut self) -> intravisit
::NestedVisitorMap
<Self::Map
> {
2209 intravisit
::NestedVisitorMap
::None
2212 fn visit_anon_const(&mut self, c
: &'tcx hir
::AnonConst
) {
2213 let def_id
= self.tcx
.hir().local_def_id(c
.hir_id
);
2214 let ct
= ty
::Const
::from_anon_const(self.tcx
, def_id
);
2215 if let ty
::ConstKind
::Unevaluated(def
, substs
, None
) = ct
.val
{
2216 let span
= self.tcx
.hir().span(c
.hir_id
);
2218 ty
::PredicateKind
::ConstEvaluatable(def
, substs
).to_predicate(self.tcx
),
2225 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
2226 let node
= tcx
.hir().get(hir_id
);
2228 let mut collector
= ConstCollector { tcx, preds: FxIndexSet::default() }
;
2229 if let hir
::Node
::Item(item
) = node
{
2230 if let hir
::ItemKind
::Impl(ref impl_
) = item
.kind
{
2231 if let Some(of_trait
) = &impl_
.of_trait
{
2232 debug
!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id
);
2233 collector
.visit_trait_ref(of_trait
);
2236 debug
!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id
);
2237 collector
.visit_ty(impl_
.self_ty
);
2241 if let Some(generics
) = node
.generics() {
2242 debug
!("const_evaluatable_predicates_of({:?}): visit_generics", def_id
);
2243 collector
.visit_generics(generics
);
2246 if let Some(fn_sig
) = tcx
.hir().fn_sig_by_hir_id(hir_id
) {
2247 debug
!("const_evaluatable_predicates_of({:?}): visit_fn_decl", def_id
);
2248 collector
.visit_fn_decl(fn_sig
.decl
);
2250 debug
!("const_evaluatable_predicates_of({:?}) = {:?}", def_id
, collector
.preds
);
2255 fn trait_explicit_predicates_and_bounds(
2258 ) -> ty
::GenericPredicates
<'_
> {
2259 assert_eq
!(tcx
.def_kind(def_id
), DefKind
::Trait
);
2260 gather_explicit_predicates_of(tcx
, def_id
.to_def_id())
2263 fn explicit_predicates_of(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> ty
::GenericPredicates
<'_
> {
2264 if let DefKind
::Trait
= tcx
.def_kind(def_id
) {
2265 // Remove bounds on associated types from the predicates, they will be
2266 // returned by `explicit_item_bounds`.
2267 let predicates_and_bounds
= tcx
.trait_explicit_predicates_and_bounds(def_id
.expect_local());
2268 let trait_identity_substs
= InternalSubsts
::identity_for_item(tcx
, def_id
);
2270 let is_assoc_item_ty
= |ty
: Ty
<'_
>| {
2271 // For a predicate from a where clause to become a bound on an
2273 // * It must use the identity substs of the item.
2274 // * Since any generic parameters on the item are not in scope,
2275 // this means that the item is not a GAT, and its identity
2276 // substs are the same as the trait's.
2277 // * It must be an associated type for this trait (*not* a
2279 if let ty
::Projection(projection
) = ty
.kind() {
2280 projection
.substs
== trait_identity_substs
2281 && tcx
.associated_item(projection
.item_def_id
).container
.id() == def_id
2287 let predicates
: Vec
<_
> = predicates_and_bounds
2291 .filter(|(pred
, _
)| match pred
.kind().skip_binder() {
2292 ty
::PredicateKind
::Trait(tr
, _
) => !is_assoc_item_ty(tr
.self_ty()),
2293 ty
::PredicateKind
::Projection(proj
) => {
2294 !is_assoc_item_ty(proj
.projection_ty
.self_ty())
2296 ty
::PredicateKind
::TypeOutlives(outlives
) => !is_assoc_item_ty(outlives
.0),
2300 if predicates
.len() == predicates_and_bounds
.predicates
.len() {
2301 predicates_and_bounds
2303 ty
::GenericPredicates
{
2304 parent
: predicates_and_bounds
.parent
,
2305 predicates
: tcx
.arena
.alloc_slice(&predicates
),
2309 gather_explicit_predicates_of(tcx
, def_id
)
2313 fn projection_ty_from_predicates(
2318 // def_id of `N` in `<T as Trait>::N`
2321 ) -> Option
<ty
::ProjectionTy
<'tcx
>> {
2322 let (ty_def_id
, item_def_id
) = key
;
2323 let mut projection_ty
= None
;
2324 for (predicate
, _
) in tcx
.predicates_of(ty_def_id
).predicates
{
2325 if let ty
::PredicateKind
::Projection(projection_predicate
) = predicate
.kind().skip_binder()
2327 if item_def_id
== projection_predicate
.projection_ty
.item_def_id
{
2328 projection_ty
= Some(projection_predicate
.projection_ty
);
2336 /// Converts a specific `GenericBound` from the AST into a set of
2337 /// predicates that apply to the self type. A vector is returned
2338 /// because this can be anywhere from zero predicates (`T: ?Sized` adds no
2339 /// predicates) to one (`T: Foo`) to many (`T: Bar<X = i32>` adds `T: Bar`
2340 /// and `<T as Bar>::X == i32`).
2341 fn predicates_from_bound
<'tcx
>(
2342 astconv
: &dyn AstConv
<'tcx
>,
2344 bound
: &'tcx hir
::GenericBound
<'tcx
>,
2345 constness
: hir
::Constness
,
2346 ) -> Vec
<(ty
::Predicate
<'tcx
>, Span
)> {
2348 hir
::GenericBound
::Trait(ref tr
, modifier
) => {
2349 let constness
= match modifier
{
2350 hir
::TraitBoundModifier
::Maybe
=> return vec
![],
2351 hir
::TraitBoundModifier
::MaybeConst
=> hir
::Constness
::NotConst
,
2352 hir
::TraitBoundModifier
::None
=> constness
,
2355 let mut bounds
= Bounds
::default();
2356 let _
= astconv
.instantiate_poly_trait_ref(tr
, constness
, param_ty
, &mut bounds
);
2357 bounds
.predicates(astconv
.tcx(), param_ty
)
2359 hir
::GenericBound
::LangItemTrait(lang_item
, span
, hir_id
, args
) => {
2360 let mut bounds
= Bounds
::default();
2361 astconv
.instantiate_lang_item_trait_ref(
2369 bounds
.predicates(astconv
.tcx(), param_ty
)
2371 hir
::GenericBound
::Outlives(ref lifetime
) => {
2372 let region
= astconv
.ast_region_to_region(lifetime
, None
);
2373 let pred
= ty
::PredicateKind
::TypeOutlives(ty
::OutlivesPredicate(param_ty
, region
))
2374 .to_predicate(astconv
.tcx());
2375 vec
![(pred
, lifetime
.span
)]
2380 fn compute_sig_of_foreign_fn_decl
<'tcx
>(
2383 decl
: &'tcx hir
::FnDecl
<'tcx
>,
2386 ) -> ty
::PolyFnSig
<'tcx
> {
2387 let unsafety
= if abi
== abi
::Abi
::RustIntrinsic
{
2388 intrinsic_operation_unsafety(tcx
.item_name(def_id
))
2390 hir
::Unsafety
::Unsafe
2392 let fty
= <dyn AstConv
<'_
>>::ty_of_fn(
2393 &ItemCtxt
::new(tcx
, def_id
),
2397 &hir
::Generics
::empty(),
2402 // Feature gate SIMD types in FFI, since I am not sure that the
2403 // ABIs are handled at all correctly. -huonw
2404 if abi
!= abi
::Abi
::RustIntrinsic
2405 && abi
!= abi
::Abi
::PlatformIntrinsic
2406 && !tcx
.features().simd_ffi
2408 let check
= |ast_ty
: &hir
::Ty
<'_
>, ty
: Ty
<'_
>| {
2413 .span_to_snippet(ast_ty
.span
)
2414 .map_or_else(|_
| String
::new(), |s
| format
!(" `{}`", s
));
2419 "use of SIMD type{} in FFI is highly experimental and \
2420 may result in invalid code",
2424 .help("add `#![feature(simd_ffi)]` to the crate attributes to enable")
2428 for (input
, ty
) in decl
.inputs
.iter().zip(fty
.inputs().skip_binder()) {
2431 if let hir
::FnRetTy
::Return(ref ty
) = decl
.output
{
2432 check(&ty
, fty
.output().skip_binder())
2439 fn is_foreign_item(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> bool
{
2440 match tcx
.hir().get_if_local(def_id
) {
2441 Some(Node
::ForeignItem(..)) => true,
2443 _
=> bug
!("is_foreign_item applied to non-local def-id {:?}", def_id
),
2447 fn static_mutability(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> Option
<hir
::Mutability
> {
2448 match tcx
.hir().get_if_local(def_id
) {
2450 Node
::Item(&hir
::Item { kind: hir::ItemKind::Static(_, mutbl, _), .. }
)
2451 | Node
::ForeignItem(&hir
::ForeignItem
{
2452 kind
: hir
::ForeignItemKind
::Static(_
, mutbl
),
2457 _
=> bug
!("static_mutability applied to non-local def-id {:?}", def_id
),
2461 fn generator_kind(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> Option
<hir
::GeneratorKind
> {
2462 match tcx
.hir().get_if_local(def_id
) {
2463 Some(Node
::Expr(&rustc_hir
::Expr
{
2464 kind
: rustc_hir
::ExprKind
::Closure(_
, _
, body_id
, _
, _
),
2466 })) => tcx
.hir().body(body_id
).generator_kind(),
2468 _
=> bug
!("generator_kind applied to non-local def-id {:?}", def_id
),
2472 fn from_target_feature(
2475 attr
: &ast
::Attribute
,
2476 supported_target_features
: &FxHashMap
<String
, Option
<Symbol
>>,
2477 target_features
: &mut Vec
<Symbol
>,
2479 let list
= match attr
.meta_item_list() {
2483 let bad_item
= |span
| {
2484 let msg
= "malformed `target_feature` attribute input";
2485 let code
= "enable = \"..\"".to_owned();
2487 .struct_span_err(span
, &msg
)
2488 .span_suggestion(span
, "must be of the form", code
, Applicability
::HasPlaceholders
)
2491 let rust_features
= tcx
.features();
2493 // Only `enable = ...` is accepted in the meta-item list.
2494 if !item
.has_name(sym
::enable
) {
2495 bad_item(item
.span());
2499 // Must be of the form `enable = "..."` (a string).
2500 let value
= match item
.value_str() {
2501 Some(value
) => value
,
2503 bad_item(item
.span());
2508 // We allow comma separation to enable multiple features.
2509 target_features
.extend(value
.as_str().split('
,'
).filter_map(|feature
| {
2510 let feature_gate
= match supported_target_features
.get(feature
) {
2514 format
!("the feature named `{}` is not valid for this target", feature
);
2515 let mut err
= tcx
.sess
.struct_span_err(item
.span(), &msg
);
2518 format
!("`{}` is not valid for this target", feature
),
2520 if let Some(stripped
) = feature
.strip_prefix('
+'
) {
2521 let valid
= supported_target_features
.contains_key(stripped
);
2523 err
.help("consider removing the leading `+` in the feature name");
2531 // Only allow features whose feature gates have been enabled.
2532 let allowed
= match feature_gate
.as_ref().copied() {
2533 Some(sym
::arm_target_feature
) => rust_features
.arm_target_feature
,
2534 Some(sym
::aarch64_target_feature
) => rust_features
.aarch64_target_feature
,
2535 Some(sym
::hexagon_target_feature
) => rust_features
.hexagon_target_feature
,
2536 Some(sym
::powerpc_target_feature
) => rust_features
.powerpc_target_feature
,
2537 Some(sym
::mips_target_feature
) => rust_features
.mips_target_feature
,
2538 Some(sym
::riscv_target_feature
) => rust_features
.riscv_target_feature
,
2539 Some(sym
::avx512_target_feature
) => rust_features
.avx512_target_feature
,
2540 Some(sym
::sse4a_target_feature
) => rust_features
.sse4a_target_feature
,
2541 Some(sym
::tbm_target_feature
) => rust_features
.tbm_target_feature
,
2542 Some(sym
::wasm_target_feature
) => rust_features
.wasm_target_feature
,
2543 Some(sym
::cmpxchg16b_target_feature
) => rust_features
.cmpxchg16b_target_feature
,
2544 Some(sym
::adx_target_feature
) => rust_features
.adx_target_feature
,
2545 Some(sym
::movbe_target_feature
) => rust_features
.movbe_target_feature
,
2546 Some(sym
::rtm_target_feature
) => rust_features
.rtm_target_feature
,
2547 Some(sym
::f16c_target_feature
) => rust_features
.f16c_target_feature
,
2548 Some(sym
::ermsb_target_feature
) => rust_features
.ermsb_target_feature
,
2549 Some(name
) => bug
!("unknown target feature gate {}", name
),
2552 if !allowed
&& id
.is_local() {
2554 &tcx
.sess
.parse_sess
,
2555 feature_gate
.unwrap(),
2557 &format
!("the target feature `{}` is currently unstable", feature
),
2561 Some(Symbol
::intern(feature
))
2566 fn linkage_by_name(tcx
: TyCtxt
<'_
>, def_id
: DefId
, name
: &str) -> Linkage
{
2567 use rustc_middle
::mir
::mono
::Linkage
::*;
2569 // Use the names from src/llvm/docs/LangRef.rst here. Most types are only
2570 // applicable to variable declarations and may not really make sense for
2571 // Rust code in the first place but allow them anyway and trust that the
2572 // user knows what s/he's doing. Who knows, unanticipated use cases may pop
2573 // up in the future.
2575 // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
2576 // and don't have to be, LLVM treats them as no-ops.
2578 "appending" => Appending
,
2579 "available_externally" => AvailableExternally
,
2581 "extern_weak" => ExternalWeak
,
2582 "external" => External
,
2583 "internal" => Internal
,
2584 "linkonce" => LinkOnceAny
,
2585 "linkonce_odr" => LinkOnceODR
,
2586 "private" => Private
,
2588 "weak_odr" => WeakODR
,
2590 let span
= tcx
.hir().span_if_local(def_id
);
2591 if let Some(span
) = span
{
2592 tcx
.sess
.span_fatal(span
, "invalid linkage specified")
2594 tcx
.sess
.fatal(&format
!("invalid linkage specified: {}", name
))
2600 fn codegen_fn_attrs(tcx
: TyCtxt
<'_
>, id
: DefId
) -> CodegenFnAttrs
{
2601 let attrs
= tcx
.get_attrs(id
);
2603 let mut codegen_fn_attrs
= CodegenFnAttrs
::new();
2604 if should_inherit_track_caller(tcx
, id
) {
2605 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::TRACK_CALLER
;
2608 let supported_target_features
= tcx
.supported_target_features(LOCAL_CRATE
);
2610 let mut inline_span
= None
;
2611 let mut link_ordinal_span
= None
;
2612 let mut no_sanitize_span
= None
;
2613 for attr
in attrs
.iter() {
2614 if tcx
.sess
.check_name(attr
, sym
::cold
) {
2615 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::COLD
;
2616 } else if tcx
.sess
.check_name(attr
, sym
::rustc_allocator
) {
2617 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::ALLOCATOR
;
2618 } else if tcx
.sess
.check_name(attr
, sym
::unwind
) {
2619 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::UNWIND
;
2620 } else if tcx
.sess
.check_name(attr
, sym
::ffi_returns_twice
) {
2621 if tcx
.is_foreign_item(id
) {
2622 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::FFI_RETURNS_TWICE
;
2624 // `#[ffi_returns_twice]` is only allowed `extern fn`s.
2629 "`#[ffi_returns_twice]` may only be used on foreign functions"
2633 } else if tcx
.sess
.check_name(attr
, sym
::ffi_pure
) {
2634 if tcx
.is_foreign_item(id
) {
2635 if attrs
.iter().any(|a
| tcx
.sess
.check_name(a
, sym
::ffi_const
)) {
2636 // `#[ffi_const]` functions cannot be `#[ffi_pure]`
2641 "`#[ffi_const]` function cannot be `#[ffi_pure]`"
2645 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::FFI_PURE
;
2648 // `#[ffi_pure]` is only allowed on foreign functions
2653 "`#[ffi_pure]` may only be used on foreign functions"
2657 } else if tcx
.sess
.check_name(attr
, sym
::ffi_const
) {
2658 if tcx
.is_foreign_item(id
) {
2659 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::FFI_CONST
;
2661 // `#[ffi_const]` is only allowed on foreign functions
2666 "`#[ffi_const]` may only be used on foreign functions"
2670 } else if tcx
.sess
.check_name(attr
, sym
::rustc_allocator_nounwind
) {
2671 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::RUSTC_ALLOCATOR_NOUNWIND
;
2672 } else if tcx
.sess
.check_name(attr
, sym
::naked
) {
2673 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::NAKED
;
2674 } else if tcx
.sess
.check_name(attr
, sym
::no_mangle
) {
2675 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::NO_MANGLE
;
2676 } else if tcx
.sess
.check_name(attr
, sym
::rustc_std_internal_symbol
) {
2677 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::RUSTC_STD_INTERNAL_SYMBOL
;
2678 } else if tcx
.sess
.check_name(attr
, sym
::used
) {
2679 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::USED
;
2680 } else if tcx
.sess
.check_name(attr
, sym
::cmse_nonsecure_entry
) {
2681 if !matches
!(tcx
.fn_sig(id
).abi(), abi
::Abi
::C { .. }
) {
2686 "`#[cmse_nonsecure_entry]` requires C ABI"
2690 if !tcx
.sess
.target
.llvm_target
.contains("thumbv8m") {
2691 struct_span_err
!(tcx
.sess
, attr
.span
, E0775
, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension")
2694 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::CMSE_NONSECURE_ENTRY
;
2695 } else if tcx
.sess
.check_name(attr
, sym
::thread_local
) {
2696 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::THREAD_LOCAL
;
2697 } else if tcx
.sess
.check_name(attr
, sym
::track_caller
) {
2698 if tcx
.is_closure(id
) || tcx
.fn_sig(id
).abi() != abi
::Abi
::Rust
{
2699 struct_span_err
!(tcx
.sess
, attr
.span
, E0737
, "`#[track_caller]` requires Rust ABI")
2702 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::TRACK_CALLER
;
2703 } else if tcx
.sess
.check_name(attr
, sym
::export_name
) {
2704 if let Some(s
) = attr
.value_str() {
2705 if s
.as_str().contains('
\0'
) {
2706 // `#[export_name = ...]` will be converted to a null-terminated string,
2707 // so it may not contain any null characters.
2712 "`export_name` may not contain null characters"
2716 codegen_fn_attrs
.export_name
= Some(s
);
2718 } else if tcx
.sess
.check_name(attr
, sym
::target_feature
) {
2719 if !tcx
.is_closure(id
) && tcx
.fn_sig(id
).unsafety() == hir
::Unsafety
::Normal
{
2720 if !tcx
.features().target_feature_11
{
2721 let mut err
= feature_err(
2722 &tcx
.sess
.parse_sess
,
2723 sym
::target_feature_11
,
2725 "`#[target_feature(..)]` can only be applied to `unsafe` functions",
2727 err
.span_label(tcx
.def_span(id
), "not an `unsafe` function");
2729 } else if let Some(local_id
) = id
.as_local() {
2730 check_target_feature_trait_unsafe(tcx
, local_id
, attr
.span
);
2733 from_target_feature(
2737 &supported_target_features
,
2738 &mut codegen_fn_attrs
.target_features
,
2740 } else if tcx
.sess
.check_name(attr
, sym
::linkage
) {
2741 if let Some(val
) = attr
.value_str() {
2742 codegen_fn_attrs
.linkage
= Some(linkage_by_name(tcx
, id
, &val
.as_str()));
2744 } else if tcx
.sess
.check_name(attr
, sym
::link_section
) {
2745 if let Some(val
) = attr
.value_str() {
2746 if val
.as_str().bytes().any(|b
| b
== 0) {
2748 "illegal null byte in link_section \
2752 tcx
.sess
.span_err(attr
.span
, &msg
);
2754 codegen_fn_attrs
.link_section
= Some(val
);
2757 } else if tcx
.sess
.check_name(attr
, sym
::link_name
) {
2758 codegen_fn_attrs
.link_name
= attr
.value_str();
2759 } else if tcx
.sess
.check_name(attr
, sym
::link_ordinal
) {
2760 link_ordinal_span
= Some(attr
.span
);
2761 if let ordinal @
Some(_
) = check_link_ordinal(tcx
, attr
) {
2762 codegen_fn_attrs
.link_ordinal
= ordinal
;
2764 } else if tcx
.sess
.check_name(attr
, sym
::no_sanitize
) {
2765 no_sanitize_span
= Some(attr
.span
);
2766 if let Some(list
) = attr
.meta_item_list() {
2767 for item
in list
.iter() {
2768 if item
.has_name(sym
::address
) {
2769 codegen_fn_attrs
.no_sanitize
|= SanitizerSet
::ADDRESS
;
2770 } else if item
.has_name(sym
::memory
) {
2771 codegen_fn_attrs
.no_sanitize
|= SanitizerSet
::MEMORY
;
2772 } else if item
.has_name(sym
::thread
) {
2773 codegen_fn_attrs
.no_sanitize
|= SanitizerSet
::THREAD
;
2774 } else if item
.has_name(sym
::hwaddress
) {
2775 codegen_fn_attrs
.no_sanitize
|= SanitizerSet
::HWADDRESS
;
2778 .struct_span_err(item
.span(), "invalid argument for `no_sanitize`")
2779 .note("expected one of: `address`, `hwaddress`, `memory` or `thread`")
2784 } else if tcx
.sess
.check_name(attr
, sym
::instruction_set
) {
2785 codegen_fn_attrs
.instruction_set
= match attr
.meta().map(|i
| i
.kind
) {
2786 Some(MetaItemKind
::List(ref items
)) => match items
.as_slice() {
2787 [NestedMetaItem
::MetaItem(set
)] => {
2789 set
.path
.segments
.iter().map(|x
| x
.ident
.name
).collect
::<Vec
<_
>>();
2790 match segments
.as_slice() {
2791 [sym
::arm
, sym
::a32
] | [sym
::arm
, sym
::t32
] => {
2792 if !tcx
.sess
.target
.has_thumb_interworking
{
2794 tcx
.sess
.diagnostic(),
2797 "target does not support `#[instruction_set]`"
2801 } else if segments
[1] == sym
::a32
{
2802 Some(InstructionSetAttr
::ArmA32
)
2803 } else if segments
[1] == sym
::t32
{
2804 Some(InstructionSetAttr
::ArmT32
)
2811 tcx
.sess
.diagnostic(),
2814 "invalid instruction set specified",
2823 tcx
.sess
.diagnostic(),
2826 "`#[instruction_set]` requires an argument"
2833 tcx
.sess
.diagnostic(),
2836 "cannot specify more than one instruction set"
2844 tcx
.sess
.diagnostic(),
2847 "must specify an instruction set"
2856 codegen_fn_attrs
.inline
= attrs
.iter().fold(InlineAttr
::None
, |ia
, attr
| {
2857 if !attr
.has_name(sym
::inline
) {
2860 match attr
.meta().map(|i
| i
.kind
) {
2861 Some(MetaItemKind
::Word
) => {
2862 tcx
.sess
.mark_attr_used(attr
);
2865 Some(MetaItemKind
::List(ref items
)) => {
2866 tcx
.sess
.mark_attr_used(attr
);
2867 inline_span
= Some(attr
.span
);
2868 if items
.len() != 1 {
2870 tcx
.sess
.diagnostic(),
2873 "expected one argument"
2877 } else if list_contains_name(&items
[..], sym
::always
) {
2879 } else if list_contains_name(&items
[..], sym
::never
) {
2883 tcx
.sess
.diagnostic(),
2893 Some(MetaItemKind
::NameValue(_
)) => ia
,
2898 codegen_fn_attrs
.optimize
= attrs
.iter().fold(OptimizeAttr
::None
, |ia
, attr
| {
2899 if !attr
.has_name(sym
::optimize
) {
2902 let err
= |sp
, s
| struct_span_err
!(tcx
.sess
.diagnostic(), sp
, E0722
, "{}", s
).emit();
2903 match attr
.meta().map(|i
| i
.kind
) {
2904 Some(MetaItemKind
::Word
) => {
2905 err(attr
.span
, "expected one argument");
2908 Some(MetaItemKind
::List(ref items
)) => {
2909 tcx
.sess
.mark_attr_used(attr
);
2910 inline_span
= Some(attr
.span
);
2911 if items
.len() != 1 {
2912 err(attr
.span
, "expected one argument");
2914 } else if list_contains_name(&items
[..], sym
::size
) {
2916 } else if list_contains_name(&items
[..], sym
::speed
) {
2919 err(items
[0].span(), "invalid argument");
2923 Some(MetaItemKind
::NameValue(_
)) => ia
,
2928 // #73631: closures inherit `#[target_feature]` annotations
2929 if tcx
.features().target_feature_11
&& tcx
.is_closure(id
) {
2930 let owner_id
= tcx
.parent(id
).expect("closure should have a parent");
2933 .extend(tcx
.codegen_fn_attrs(owner_id
).target_features
.iter().copied())
2936 // If a function uses #[target_feature] it can't be inlined into general
2937 // purpose functions as they wouldn't have the right target features
2938 // enabled. For that reason we also forbid #[inline(always)] as it can't be
2940 if !codegen_fn_attrs
.target_features
.is_empty() {
2941 if codegen_fn_attrs
.inline
== InlineAttr
::Always
{
2942 if let Some(span
) = inline_span
{
2945 "cannot use `#[inline(always)]` with \
2946 `#[target_feature]`",
2952 if !codegen_fn_attrs
.no_sanitize
.is_empty() {
2953 if codegen_fn_attrs
.inline
== InlineAttr
::Always
{
2954 if let (Some(no_sanitize_span
), Some(inline_span
)) = (no_sanitize_span
, inline_span
) {
2955 let hir_id
= tcx
.hir().local_def_id_to_hir_id(id
.expect_local());
2956 tcx
.struct_span_lint_hir(
2957 lint
::builtin
::INLINE_NO_SANITIZE
,
2961 lint
.build("`no_sanitize` will have no effect after inlining")
2962 .span_note(inline_span
, "inlining requested here")
2970 // Weak lang items have the same semantics as "std internal" symbols in the
2971 // sense that they're preserved through all our LTO passes and only
2972 // strippable by the linker.
2974 // Additionally weak lang items have predetermined symbol names.
2975 if tcx
.is_weak_lang_item(id
) {
2976 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::RUSTC_STD_INTERNAL_SYMBOL
;
2978 let check_name
= |attr
, sym
| tcx
.sess
.check_name(attr
, sym
);
2979 if let Some(name
) = weak_lang_items
::link_name(check_name
, &attrs
) {
2980 codegen_fn_attrs
.export_name
= Some(name
);
2981 codegen_fn_attrs
.link_name
= Some(name
);
2983 check_link_name_xor_ordinal(tcx
, &codegen_fn_attrs
, link_ordinal_span
);
2985 // Internal symbols to the standard library all have no_mangle semantics in
2986 // that they have defined symbol names present in the function name. This
2987 // also applies to weak symbols where they all have known symbol names.
2988 if codegen_fn_attrs
.flags
.contains(CodegenFnAttrFlags
::RUSTC_STD_INTERNAL_SYMBOL
) {
2989 codegen_fn_attrs
.flags
|= CodegenFnAttrFlags
::NO_MANGLE
;
2995 /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller
2996 /// applied to the method prototype.
2997 fn should_inherit_track_caller(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> bool
{
2998 if let Some(impl_item
) = tcx
.opt_associated_item(def_id
) {
2999 if let ty
::AssocItemContainer
::ImplContainer(impl_def_id
) = impl_item
.container
{
3000 if let Some(trait_def_id
) = tcx
.trait_id_of_impl(impl_def_id
) {
3001 if let Some(trait_item
) = tcx
3002 .associated_items(trait_def_id
)
3003 .filter_by_name_unhygienic(impl_item
.ident
.name
)
3004 .find(move |trait_item
| {
3005 trait_item
.kind
== ty
::AssocKind
::Fn
3006 && tcx
.hygienic_eq(impl_item
.ident
, trait_item
.ident
, trait_def_id
)
3010 .codegen_fn_attrs(trait_item
.def_id
)
3012 .intersects(CodegenFnAttrFlags
::TRACK_CALLER
);
3021 fn check_link_ordinal(tcx
: TyCtxt
<'_
>, attr
: &ast
::Attribute
) -> Option
<usize> {
3022 use rustc_ast
::{Lit, LitIntType, LitKind}
;
3023 let meta_item_list
= attr
.meta_item_list();
3024 let meta_item_list
: Option
<&[ast
::NestedMetaItem
]> = meta_item_list
.as_ref().map(Vec
::as_ref
);
3025 let sole_meta_list
= match meta_item_list
{
3026 Some([item
]) => item
.literal(),
3029 if let Some(Lit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }
) = sole_meta_list
{
3030 if *ordinal
<= usize::MAX
as u128
{
3031 Some(*ordinal
as usize)
3033 let msg
= format
!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal
);
3035 .struct_span_err(attr
.span
, &msg
)
3036 .note("the value may not exceed `usize::MAX`")
3042 .struct_span_err(attr
.span
, "illegal ordinal format in `link_ordinal`")
3043 .note("an unsuffixed integer value, e.g., `1`, is expected")
3049 fn check_link_name_xor_ordinal(
3051 codegen_fn_attrs
: &CodegenFnAttrs
,
3052 inline_span
: Option
<Span
>,
3054 if codegen_fn_attrs
.link_name
.is_none() || codegen_fn_attrs
.link_ordinal
.is_none() {
3057 let msg
= "cannot use `#[link_name]` with `#[link_ordinal]`";
3058 if let Some(span
) = inline_span
{
3059 tcx
.sess
.span_err(span
, msg
);
3065 /// Checks the function annotated with `#[target_feature]` is not a safe
3066 /// trait method implementation, reporting an error if it is.
3067 fn check_target_feature_trait_unsafe(tcx
: TyCtxt
<'_
>, id
: LocalDefId
, attr_span
: Span
) {
3068 let hir_id
= tcx
.hir().local_def_id_to_hir_id(id
);
3069 let node
= tcx
.hir().get(hir_id
);
3070 if let Node
::ImplItem(hir
::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }
) = node
{
3071 let parent_id
= tcx
.hir().get_parent_item(hir_id
);
3072 let parent_item
= tcx
.hir().expect_item(parent_id
);
3073 if let hir
::ItemKind
::Impl(hir
::Impl { of_trait: Some(_), .. }
) = parent_item
.kind
{
3077 "`#[target_feature(..)]` cannot be applied to safe trait method",
3079 .span_label(attr_span
, "cannot be applied to safe trait method")
3080 .span_label(tcx
.def_span(id
), "not an `unsafe` function")