]> git.lizzy.rs Git - rust.git/blob - src/librustc/dep_graph/dep_node.rs
Split DepNode::ItemSignature into non-overlapping variants.
[rust.git] / src / librustc / dep_graph / dep_node.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11
12 //! This module defines the `DepNode` type which the compiler uses to represent
13 //! nodes in the dependency graph. A `DepNode` consists of a `DepKind` (which
14 //! specifies the kind of thing it represents, like a piece of HIR, MIR, etc)
15 //! and a `Fingerprint`, a 128 bit hash value the exact meaning of which
16 //! depends on the node's `DepKind`. Together, the kind and the fingerprint
17 //! fully identify a dependency node, even across multiple compilation sessions.
18 //! In other words, the value of the fingerprint does not depend on anything
19 //! that is specific to a given compilation session, like an unpredictable
20 //! interning key (e.g. NodeId, DefId, Symbol) or the numeric value of a
21 //! pointer. The concept behind this could be compared to how git commit hashes
22 //! uniquely identify a given commit and has a few advantages:
23 //!
24 //! * A `DepNode` can simply be serialized to disk and loaded in another session
25 //!   without the need to do any "rebasing (like we have to do for Spans and
26 //!   NodeIds) or "retracing" like we had to do for `DefId` in earlier
27 //!   implementations of the dependency graph.
28 //! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
29 //!   implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
30 //! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
31 //!   memory without any post-processing (e.g. "abomination-style" pointer
32 //!   reconstruction).
33 //! * Because a `DepNode` is self-contained, we can instantiate `DepNodes` that
34 //!   refer to things that do not exist anymore. In previous implementations
35 //!   `DepNode` contained a `DefId`. A `DepNode` referring to something that
36 //!   had been removed between the previous and the current compilation session
37 //!   could not be instantiated because the current compilation session
38 //!   contained no `DefId` for thing that had been removed.
39 //!
40 //! `DepNode` definition happens in the `define_dep_nodes!()` macro. This macro
41 //! defines the `DepKind` enum and a corresponding `DepConstructor` enum. The
42 //! `DepConstructor` enum links a `DepKind` to the parameters that are needed at
43 //! runtime in order to construct a valid `DepNode` fingerprint.
44 //!
45 //! Because the macro sees what parameters a given `DepKind` requires, it can
46 //! "infer" some properties for each kind of `DepNode`:
47 //!
48 //! * Whether a `DepNode` of a given kind has any parameters at all. Some
49 //!   `DepNode`s, like `Krate`, represent global concepts with only one value.
50 //! * Whether it is possible, in principle, to reconstruct a query key from a
51 //!   given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
52 //!   in which case it is possible to map the node's fingerprint back to the
53 //!   `DefId` it was computed from. In other cases, too much information gets
54 //!   lost during fingerprint computation.
55 //!
56 //! The `DepConstructor` enum, together with `DepNode::new()` ensures that only
57 //! valid `DepNode` instances can be constructed. For example, the API does not
58 //! allow for constructing parameterless `DepNode`s with anything other
59 //! than a zeroed out fingerprint. More generally speaking, it relieves the
60 //! user of the `DepNode` API of having to know how to compute the expected
61 //! fingerprint for a given set of node parameters.
62
63 use hir::def_id::{CrateNum, DefId};
64 use hir::map::DefPathHash;
65
66 use ich::Fingerprint;
67 use ty::TyCtxt;
68 use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
69 use ich::StableHashingContext;
70 use std::fmt;
71 use std::hash::Hash;
72
73 // erase!() just makes tokens go away. It's used to specify which macro argument
74 // is repeated (i.e. which sub-expression of the macro we are in) but don't need
75 // to actually use any of the arguments.
76 macro_rules! erase {
77     ($x:tt) => ({})
78 }
79
80 macro_rules! define_dep_nodes {
81     ($(
82         $variant:ident $(( $($tuple_arg:tt),* ))*
83                        $({ $($struct_arg_name:ident : $struct_arg_ty:ty),* })*
84       ,)*
85     ) => (
86         #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
87                  RustcEncodable, RustcDecodable)]
88         pub enum DepKind {
89             $($variant),*
90         }
91
92         impl DepKind {
93             #[allow(unreachable_code)]
94             #[inline]
95             pub fn can_reconstruct_query_key(&self) -> bool {
96                 match *self {
97                     $(
98                         DepKind :: $variant => {
99                             // tuple args
100                             $({
101                                 return <( $($tuple_arg,)* ) as DepNodeParams>
102                                     ::CAN_RECONSTRUCT_QUERY_KEY;
103                             })*
104
105                             // struct args
106                             $({
107                                 return <( $($struct_arg_ty,)* ) as DepNodeParams>
108                                     ::CAN_RECONSTRUCT_QUERY_KEY;
109                             })*
110
111                             true
112                         }
113                     )*
114                 }
115             }
116
117             #[allow(unreachable_code)]
118             #[inline]
119             pub fn has_params(&self) -> bool {
120                 match *self {
121                     $(
122                         DepKind :: $variant => {
123                             // tuple args
124                             $({
125                                 $(erase!($tuple_arg);)*
126                                 return true;
127                             })*
128
129                             // struct args
130                             $({
131                                 $(erase!($struct_arg_name);)*
132                                 return true;
133                             })*
134
135                             false
136                         }
137                     )*
138                 }
139             }
140         }
141
142         pub enum DepConstructor {
143             $(
144                 $variant $(( $($tuple_arg),* ))*
145                          $({ $($struct_arg_name : $struct_arg_ty),* })*
146             ),*
147         }
148
149         #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
150                  RustcEncodable, RustcDecodable)]
151         pub struct DepNode {
152             pub kind: DepKind,
153             pub hash: Fingerprint,
154         }
155
156         impl DepNode {
157             #[allow(unreachable_code, non_snake_case)]
158             pub fn new(tcx: TyCtxt, dep: DepConstructor) -> DepNode {
159                 match dep {
160                     $(
161                         DepConstructor :: $variant $(( $($tuple_arg),* ))*
162                                                    $({ $($struct_arg_name),* })*
163                             =>
164                         {
165                             // tuple args
166                             $({
167                                 let tupled_args = ( $($tuple_arg,)* );
168                                 let hash = DepNodeParams::to_fingerprint(&tupled_args,
169                                                                          tcx);
170                                 let dep_node = DepNode {
171                                     kind: DepKind::$variant,
172                                     hash
173                                 };
174
175                                 if cfg!(debug_assertions) &&
176                                    !dep_node.kind.can_reconstruct_query_key() &&
177                                    (tcx.sess.opts.debugging_opts.incremental_info ||
178                                     tcx.sess.opts.debugging_opts.query_dep_graph)
179                                 {
180                                     tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
181                                         tupled_args.to_debug_str(tcx)
182                                     });
183                                 }
184
185                                 return dep_node;
186                             })*
187
188                             // struct args
189                             $({
190                                 let tupled_args = ( $($struct_arg_name,)* );
191                                 let hash = DepNodeParams::to_fingerprint(&tupled_args,
192                                                                          tcx);
193                                 let dep_node = DepNode {
194                                     kind: DepKind::$variant,
195                                     hash
196                                 };
197
198                                 if cfg!(debug_assertions) &&
199                                    !dep_node.kind.can_reconstruct_query_key() &&
200                                    (tcx.sess.opts.debugging_opts.incremental_info ||
201                                     tcx.sess.opts.debugging_opts.query_dep_graph)
202                                 {
203                                     tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
204                                         tupled_args.to_debug_str(tcx)
205                                     });
206                                 }
207
208                                 return dep_node;
209                             })*
210
211                             DepNode {
212                                 kind: DepKind::$variant,
213                                 hash: Fingerprint::zero(),
214                             }
215                         }
216                     )*
217                 }
218             }
219
220             /// Construct a DepNode from the given DepKind and DefPathHash. This
221             /// method will assert that the given DepKind actually requires a
222             /// single DefId/DefPathHash parameter.
223             #[inline]
224             pub fn from_def_path_hash(kind: DepKind,
225                                       def_path_hash: DefPathHash)
226                                       -> DepNode {
227                 assert!(kind.can_reconstruct_query_key() && kind.has_params());
228                 DepNode {
229                     kind,
230                     hash: def_path_hash.0,
231                 }
232             }
233
234             /// Create a new, parameterless DepNode. This method will assert
235             /// that the DepNode corresponding to the given DepKind actually
236             /// does not require any parameters.
237             #[inline]
238             pub fn new_no_params(kind: DepKind) -> DepNode {
239                 assert!(!kind.has_params());
240                 DepNode {
241                     kind,
242                     hash: Fingerprint::zero(),
243                 }
244             }
245
246             /// Extract the DefId corresponding to this DepNode. This will work
247             /// if two conditions are met:
248             ///
249             /// 1. The Fingerprint of the DepNode actually is a DefPathHash, and
250             /// 2. the item that the DefPath refers to exists in the current tcx.
251             ///
252             /// Condition (1) is determined by the DepKind variant of the
253             /// DepNode. Condition (2) might not be fulfilled if a DepNode
254             /// refers to something from the previous compilation session that
255             /// has been removed.
256             #[inline]
257             pub fn extract_def_id(&self, tcx: TyCtxt) -> Option<DefId> {
258                 if self.kind.can_reconstruct_query_key() {
259                     let def_path_hash = DefPathHash(self.hash);
260                     if let Some(ref def_path_map) = tcx.def_path_hash_to_def_id.as_ref() {
261                         def_path_map.get(&def_path_hash).cloned()
262                     } else {
263                        None
264                     }
265                 } else {
266                     None
267                 }
268             }
269
270             /// Used in testing
271             pub fn from_label_string(label: &str,
272                                      def_path_hash: DefPathHash)
273                                      -> Result<DepNode, ()> {
274                 let kind = match label {
275                     $(
276                         stringify!($variant) => DepKind::$variant,
277                     )*
278                     _ => return Err(()),
279                 };
280
281                 if !kind.can_reconstruct_query_key() {
282                     return Err(());
283                 }
284
285                 if kind.has_params() {
286                     Ok(def_path_hash.to_dep_node(kind))
287                 } else {
288                     Ok(DepNode::new_no_params(kind))
289                 }
290             }
291         }
292     );
293 }
294
295 impl fmt::Debug for DepNode {
296     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
297         write!(f, "{:?}", self.kind)?;
298
299         if !self.kind.has_params() {
300             return Ok(());
301         }
302
303         write!(f, "(")?;
304
305         ::ty::tls::with_opt(|opt_tcx| {
306             if let Some(tcx) = opt_tcx {
307                 if let Some(def_id) = self.extract_def_id(tcx) {
308                     write!(f, "{}", tcx.item_path_str(def_id))?;
309                 } else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
310                     write!(f, "{}", s)?;
311                 } else {
312                     write!(f, "{:?}", self.hash)?;
313                 }
314             } else {
315                 write!(f, "{:?}", self.hash)?;
316             }
317             Ok(())
318         })?;
319
320         write!(f, ")")
321     }
322 }
323
324
325 impl DefPathHash {
326     #[inline]
327     pub fn to_dep_node(self, kind: DepKind) -> DepNode {
328         DepNode::from_def_path_hash(kind, self)
329     }
330 }
331
332 impl DefId {
333     #[inline]
334     pub fn to_dep_node(self, tcx: TyCtxt, kind: DepKind) -> DepNode {
335         DepNode::from_def_path_hash(kind, tcx.def_path_hash(self))
336     }
337 }
338
339 define_dep_nodes!(
340     // Represents the `Krate` as a whole (the `hir::Krate` value) (as
341     // distinct from the krate module). This is basically a hash of
342     // the entire krate, so if you read from `Krate` (e.g., by calling
343     // `tcx.hir.krate()`), we will have to assume that any change
344     // means that you need to be recompiled. This is because the
345     // `Krate` value gives you access to all other items. To avoid
346     // this fate, do not call `tcx.hir.krate()`; instead, prefer
347     // wrappers like `tcx.visit_all_items_in_krate()`.  If there is no
348     // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
349     // access to the krate, but you must remember to add suitable
350     // edges yourself for the individual items that you read.
351     Krate,
352
353     // Represents the HIR node with the given node-id
354     Hir(DefId),
355
356     // Represents the body of a function or method. The def-id is that of the
357     // function/method.
358     HirBody(DefId),
359
360     // Represents the metadata for a given HIR node, typically found
361     // in an extern crate.
362     MetaData(DefId),
363
364     // Represents some artifact that we save to disk. Note that these
365     // do not have a def-id as part of their identifier.
366     WorkProduct(WorkProductId),
367
368     // Represents different phases in the compiler.
369     RegionMaps(DefId),
370     Coherence,
371     Resolve,
372     CoherenceCheckTrait(DefId),
373     PrivacyAccessLevels(CrateNum),
374
375     // Represents the MIR for a fn; also used as the task node for
376     // things read/modify that MIR.
377     Mir(DefId),
378     MirShim(DefIdList),
379
380     BorrowCheckKrate,
381     BorrowCheck(DefId),
382     RvalueCheck(DefId),
383     Reachability,
384     MirKeys,
385     TransWriteMetadata,
386     CrateVariances,
387
388     // Nodes representing bits of computed IR in the tcx. Each shared
389     // table in the tcx (or elsewhere) maps to one of these
390     // nodes.
391     AssociatedItems(DefId),
392     TypeOfItem(DefId),
393     GenericsOfItem(DefId),
394     PredicatesOfItem(DefId),
395     SuperPredicatesOfItem(DefId),
396     TraitDefOfItem(DefId),
397     AdtDefOfItem(DefId),
398     IsDefaultImpl(DefId),
399     ImplTraitRef(DefId),
400     ImplPolarity(DefId),
401     ClosureKind(DefId),
402     FnSignature(DefId),
403     CoerceUnsizedInfo(DefId),
404
405     ItemVarianceConstraints(DefId),
406     ItemVariances(DefId),
407     IsConstFn(DefId),
408     IsForeignItem(DefId),
409     TypeParamPredicates { item_id: DefId, param_id: DefId },
410     SizedConstraint(DefId),
411     DtorckConstraint(DefId),
412     AdtDestructor(DefId),
413     AssociatedItemDefIds(DefId),
414     InherentImpls(DefId),
415     TypeckBodiesKrate,
416     TypeckTables(DefId),
417     ConstEval(DefId),
418     SymbolName(DefId),
419     SpecializationGraph(DefId),
420     ObjectSafety(DefId),
421     IsCopy(DefId),
422     IsSized(DefId),
423     IsFreeze(DefId),
424     NeedsDrop(DefId),
425     Layout(DefId),
426
427     // The set of impls for a given trait. Ultimately, it would be
428     // nice to get more fine-grained here (e.g., to include a
429     // simplified type), but we can't do that until we restructure the
430     // HIR to distinguish the *header* of an impl from its body.  This
431     // is because changes to the header may change the self-type of
432     // the impl and hence would require us to be more conservative
433     // than changes in the impl body.
434     TraitImpls(DefId),
435
436     AllLocalTraitImpls,
437
438     // Nodes representing caches. To properly handle a true cache, we
439     // don't use a DepTrackingMap, but rather we push a task node.
440     // Otherwise the write into the map would be incorrectly
441     // attributed to the first task that happened to fill the cache,
442     // which would yield an overly conservative dep-graph.
443     TraitItems(DefId),
444     ReprHints(DefId),
445
446     // Trait selection cache is a little funny. Given a trait
447     // reference like `Foo: SomeTrait<Bar>`, there could be
448     // arbitrarily many def-ids to map on in there (e.g., `Foo`,
449     // `SomeTrait`, `Bar`). We could have a vector of them, but it
450     // requires heap-allocation, and trait sel in general can be a
451     // surprisingly hot path. So instead we pick two def-ids: the
452     // trait def-id, and the first def-id in the input types. If there
453     // is no def-id in the input types, then we use the trait def-id
454     // again. So for example:
455     //
456     // - `i32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
457     // - `u32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
458     // - `Clone: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
459     // - `Vec<i32>: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Vec }`
460     // - `String: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: String }`
461     // - `Foo: Trait<Bar>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
462     // - `Foo: Trait<i32>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
463     // - `(Foo, Bar): Trait` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
464     // - `i32: Trait<Foo>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
465     //
466     // You can see that we map many trait refs to the same
467     // trait-select node.  This is not a problem, it just means
468     // imprecision in our dep-graph tracking.  The important thing is
469     // that for any given trait-ref, we always map to the **same**
470     // trait-select node.
471     TraitSelect { trait_def_id: DefId, input_def_id: DefId },
472
473     // For proj. cache, we just keep a list of all def-ids, since it is
474     // not a hotspot.
475     ProjectionCache { def_ids: DefIdList },
476
477     ParamEnv(DefId),
478     DescribeDef(DefId),
479     DefSpan(DefId),
480     Stability(DefId),
481     Deprecation(DefId),
482     ItemBodyNestedBodies(DefId),
483     ConstIsRvaluePromotableToStatic(DefId),
484     ImplParent(DefId),
485     TraitOfItem(DefId),
486     IsExportedSymbol(DefId),
487     IsMirAvailable(DefId),
488     ItemAttrs(DefId),
489     FnArgNames(DefId),
490     DylibDepFormats(DefId),
491     IsAllocator(DefId),
492     IsPanicRuntime(DefId),
493     ExternCrate(DefId),
494 );
495
496 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> {
497     const CAN_RECONSTRUCT_QUERY_KEY: bool;
498     fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint;
499     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String;
500 }
501
502 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T
503     where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + fmt::Debug
504 {
505     default const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
506
507     default fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint {
508         let mut hcx = StableHashingContext::new(tcx);
509         let mut hasher = StableHasher::new();
510
511         self.hash_stable(&mut hcx, &mut hasher);
512
513         hasher.finish()
514     }
515
516     default fn to_debug_str(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> String {
517         format!("{:?}", *self)
518     }
519 }
520
521 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId,) {
522     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
523
524     fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
525         tcx.def_path_hash(self.0).0
526     }
527
528     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
529         tcx.item_path_str(self.0)
530     }
531 }
532
533 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId, DefId) {
534     const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
535
536     // We actually would not need to specialize the implementation of this
537     // method but it's faster to combine the hashes than to instantiate a full
538     // hashing context and stable-hashing state.
539     fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
540         let (def_id_0, def_id_1) = *self;
541
542         let def_path_hash_0 = tcx.def_path_hash(def_id_0);
543         let def_path_hash_1 = tcx.def_path_hash(def_id_1);
544
545         def_path_hash_0.0.combine(def_path_hash_1.0)
546     }
547
548     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
549         let (def_id_0, def_id_1) = *self;
550
551         format!("({}, {})",
552                 tcx.def_path(def_id_0).to_string(tcx),
553                 tcx.def_path(def_id_1).to_string(tcx))
554     }
555 }
556
557
558 impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefIdList,) {
559     const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
560
561     // We actually would not need to specialize the implementation of this
562     // method but it's faster to combine the hashes than to instantiate a full
563     // hashing context and stable-hashing state.
564     fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint {
565         let mut fingerprint = Fingerprint::zero();
566
567         for &def_id in self.0.iter() {
568             let def_path_hash = tcx.def_path_hash(def_id);
569             fingerprint = fingerprint.combine(def_path_hash.0);
570         }
571
572         fingerprint
573     }
574
575     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
576         use std::fmt::Write;
577
578         let mut s = String::new();
579         write!(&mut s, "[").unwrap();
580
581         for &def_id in self.0.iter() {
582             write!(&mut s, "{}", tcx.def_path(def_id).to_string(tcx)).unwrap();
583         }
584
585         write!(&mut s, "]").unwrap();
586
587         s
588     }
589 }
590
591 /// A "work product" corresponds to a `.o` (or other) file that we
592 /// save in between runs. These ids do not have a DefId but rather
593 /// some independent path or string that persists between runs without
594 /// the need to be mapped or unmapped. (This ensures we can serialize
595 /// them even in the absence of a tcx.)
596 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
597          RustcEncodable, RustcDecodable)]
598 pub struct WorkProductId {
599     hash: Fingerprint
600 }
601
602 impl WorkProductId {
603     pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
604         let mut hasher = StableHasher::new();
605         cgu_name.len().hash(&mut hasher);
606         cgu_name.hash(&mut hasher);
607         WorkProductId {
608             hash: hasher.finish()
609         }
610     }
611
612     pub fn from_fingerprint(fingerprint: Fingerprint) -> WorkProductId {
613         WorkProductId {
614             hash: fingerprint
615         }
616     }
617
618     pub fn to_dep_node(self) -> DepNode {
619         DepNode {
620             kind: DepKind::WorkProduct,
621             hash: self.hash,
622         }
623     }
624 }
625
626 impl_stable_hash_for!(struct ::dep_graph::WorkProductId {
627     hash
628 });
629
630 type DefIdList = Vec<DefId>;