]>
Commit | Line | Data |
---|---|---|
064997fb FG |
1 | //! Collects lang items: items marked with `#[lang = "..."]` attribute. |
2 | //! | |
3 | //! This attribute to tell the compiler about semi built-in std library | |
4 | //! features, such as Fn family of traits. | |
5 | use std::sync::Arc; | |
6 | ||
7 | use rustc_hash::FxHashMap; | |
8 | use syntax::SmolStr; | |
9 | ||
10 | use crate::{ | |
9ffffee4 FG |
11 | db::DefDatabase, AdtId, AssocItemId, AttrDefId, CrateId, EnumId, EnumVariantId, FunctionId, |
12 | ImplId, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, UnionId, | |
064997fb FG |
13 | }; |
14 | ||
15 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | |
16 | pub enum LangItemTarget { | |
17 | EnumId(EnumId), | |
9ffffee4 FG |
18 | Function(FunctionId), |
19 | ImplDef(ImplId), | |
20 | Static(StaticId), | |
21 | Struct(StructId), | |
22 | Union(UnionId), | |
23 | TypeAlias(TypeAliasId), | |
24 | Trait(TraitId), | |
25 | EnumVariant(EnumVariantId), | |
064997fb FG |
26 | } |
27 | ||
28 | impl LangItemTarget { | |
29 | pub fn as_enum(self) -> Option<EnumId> { | |
30 | match self { | |
31 | LangItemTarget::EnumId(id) => Some(id), | |
32 | _ => None, | |
33 | } | |
34 | } | |
35 | ||
36 | pub fn as_function(self) -> Option<FunctionId> { | |
37 | match self { | |
9ffffee4 | 38 | LangItemTarget::Function(id) => Some(id), |
064997fb FG |
39 | _ => None, |
40 | } | |
41 | } | |
42 | ||
43 | pub fn as_impl_def(self) -> Option<ImplId> { | |
44 | match self { | |
9ffffee4 | 45 | LangItemTarget::ImplDef(id) => Some(id), |
064997fb FG |
46 | _ => None, |
47 | } | |
48 | } | |
49 | ||
50 | pub fn as_static(self) -> Option<StaticId> { | |
51 | match self { | |
9ffffee4 | 52 | LangItemTarget::Static(id) => Some(id), |
064997fb FG |
53 | _ => None, |
54 | } | |
55 | } | |
56 | ||
57 | pub fn as_struct(self) -> Option<StructId> { | |
58 | match self { | |
9ffffee4 | 59 | LangItemTarget::Struct(id) => Some(id), |
064997fb FG |
60 | _ => None, |
61 | } | |
62 | } | |
63 | ||
64 | pub fn as_trait(self) -> Option<TraitId> { | |
65 | match self { | |
9ffffee4 | 66 | LangItemTarget::Trait(id) => Some(id), |
064997fb FG |
67 | _ => None, |
68 | } | |
69 | } | |
70 | ||
71 | pub fn as_enum_variant(self) -> Option<EnumVariantId> { | |
72 | match self { | |
9ffffee4 | 73 | LangItemTarget::EnumVariant(id) => Some(id), |
064997fb FG |
74 | _ => None, |
75 | } | |
76 | } | |
77 | } | |
78 | ||
79 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | |
80 | pub struct LangItems { | |
9ffffee4 | 81 | items: FxHashMap<LangItem, LangItemTarget>, |
064997fb FG |
82 | } |
83 | ||
84 | impl LangItems { | |
9ffffee4 FG |
85 | pub fn target(&self, item: LangItem) -> Option<LangItemTarget> { |
86 | self.items.get(&item).copied() | |
064997fb FG |
87 | } |
88 | ||
89 | /// Salsa query. This will look for lang items in a specific crate. | |
90 | pub(crate) fn crate_lang_items_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<LangItems> { | |
91 | let _p = profile::span("crate_lang_items_query"); | |
92 | ||
93 | let mut lang_items = LangItems::default(); | |
94 | ||
95 | let crate_def_map = db.crate_def_map(krate); | |
96 | ||
97 | for (_, module_data) in crate_def_map.modules() { | |
98 | for impl_def in module_data.scope.impls() { | |
9ffffee4 FG |
99 | lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDef); |
100 | for assoc in db.impl_data(impl_def).items.iter().copied() { | |
101 | match assoc { | |
102 | AssocItemId::FunctionId(f) => { | |
103 | lang_items.collect_lang_item(db, f, LangItemTarget::Function) | |
104 | } | |
105 | AssocItemId::TypeAliasId(t) => { | |
106 | lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias) | |
107 | } | |
108 | AssocItemId::ConstId(_) => (), | |
109 | } | |
110 | } | |
064997fb FG |
111 | } |
112 | ||
113 | for def in module_data.scope.declarations() { | |
114 | match def { | |
115 | ModuleDefId::TraitId(trait_) => { | |
9ffffee4 | 116 | lang_items.collect_lang_item(db, trait_, LangItemTarget::Trait); |
064997fb | 117 | db.trait_data(trait_).items.iter().for_each(|&(_, assoc_id)| { |
9ffffee4 FG |
118 | if let AssocItemId::FunctionId(f) = assoc_id { |
119 | lang_items.collect_lang_item(db, f, LangItemTarget::Function); | |
064997fb FG |
120 | } |
121 | }); | |
122 | } | |
123 | ModuleDefId::AdtId(AdtId::EnumId(e)) => { | |
124 | lang_items.collect_lang_item(db, e, LangItemTarget::EnumId); | |
125 | db.enum_data(e).variants.iter().for_each(|(local_id, _)| { | |
126 | lang_items.collect_lang_item( | |
127 | db, | |
128 | EnumVariantId { parent: e, local_id }, | |
9ffffee4 | 129 | LangItemTarget::EnumVariant, |
064997fb FG |
130 | ); |
131 | }); | |
132 | } | |
133 | ModuleDefId::AdtId(AdtId::StructId(s)) => { | |
9ffffee4 FG |
134 | lang_items.collect_lang_item(db, s, LangItemTarget::Struct); |
135 | } | |
136 | ModuleDefId::AdtId(AdtId::UnionId(u)) => { | |
137 | lang_items.collect_lang_item(db, u, LangItemTarget::Union); | |
064997fb FG |
138 | } |
139 | ModuleDefId::FunctionId(f) => { | |
9ffffee4 | 140 | lang_items.collect_lang_item(db, f, LangItemTarget::Function); |
064997fb FG |
141 | } |
142 | ModuleDefId::StaticId(s) => { | |
9ffffee4 FG |
143 | lang_items.collect_lang_item(db, s, LangItemTarget::Static); |
144 | } | |
145 | ModuleDefId::TypeAliasId(t) => { | |
146 | lang_items.collect_lang_item(db, t, LangItemTarget::TypeAlias); | |
064997fb FG |
147 | } |
148 | _ => {} | |
149 | } | |
150 | } | |
151 | } | |
152 | ||
153 | Arc::new(lang_items) | |
154 | } | |
155 | ||
156 | /// Salsa query. Look for a lang item, starting from the specified crate and recursively | |
157 | /// traversing its dependencies. | |
158 | pub(crate) fn lang_item_query( | |
159 | db: &dyn DefDatabase, | |
160 | start_crate: CrateId, | |
9ffffee4 | 161 | item: LangItem, |
064997fb FG |
162 | ) -> Option<LangItemTarget> { |
163 | let _p = profile::span("lang_item_query"); | |
164 | let lang_items = db.crate_lang_items(start_crate); | |
165 | let start_crate_target = lang_items.items.get(&item); | |
166 | if let Some(&target) = start_crate_target { | |
167 | return Some(target); | |
168 | } | |
169 | db.crate_graph()[start_crate] | |
170 | .dependencies | |
171 | .iter() | |
9ffffee4 | 172 | .find_map(|dep| db.lang_item(dep.crate_id, item)) |
064997fb FG |
173 | } |
174 | ||
175 | fn collect_lang_item<T>( | |
176 | &mut self, | |
177 | db: &dyn DefDatabase, | |
178 | item: T, | |
179 | constructor: fn(T) -> LangItemTarget, | |
180 | ) where | |
181 | T: Into<AttrDefId> + Copy, | |
182 | { | |
183 | let _p = profile::span("collect_lang_item"); | |
353b0b11 | 184 | if let Some(lang_item) = lang_attr(db, item) { |
9ffffee4 | 185 | self.items.entry(lang_item).or_insert_with(|| constructor(item)); |
064997fb FG |
186 | } |
187 | } | |
188 | } | |
189 | ||
353b0b11 | 190 | pub fn lang_attr(db: &dyn DefDatabase, item: impl Into<AttrDefId> + Copy) -> Option<LangItem> { |
064997fb | 191 | let attrs = db.attrs(item.into()); |
353b0b11 | 192 | attrs.by_key("lang").string_value().cloned().and_then(|it| LangItem::from_str(&it)) |
064997fb | 193 | } |
9ffffee4 FG |
194 | |
195 | pub enum GenericRequirement { | |
196 | None, | |
197 | Minimum(usize), | |
198 | Exact(usize), | |
199 | } | |
200 | ||
201 | macro_rules! language_item_table { | |
202 | ( | |
203 | $( $(#[$attr:meta])* $variant:ident, $name:ident, $method:ident, $target:expr, $generics:expr; )* | |
204 | ) => { | |
205 | ||
206 | /// A representation of all the valid language items in Rust. | |
207 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | |
208 | pub enum LangItem { | |
209 | $( | |
210 | #[doc = concat!("The `", stringify!($name), "` lang item.")] | |
211 | $(#[$attr])* | |
212 | $variant, | |
213 | )* | |
214 | } | |
215 | ||
216 | impl LangItem { | |
217 | pub fn name(self) -> SmolStr { | |
218 | match self { | |
219 | $( LangItem::$variant => SmolStr::new(stringify!($name)), )* | |
220 | } | |
221 | } | |
222 | ||
223 | /// Opposite of [`LangItem::name`] | |
224 | pub fn from_name(name: &hir_expand::name::Name) -> Option<Self> { | |
225 | Self::from_str(name.as_str()?) | |
226 | } | |
227 | ||
228 | /// Opposite of [`LangItem::name`] | |
229 | pub fn from_str(name: &str) -> Option<Self> { | |
230 | match name { | |
231 | $( stringify!($name) => Some(LangItem::$variant), )* | |
232 | _ => None, | |
233 | } | |
234 | } | |
235 | } | |
236 | } | |
237 | } | |
238 | ||
239 | language_item_table! { | |
240 | // Variant name, Name, Getter method name, Target Generic requirements; | |
241 | Sized, sized, sized_trait, Target::Trait, GenericRequirement::Exact(0); | |
242 | Unsize, unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1); | |
243 | /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ"). | |
244 | StructuralPeq, structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None; | |
245 | /// Trait injected by `#[derive(Eq)]`, (i.e. "Total EQ"; no, I will not apologize). | |
246 | StructuralTeq, structural_teq, structural_teq_trait, Target::Trait, GenericRequirement::None; | |
247 | Copy, copy, copy_trait, Target::Trait, GenericRequirement::Exact(0); | |
248 | Clone, clone, clone_trait, Target::Trait, GenericRequirement::None; | |
249 | Sync, sync, sync_trait, Target::Trait, GenericRequirement::Exact(0); | |
250 | DiscriminantKind, discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None; | |
251 | /// The associated item of the [`DiscriminantKind`] trait. | |
252 | Discriminant, discriminant_type, discriminant_type, Target::AssocTy, GenericRequirement::None; | |
253 | ||
254 | PointeeTrait, pointee_trait, pointee_trait, Target::Trait, GenericRequirement::None; | |
255 | Metadata, metadata_type, metadata_type, Target::AssocTy, GenericRequirement::None; | |
256 | DynMetadata, dyn_metadata, dyn_metadata, Target::Struct, GenericRequirement::None; | |
257 | ||
258 | Freeze, freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0); | |
259 | ||
260 | Drop, drop, drop_trait, Target::Trait, GenericRequirement::None; | |
261 | Destruct, destruct, destruct_trait, Target::Trait, GenericRequirement::None; | |
262 | ||
263 | CoerceUnsized, coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1); | |
264 | DispatchFromDyn, dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1); | |
265 | ||
266 | // language items relating to transmutability | |
267 | TransmuteOpts, transmute_opts, transmute_opts, Target::Struct, GenericRequirement::Exact(0); | |
268 | TransmuteTrait, transmute_trait, transmute_trait, Target::Trait, GenericRequirement::Exact(3); | |
269 | ||
270 | Add, add, add_trait, Target::Trait, GenericRequirement::Exact(1); | |
271 | Sub, sub, sub_trait, Target::Trait, GenericRequirement::Exact(1); | |
272 | Mul, mul, mul_trait, Target::Trait, GenericRequirement::Exact(1); | |
273 | Div, div, div_trait, Target::Trait, GenericRequirement::Exact(1); | |
274 | Rem, rem, rem_trait, Target::Trait, GenericRequirement::Exact(1); | |
275 | Neg, neg, neg_trait, Target::Trait, GenericRequirement::Exact(0); | |
276 | Not, not, not_trait, Target::Trait, GenericRequirement::Exact(0); | |
277 | BitXor, bitxor, bitxor_trait, Target::Trait, GenericRequirement::Exact(1); | |
278 | BitAnd, bitand, bitand_trait, Target::Trait, GenericRequirement::Exact(1); | |
279 | BitOr, bitor, bitor_trait, Target::Trait, GenericRequirement::Exact(1); | |
280 | Shl, shl, shl_trait, Target::Trait, GenericRequirement::Exact(1); | |
281 | Shr, shr, shr_trait, Target::Trait, GenericRequirement::Exact(1); | |
282 | AddAssign, add_assign, add_assign_trait, Target::Trait, GenericRequirement::Exact(1); | |
283 | SubAssign, sub_assign, sub_assign_trait, Target::Trait, GenericRequirement::Exact(1); | |
284 | MulAssign, mul_assign, mul_assign_trait, Target::Trait, GenericRequirement::Exact(1); | |
285 | DivAssign, div_assign, div_assign_trait, Target::Trait, GenericRequirement::Exact(1); | |
286 | RemAssign, rem_assign, rem_assign_trait, Target::Trait, GenericRequirement::Exact(1); | |
287 | BitXorAssign, bitxor_assign, bitxor_assign_trait, Target::Trait, GenericRequirement::Exact(1); | |
288 | BitAndAssign, bitand_assign, bitand_assign_trait, Target::Trait, GenericRequirement::Exact(1); | |
289 | BitOrAssign, bitor_assign, bitor_assign_trait, Target::Trait, GenericRequirement::Exact(1); | |
290 | ShlAssign, shl_assign, shl_assign_trait, Target::Trait, GenericRequirement::Exact(1); | |
291 | ShrAssign, shr_assign, shr_assign_trait, Target::Trait, GenericRequirement::Exact(1); | |
292 | Index, index, index_trait, Target::Trait, GenericRequirement::Exact(1); | |
293 | IndexMut, index_mut, index_mut_trait, Target::Trait, GenericRequirement::Exact(1); | |
294 | ||
295 | UnsafeCell, unsafe_cell, unsafe_cell_type, Target::Struct, GenericRequirement::None; | |
296 | VaList, va_list, va_list, Target::Struct, GenericRequirement::None; | |
297 | ||
298 | Deref, deref, deref_trait, Target::Trait, GenericRequirement::Exact(0); | |
299 | DerefMut, deref_mut, deref_mut_trait, Target::Trait, GenericRequirement::Exact(0); | |
300 | DerefTarget, deref_target, deref_target, Target::AssocTy, GenericRequirement::None; | |
301 | Receiver, receiver, receiver_trait, Target::Trait, GenericRequirement::None; | |
302 | ||
303 | Fn, fn, fn_trait, Target::Trait, GenericRequirement::Exact(1); | |
304 | FnMut, fn_mut, fn_mut_trait, Target::Trait, GenericRequirement::Exact(1); | |
305 | FnOnce, fn_once, fn_once_trait, Target::Trait, GenericRequirement::Exact(1); | |
306 | ||
307 | FnOnceOutput, fn_once_output, fn_once_output, Target::AssocTy, GenericRequirement::None; | |
308 | ||
309 | Future, future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0); | |
310 | GeneratorState, generator_state, gen_state, Target::Enum, GenericRequirement::None; | |
311 | Generator, generator, gen_trait, Target::Trait, GenericRequirement::Minimum(1); | |
312 | Unpin, unpin, unpin_trait, Target::Trait, GenericRequirement::None; | |
313 | Pin, pin, pin_type, Target::Struct, GenericRequirement::None; | |
314 | ||
315 | PartialEq, eq, eq_trait, Target::Trait, GenericRequirement::Exact(1); | |
316 | PartialOrd, partial_ord, partial_ord_trait, Target::Trait, GenericRequirement::Exact(1); | |
317 | ||
318 | // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and | |
319 | // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays. | |
320 | // | |
321 | // The `begin_unwind` lang item has a predefined symbol name and is sort of a "weak lang item" | |
322 | // in the sense that a crate is not required to have it defined to use it, but a final product | |
323 | // is required to define it somewhere. Additionally, there are restrictions on crates that use | |
324 | // a weak lang item, but do not have it defined. | |
325 | Panic, panic, panic_fn, Target::Fn, GenericRequirement::Exact(0); | |
326 | PanicNounwind, panic_nounwind, panic_nounwind, Target::Fn, GenericRequirement::Exact(0); | |
327 | PanicFmt, panic_fmt, panic_fmt, Target::Fn, GenericRequirement::None; | |
328 | PanicDisplay, panic_display, panic_display, Target::Fn, GenericRequirement::None; | |
329 | ConstPanicFmt, const_panic_fmt, const_panic_fmt, Target::Fn, GenericRequirement::None; | |
330 | PanicBoundsCheck, panic_bounds_check, panic_bounds_check_fn, Target::Fn, GenericRequirement::Exact(0); | |
331 | PanicInfo, panic_info, panic_info, Target::Struct, GenericRequirement::None; | |
332 | PanicLocation, panic_location, panic_location, Target::Struct, GenericRequirement::None; | |
333 | PanicImpl, panic_impl, panic_impl, Target::Fn, GenericRequirement::None; | |
334 | PanicCannotUnwind, panic_cannot_unwind, panic_cannot_unwind, Target::Fn, GenericRequirement::Exact(0); | |
335 | /// libstd panic entry point. Necessary for const eval to be able to catch it | |
336 | BeginPanic, begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None; | |
337 | ||
338 | ExchangeMalloc, exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None; | |
339 | BoxFree, box_free, box_free_fn, Target::Fn, GenericRequirement::Minimum(1); | |
340 | DropInPlace, drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1); | |
341 | AllocLayout, alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None; | |
342 | ||
343 | Start, start, start_fn, Target::Fn, GenericRequirement::Exact(1); | |
344 | ||
345 | EhPersonality, eh_personality, eh_personality, Target::Fn, GenericRequirement::None; | |
346 | EhCatchTypeinfo, eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None; | |
347 | ||
348 | OwnedBox, owned_box, owned_box, Target::Struct, GenericRequirement::Minimum(1); | |
349 | ||
350 | PhantomData, phantom_data, phantom_data, Target::Struct, GenericRequirement::Exact(1); | |
351 | ||
352 | ManuallyDrop, manually_drop, manually_drop, Target::Struct, GenericRequirement::None; | |
353 | ||
354 | MaybeUninit, maybe_uninit, maybe_uninit, Target::Union, GenericRequirement::None; | |
355 | ||
356 | /// Align offset for stride != 1; must not panic. | |
357 | AlignOffset, align_offset, align_offset_fn, Target::Fn, GenericRequirement::None; | |
358 | ||
359 | Termination, termination, termination, Target::Trait, GenericRequirement::None; | |
360 | ||
361 | Try, Try, try_trait, Target::Trait, GenericRequirement::None; | |
362 | ||
363 | Tuple, tuple_trait, tuple_trait, Target::Trait, GenericRequirement::Exact(0); | |
364 | ||
365 | SliceLen, slice_len_fn, slice_len_fn, Target::Method(MethodKind::Inherent), GenericRequirement::None; | |
366 | ||
367 | // Language items from AST lowering | |
368 | TryTraitFromResidual, from_residual, from_residual_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; | |
369 | TryTraitFromOutput, from_output, from_output_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; | |
370 | TryTraitBranch, branch, branch_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; | |
371 | TryTraitFromYeet, from_yeet, from_yeet_fn, Target::Fn, GenericRequirement::None; | |
372 | ||
373 | PointerSized, pointer_sized, pointer_sized, Target::Trait, GenericRequirement::Exact(0); | |
374 | ||
375 | Poll, Poll, poll, Target::Enum, GenericRequirement::None; | |
376 | PollReady, Ready, poll_ready_variant, Target::Variant, GenericRequirement::None; | |
377 | PollPending, Pending, poll_pending_variant, Target::Variant, GenericRequirement::None; | |
378 | ||
379 | // FIXME(swatinem): the following lang items are used for async lowering and | |
380 | // should become obsolete eventually. | |
381 | ResumeTy, ResumeTy, resume_ty, Target::Struct, GenericRequirement::None; | |
382 | IdentityFuture, identity_future, identity_future_fn, Target::Fn, GenericRequirement::None; | |
383 | GetContext, get_context, get_context_fn, Target::Fn, GenericRequirement::None; | |
384 | ||
385 | Context, Context, context, Target::Struct, GenericRequirement::None; | |
386 | FuturePoll, poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; | |
387 | ||
388 | FromFrom, from, from_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; | |
389 | ||
390 | OptionSome, Some, option_some_variant, Target::Variant, GenericRequirement::None; | |
391 | OptionNone, None, option_none_variant, Target::Variant, GenericRequirement::None; | |
392 | ||
393 | ResultOk, Ok, result_ok_variant, Target::Variant, GenericRequirement::None; | |
394 | ResultErr, Err, result_err_variant, Target::Variant, GenericRequirement::None; | |
395 | ||
396 | ControlFlowContinue, Continue, cf_continue_variant, Target::Variant, GenericRequirement::None; | |
397 | ControlFlowBreak, Break, cf_break_variant, Target::Variant, GenericRequirement::None; | |
398 | ||
399 | IntoFutureIntoFuture, into_future, into_future_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; | |
400 | IntoIterIntoIter, into_iter, into_iter_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; | |
401 | IteratorNext, next, next_fn, Target::Method(MethodKind::Trait { body: false}), GenericRequirement::None; | |
402 | ||
403 | PinNewUnchecked, new_unchecked, new_unchecked_fn, Target::Method(MethodKind::Inherent), GenericRequirement::None; | |
404 | ||
405 | RangeFrom, RangeFrom, range_from_struct, Target::Struct, GenericRequirement::None; | |
406 | RangeFull, RangeFull, range_full_struct, Target::Struct, GenericRequirement::None; | |
407 | RangeInclusiveStruct, RangeInclusive, range_inclusive_struct, Target::Struct, GenericRequirement::None; | |
408 | RangeInclusiveNew, range_inclusive_new, range_inclusive_new_method, Target::Method(MethodKind::Inherent), GenericRequirement::None; | |
409 | Range, Range, range_struct, Target::Struct, GenericRequirement::None; | |
410 | RangeToInclusive, RangeToInclusive, range_to_inclusive_struct, Target::Struct, GenericRequirement::None; | |
411 | RangeTo, RangeTo, range_to_struct, Target::Struct, GenericRequirement::None; | |
412 | ||
413 | String, String, string, Target::Struct, GenericRequirement::None; | |
414 | } |