]> git.proxmox.com Git - rustc.git/blob - src/librustc/hir/lowering/item.rs
New upstream version 1.40.0+dfsg1
[rustc.git] / src / librustc / hir / lowering / item.rs
1 use super::LoweringContext;
2 use super::ImplTraitContext;
3 use super::ImplTraitPosition;
4 use super::ImplTraitTypeIdVisitor;
5 use super::AnonymousLifetimeMode;
6 use super::ParamMode;
7
8 use crate::hir::{self, HirVec};
9 use crate::hir::ptr::P;
10 use crate::hir::def_id::DefId;
11 use crate::hir::def::{Res, DefKind};
12 use crate::util::nodemap::NodeMap;
13
14 use rustc_data_structures::thin_vec::ThinVec;
15
16 use std::collections::BTreeSet;
17 use smallvec::SmallVec;
18 use syntax::attr;
19 use syntax::ast::*;
20 use syntax::visit::{self, Visitor};
21 use syntax::expand::SpecialDerives;
22 use syntax::source_map::{respan, DesugaringKind, Spanned};
23 use syntax::symbol::{kw, sym};
24 use syntax_pos::Span;
25
26 pub(super) struct ItemLowerer<'tcx, 'interner> {
27 pub(super) lctx: &'tcx mut LoweringContext<'interner>,
28 }
29
30 impl<'tcx, 'interner> ItemLowerer<'tcx, 'interner> {
31 fn with_trait_impl_ref<F>(&mut self, trait_impl_ref: &Option<TraitRef>, f: F)
32 where
33 F: FnOnce(&mut Self),
34 {
35 let old = self.lctx.is_in_trait_impl;
36 self.lctx.is_in_trait_impl = if let &None = trait_impl_ref {
37 false
38 } else {
39 true
40 };
41 f(self);
42 self.lctx.is_in_trait_impl = old;
43 }
44 }
45
46 impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> {
47 fn visit_mod(&mut self, m: &'tcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
48 let hir_id = self.lctx.lower_node_id(n);
49
50 self.lctx.modules.insert(hir_id, hir::ModuleItems {
51 items: BTreeSet::new(),
52 trait_items: BTreeSet::new(),
53 impl_items: BTreeSet::new(),
54 });
55
56 let old = self.lctx.current_module;
57 self.lctx.current_module = hir_id;
58 visit::walk_mod(self, m);
59 self.lctx.current_module = old;
60 }
61
62 fn visit_item(&mut self, item: &'tcx Item) {
63 let mut item_hir_id = None;
64 self.lctx.with_hir_id_owner(item.id, |lctx| {
65 lctx.without_in_scope_lifetime_defs(|lctx| {
66 if let Some(hir_item) = lctx.lower_item(item) {
67 item_hir_id = Some(hir_item.hir_id);
68 lctx.insert_item(hir_item);
69 }
70 })
71 });
72
73 if let Some(hir_id) = item_hir_id {
74 self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
75 let this = &mut ItemLowerer { lctx: this };
76 if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.kind {
77 this.with_trait_impl_ref(opt_trait_ref, |this| {
78 visit::walk_item(this, item)
79 });
80 } else {
81 visit::walk_item(this, item);
82 }
83 });
84 }
85 }
86
87 fn visit_trait_item(&mut self, item: &'tcx TraitItem) {
88 self.lctx.with_hir_id_owner(item.id, |lctx| {
89 let hir_item = lctx.lower_trait_item(item);
90 let id = hir::TraitItemId { hir_id: hir_item.hir_id };
91 lctx.trait_items.insert(id, hir_item);
92 lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id);
93 });
94
95 visit::walk_trait_item(self, item);
96 }
97
98 fn visit_impl_item(&mut self, item: &'tcx ImplItem) {
99 self.lctx.with_hir_id_owner(item.id, |lctx| {
100 let hir_item = lctx.lower_impl_item(item);
101 let id = hir::ImplItemId { hir_id: hir_item.hir_id };
102 lctx.impl_items.insert(id, hir_item);
103 lctx.modules.get_mut(&lctx.current_module).unwrap().impl_items.insert(id);
104 });
105 visit::walk_impl_item(self, item);
106 }
107 }
108
109 impl LoweringContext<'_> {
110 // Same as the method above, but accepts `hir::GenericParam`s
111 // instead of `ast::GenericParam`s.
112 // This should only be used with generics that have already had their
113 // in-band lifetimes added. In practice, this means that this function is
114 // only used when lowering a child item of a trait or impl.
115 fn with_parent_item_lifetime_defs<T>(
116 &mut self,
117 parent_hir_id: hir::HirId,
118 f: impl FnOnce(&mut LoweringContext<'_>) -> T,
119 ) -> T {
120 let old_len = self.in_scope_lifetimes.len();
121
122 let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind {
123 hir::ItemKind::Impl(_, _, _, ref generics, ..)
124 | hir::ItemKind::Trait(_, _, ref generics, ..) => {
125 &generics.params[..]
126 }
127 _ => &[],
128 };
129 let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
130 hir::GenericParamKind::Lifetime { .. } => Some(param.name.modern()),
131 _ => None,
132 });
133 self.in_scope_lifetimes.extend(lt_def_names);
134
135 let res = f(self);
136
137 self.in_scope_lifetimes.truncate(old_len);
138 res
139 }
140
141 // Clears (and restores) the `in_scope_lifetimes` field. Used when
142 // visiting nested items, which never inherit in-scope lifetimes
143 // from their surrounding environment.
144 fn without_in_scope_lifetime_defs<T>(
145 &mut self,
146 f: impl FnOnce(&mut LoweringContext<'_>) -> T,
147 ) -> T {
148 let old_in_scope_lifetimes = std::mem::replace(&mut self.in_scope_lifetimes, vec![]);
149
150 // this vector is only used when walking over impl headers,
151 // input types, and the like, and should not be non-empty in
152 // between items
153 assert!(self.lifetimes_to_define.is_empty());
154
155 let res = f(self);
156
157 assert!(self.in_scope_lifetimes.is_empty());
158 self.in_scope_lifetimes = old_in_scope_lifetimes;
159
160 res
161 }
162
163 pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
164 hir::Mod {
165 inner: m.inner,
166 item_ids: m.items.iter().flat_map(|x| self.lower_item_id(x)).collect(),
167 }
168 }
169
170 pub(super) fn lower_item_id(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
171 let node_ids = match i.kind {
172 ItemKind::Use(ref use_tree) => {
173 let mut vec = smallvec![i.id];
174 self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
175 vec
176 }
177 ItemKind::MacroDef(..) => SmallVec::new(),
178 ItemKind::Fn(..) |
179 ItemKind::Impl(.., None, _, _) => smallvec![i.id],
180 ItemKind::Static(ref ty, ..) => {
181 let mut ids = smallvec![i.id];
182 if self.sess.features_untracked().impl_trait_in_bindings {
183 let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
184 visitor.visit_ty(ty);
185 }
186 ids
187 },
188 ItemKind::Const(ref ty, ..) => {
189 let mut ids = smallvec![i.id];
190 if self.sess.features_untracked().impl_trait_in_bindings {
191 let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
192 visitor.visit_ty(ty);
193 }
194 ids
195 },
196 _ => smallvec![i.id],
197 };
198
199 node_ids.into_iter().map(|node_id| hir::ItemId {
200 id: self.allocate_hir_id_counter(node_id)
201 }).collect()
202 }
203
204 fn lower_item_id_use_tree(
205 &mut self,
206 tree: &UseTree,
207 base_id: NodeId,
208 vec: &mut SmallVec<[NodeId; 1]>
209 ) {
210 match tree.kind {
211 UseTreeKind::Nested(ref nested_vec) => for &(ref nested, id) in nested_vec {
212 vec.push(id);
213 self.lower_item_id_use_tree(nested, id, vec);
214 },
215 UseTreeKind::Glob => {}
216 UseTreeKind::Simple(_, id1, id2) => {
217 for (_, &id) in self.expect_full_res_from_use(base_id)
218 .skip(1)
219 .zip([id1, id2].iter())
220 {
221 vec.push(id);
222 }
223 },
224 }
225 }
226
227 pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
228 let mut ident = i.ident;
229 let mut vis = self.lower_visibility(&i.vis, None);
230 let mut attrs = self.lower_attrs_extendable(&i.attrs);
231 if self.resolver.has_derives(i.id, SpecialDerives::PARTIAL_EQ | SpecialDerives::EQ) {
232 // Add `#[structural_match]` if the item derived both `PartialEq` and `Eq`.
233 let ident = Ident::new(sym::structural_match, i.span);
234 attrs.push(attr::mk_attr_outer(attr::mk_word_item(ident)));
235 }
236 let attrs = attrs.into();
237
238 if let ItemKind::MacroDef(ref def) = i.kind {
239 if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) {
240 let body = self.lower_token_stream(def.stream());
241 let hir_id = self.lower_node_id(i.id);
242 self.exported_macros.push(hir::MacroDef {
243 name: ident.name,
244 vis,
245 attrs,
246 hir_id,
247 span: i.span,
248 body,
249 legacy: def.legacy,
250 });
251 } else {
252 self.non_exported_macro_attrs.extend(attrs.into_iter());
253 }
254 return None;
255 }
256
257 let kind = self.lower_item_kind(i.id, &mut ident, &attrs, &mut vis, &i.kind);
258
259 Some(hir::Item {
260 hir_id: self.lower_node_id(i.id),
261 ident,
262 attrs,
263 kind,
264 vis,
265 span: i.span,
266 })
267 }
268
269 fn lower_item_kind(
270 &mut self,
271 id: NodeId,
272 ident: &mut Ident,
273 attrs: &hir::HirVec<Attribute>,
274 vis: &mut hir::Visibility,
275 i: &ItemKind,
276 ) -> hir::ItemKind {
277 match *i {
278 ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
279 ItemKind::Use(ref use_tree) => {
280 // Start with an empty prefix.
281 let prefix = Path {
282 segments: vec![],
283 span: use_tree.span,
284 };
285
286 self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
287 }
288 ItemKind::Static(ref t, m, ref e) => {
289 hir::ItemKind::Static(
290 self.lower_ty(
291 t,
292 if self.sess.features_untracked().impl_trait_in_bindings {
293 ImplTraitContext::OpaqueTy(None)
294 } else {
295 ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
296 }
297 ),
298 self.lower_mutability(m),
299 self.lower_const_body(e),
300 )
301 }
302 ItemKind::Const(ref t, ref e) => {
303 hir::ItemKind::Const(
304 self.lower_ty(
305 t,
306 if self.sess.features_untracked().impl_trait_in_bindings {
307 ImplTraitContext::OpaqueTy(None)
308 } else {
309 ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
310 }
311 ),
312 self.lower_const_body(e)
313 )
314 }
315 ItemKind::Fn(ref decl, header, ref generics, ref body) => {
316 let fn_def_id = self.resolver.definitions().local_def_id(id);
317 self.with_new_scopes(|this| {
318 this.current_item = Some(ident.span);
319
320 // Note: we don't need to change the return type from `T` to
321 // `impl Future<Output = T>` here because lower_body
322 // only cares about the input argument patterns in the function
323 // declaration (decl), not the return types.
324 let body_id = this.lower_maybe_async_body(&decl, header.asyncness.node, body);
325
326 let (generics, fn_decl) = this.add_in_band_defs(
327 generics,
328 fn_def_id,
329 AnonymousLifetimeMode::PassThrough,
330 |this, idty| this.lower_fn_decl(
331 &decl,
332 Some((fn_def_id, idty)),
333 true,
334 header.asyncness.node.opt_return_id()
335 ),
336 );
337
338 hir::ItemKind::Fn(
339 fn_decl,
340 this.lower_fn_header(header),
341 generics,
342 body_id,
343 )
344 })
345 }
346 ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
347 ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
348 ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
349 ItemKind::TyAlias(ref t, ref generics) => hir::ItemKind::TyAlias(
350 self.lower_ty(t, ImplTraitContext::disallowed()),
351 self.lower_generics(generics, ImplTraitContext::disallowed()),
352 ),
353 ItemKind::OpaqueTy(ref b, ref generics) => hir::ItemKind::OpaqueTy(
354 hir::OpaqueTy {
355 generics: self.lower_generics(generics,
356 ImplTraitContext::OpaqueTy(None)),
357 bounds: self.lower_param_bounds(b,
358 ImplTraitContext::OpaqueTy(None)),
359 impl_trait_fn: None,
360 origin: hir::OpaqueTyOrigin::TypeAlias,
361 },
362 ),
363 ItemKind::Enum(ref enum_definition, ref generics) => {
364 hir::ItemKind::Enum(
365 hir::EnumDef {
366 variants: enum_definition
367 .variants
368 .iter()
369 .map(|x| self.lower_variant(x))
370 .collect(),
371 },
372 self.lower_generics(generics, ImplTraitContext::disallowed()),
373 )
374 },
375 ItemKind::Struct(ref struct_def, ref generics) => {
376 let struct_def = self.lower_variant_data(struct_def);
377 hir::ItemKind::Struct(
378 struct_def,
379 self.lower_generics(generics, ImplTraitContext::disallowed()),
380 )
381 }
382 ItemKind::Union(ref vdata, ref generics) => {
383 let vdata = self.lower_variant_data(vdata);
384 hir::ItemKind::Union(
385 vdata,
386 self.lower_generics(generics, ImplTraitContext::disallowed()),
387 )
388 }
389 ItemKind::Impl(
390 unsafety,
391 polarity,
392 defaultness,
393 ref ast_generics,
394 ref trait_ref,
395 ref ty,
396 ref impl_items,
397 ) => {
398 let def_id = self.resolver.definitions().local_def_id(id);
399
400 // Lower the "impl header" first. This ordering is important
401 // for in-band lifetimes! Consider `'a` here:
402 //
403 // impl Foo<'a> for u32 {
404 // fn method(&'a self) { .. }
405 // }
406 //
407 // Because we start by lowering the `Foo<'a> for u32`
408 // part, we will add `'a` to the list of generics on
409 // the impl. When we then encounter it later in the
410 // method, it will not be considered an in-band
411 // lifetime to be added, but rather a reference to a
412 // parent lifetime.
413 let lowered_trait_impl_id = self.lower_node_id(id);
414 let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
415 ast_generics,
416 def_id,
417 AnonymousLifetimeMode::CreateParameter,
418 |this, _| {
419 let trait_ref = trait_ref.as_ref().map(|trait_ref| {
420 this.lower_trait_ref(trait_ref, ImplTraitContext::disallowed())
421 });
422
423 if let Some(ref trait_ref) = trait_ref {
424 if let Res::Def(DefKind::Trait, def_id) = trait_ref.path.res {
425 this.trait_impls.entry(def_id).or_default().push(
426 lowered_trait_impl_id);
427 }
428 }
429
430 let lowered_ty = this.lower_ty(ty, ImplTraitContext::disallowed());
431
432 (trait_ref, lowered_ty)
433 },
434 );
435
436 let new_impl_items = self.with_in_scope_lifetime_defs(
437 &ast_generics.params,
438 |this| {
439 impl_items
440 .iter()
441 .map(|item| this.lower_impl_item_ref(item))
442 .collect()
443 },
444 );
445
446 hir::ItemKind::Impl(
447 self.lower_unsafety(unsafety),
448 self.lower_impl_polarity(polarity),
449 self.lower_defaultness(defaultness, true /* [1] */),
450 generics,
451 trait_ref,
452 lowered_ty,
453 new_impl_items,
454 )
455 }
456 ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
457 let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
458 let items = items
459 .iter()
460 .map(|item| self.lower_trait_item_ref(item))
461 .collect();
462 hir::ItemKind::Trait(
463 self.lower_is_auto(is_auto),
464 self.lower_unsafety(unsafety),
465 self.lower_generics(generics, ImplTraitContext::disallowed()),
466 bounds,
467 items,
468 )
469 }
470 ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias(
471 self.lower_generics(generics, ImplTraitContext::disallowed()),
472 self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
473 ),
474 ItemKind::MacroDef(..)
475 | ItemKind::Mac(..) => bug!("`TyMac` should have been expanded by now"),
476 }
477
478 // [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
479 // not cause an assertion failure inside the `lower_defaultness` function.
480 }
481
482 fn lower_use_tree(
483 &mut self,
484 tree: &UseTree,
485 prefix: &Path,
486 id: NodeId,
487 vis: &mut hir::Visibility,
488 ident: &mut Ident,
489 attrs: &hir::HirVec<Attribute>,
490 ) -> hir::ItemKind {
491 debug!("lower_use_tree(tree={:?})", tree);
492 debug!("lower_use_tree: vis = {:?}", vis);
493
494 let path = &tree.prefix;
495 let segments = prefix
496 .segments
497 .iter()
498 .chain(path.segments.iter())
499 .cloned()
500 .collect();
501
502 match tree.kind {
503 UseTreeKind::Simple(rename, id1, id2) => {
504 *ident = tree.ident();
505
506 // First, apply the prefix to the path.
507 let mut path = Path {
508 segments,
509 span: path.span,
510 };
511
512 // Correctly resolve `self` imports.
513 if path.segments.len() > 1
514 && path.segments.last().unwrap().ident.name == kw::SelfLower
515 {
516 let _ = path.segments.pop();
517 if rename.is_none() {
518 *ident = path.segments.last().unwrap().ident;
519 }
520 }
521
522 let mut resolutions = self.expect_full_res_from_use(id);
523 // We want to return *something* from this function, so hold onto the first item
524 // for later.
525 let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err));
526
527 // Here, we are looping over namespaces, if they exist for the definition
528 // being imported. We only handle type and value namespaces because we
529 // won't be dealing with macros in the rest of the compiler.
530 // Essentially a single `use` which imports two names is desugared into
531 // two imports.
532 for (res, &new_node_id) in resolutions.zip([id1, id2].iter()) {
533 let ident = *ident;
534 let mut path = path.clone();
535 for seg in &mut path.segments {
536 seg.id = self.sess.next_node_id();
537 }
538 let span = path.span;
539
540 self.with_hir_id_owner(new_node_id, |this| {
541 let new_id = this.lower_node_id(new_node_id);
542 let res = this.lower_res(res);
543 let path =
544 this.lower_path_extra(res, &path, ParamMode::Explicit, None);
545 let kind = hir::ItemKind::Use(P(path), hir::UseKind::Single);
546 let vis = this.rebuild_vis(&vis);
547
548 this.insert_item(
549 hir::Item {
550 hir_id: new_id,
551 ident,
552 attrs: attrs.into_iter().cloned().collect(),
553 kind,
554 vis,
555 span,
556 },
557 );
558 });
559 }
560
561 let path = P(self.lower_path_extra(ret_res, &path, ParamMode::Explicit, None));
562 hir::ItemKind::Use(path, hir::UseKind::Single)
563 }
564 UseTreeKind::Glob => {
565 let path = P(self.lower_path(
566 id,
567 &Path {
568 segments,
569 span: path.span,
570 },
571 ParamMode::Explicit,
572 ));
573 hir::ItemKind::Use(path, hir::UseKind::Glob)
574 }
575 UseTreeKind::Nested(ref trees) => {
576 // Nested imports are desugared into simple imports.
577 // So, if we start with
578 //
579 // ```
580 // pub(x) use foo::{a, b};
581 // ```
582 //
583 // we will create three items:
584 //
585 // ```
586 // pub(x) use foo::a;
587 // pub(x) use foo::b;
588 // pub(x) use foo::{}; // <-- this is called the `ListStem`
589 // ```
590 //
591 // The first two are produced by recursively invoking
592 // `lower_use_tree` (and indeed there may be things
593 // like `use foo::{a::{b, c}}` and so forth). They
594 // wind up being directly added to
595 // `self.items`. However, the structure of this
596 // function also requires us to return one item, and
597 // for that we return the `{}` import (called the
598 // `ListStem`).
599
600 let prefix = Path {
601 segments,
602 span: prefix.span.to(path.span),
603 };
604
605 // Add all the nested `PathListItem`s to the HIR.
606 for &(ref use_tree, id) in trees {
607 let new_hir_id = self.lower_node_id(id);
608
609 let mut prefix = prefix.clone();
610
611 // Give the segments new node-ids since they are being cloned.
612 for seg in &mut prefix.segments {
613 seg.id = self.sess.next_node_id();
614 }
615
616 // Each `use` import is an item and thus are owners of the
617 // names in the path. Up to this point the nested import is
618 // the current owner, since we want each desugared import to
619 // own its own names, we have to adjust the owner before
620 // lowering the rest of the import.
621 self.with_hir_id_owner(id, |this| {
622 let mut vis = this.rebuild_vis(&vis);
623 let mut ident = *ident;
624
625 let kind = this.lower_use_tree(use_tree,
626 &prefix,
627 id,
628 &mut vis,
629 &mut ident,
630 attrs);
631
632 this.insert_item(
633 hir::Item {
634 hir_id: new_hir_id,
635 ident,
636 attrs: attrs.into_iter().cloned().collect(),
637 kind,
638 vis,
639 span: use_tree.span,
640 },
641 );
642 });
643 }
644
645 // Subtle and a bit hacky: we lower the privacy level
646 // of the list stem to "private" most of the time, but
647 // not for "restricted" paths. The key thing is that
648 // we don't want it to stay as `pub` (with no caveats)
649 // because that affects rustdoc and also the lints
650 // about `pub` items. But we can't *always* make it
651 // private -- particularly not for restricted paths --
652 // because it contains node-ids that would then be
653 // unused, failing the check that HirIds are "densely
654 // assigned".
655 match vis.node {
656 hir::VisibilityKind::Public |
657 hir::VisibilityKind::Crate(_) |
658 hir::VisibilityKind::Inherited => {
659 *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited);
660 }
661 hir::VisibilityKind::Restricted { .. } => {
662 // Do nothing here, as described in the comment on the match.
663 }
664 }
665
666 let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
667 let res = self.lower_res(res);
668 let path = P(self.lower_path_extra(res, &prefix, ParamMode::Explicit, None));
669 hir::ItemKind::Use(path, hir::UseKind::ListStem)
670 }
671 }
672 }
673
674 /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
675 /// many times in the HIR tree; for each occurrence, we need to assign distinct
676 /// `NodeId`s. (See, e.g., #56128.)
677 fn rebuild_use_path(&mut self, path: &hir::Path) -> hir::Path {
678 debug!("rebuild_use_path(path = {:?})", path);
679 let segments = path.segments.iter().map(|seg| hir::PathSegment {
680 ident: seg.ident,
681 hir_id: seg.hir_id.map(|_| self.next_id()),
682 res: seg.res,
683 args: None,
684 infer_args: seg.infer_args,
685 }).collect();
686 hir::Path {
687 span: path.span,
688 res: path.res,
689 segments,
690 }
691 }
692
693 fn rebuild_vis(&mut self, vis: &hir::Visibility) -> hir::Visibility {
694 let vis_kind = match vis.node {
695 hir::VisibilityKind::Public => hir::VisibilityKind::Public,
696 hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
697 hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
698 hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
699 hir::VisibilityKind::Restricted {
700 path: P(self.rebuild_use_path(path)),
701 hir_id: self.next_id(),
702 }
703 }
704 };
705 respan(vis.span, vis_kind)
706 }
707
708 fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
709 let def_id = self.resolver.definitions().local_def_id(i.id);
710 hir::ForeignItem {
711 hir_id: self.lower_node_id(i.id),
712 ident: i.ident,
713 attrs: self.lower_attrs(&i.attrs),
714 kind: match i.kind {
715 ForeignItemKind::Fn(ref fdec, ref generics) => {
716 let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
717 generics,
718 def_id,
719 AnonymousLifetimeMode::PassThrough,
720 |this, _| {
721 (
722 // Disallow `impl Trait` in foreign items.
723 this.lower_fn_decl(fdec, None, false, None),
724 this.lower_fn_params_to_names(fdec),
725 )
726 },
727 );
728
729 hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
730 }
731 ForeignItemKind::Static(ref t, m) => {
732 hir::ForeignItemKind::Static(
733 self.lower_ty(t, ImplTraitContext::disallowed()), self.lower_mutability(m))
734 }
735 ForeignItemKind::Ty => hir::ForeignItemKind::Type,
736 ForeignItemKind::Macro(_) => panic!("macro shouldn't exist here"),
737 },
738 vis: self.lower_visibility(&i.vis, None),
739 span: i.span,
740 }
741 }
742
743 fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
744 hir::ForeignMod {
745 abi: fm.abi,
746 items: fm.items
747 .iter()
748 .map(|x| self.lower_foreign_item(x))
749 .collect(),
750 }
751 }
752
753 fn lower_global_asm(&mut self, ga: &GlobalAsm) -> P<hir::GlobalAsm> {
754 P(hir::GlobalAsm { asm: ga.asm })
755 }
756
757 fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
758 hir::Variant {
759 attrs: self.lower_attrs(&v.attrs),
760 data: self.lower_variant_data(&v.data),
761 disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
762 id: self.lower_node_id(v.id),
763 ident: v.ident,
764 span: v.span,
765 }
766 }
767
768 fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
769 match *vdata {
770 VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
771 fields.iter().enumerate().map(|f| self.lower_struct_field(f)).collect(),
772 recovered,
773 ),
774 VariantData::Tuple(ref fields, id) => {
775 hir::VariantData::Tuple(
776 fields
777 .iter()
778 .enumerate()
779 .map(|f| self.lower_struct_field(f))
780 .collect(),
781 self.lower_node_id(id),
782 )
783 },
784 VariantData::Unit(id) => {
785 hir::VariantData::Unit(self.lower_node_id(id))
786 },
787 }
788 }
789
790 fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField {
791 let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind {
792 let t = self.lower_path_ty(
793 &f.ty,
794 qself,
795 path,
796 ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
797 ImplTraitContext::disallowed()
798 );
799 P(t)
800 } else {
801 self.lower_ty(&f.ty, ImplTraitContext::disallowed())
802 };
803 hir::StructField {
804 span: f.span,
805 hir_id: self.lower_node_id(f.id),
806 ident: match f.ident {
807 Some(ident) => ident,
808 // FIXME(jseyfried): positional field hygiene.
809 None => Ident::new(sym::integer(index), f.span),
810 },
811 vis: self.lower_visibility(&f.vis, None),
812 ty,
813 attrs: self.lower_attrs(&f.attrs),
814 }
815 }
816
817 fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
818 let trait_item_def_id = self.resolver.definitions().local_def_id(i.id);
819
820 let (generics, kind) = match i.kind {
821 TraitItemKind::Const(ref ty, ref default) => (
822 self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
823 hir::TraitItemKind::Const(
824 self.lower_ty(ty, ImplTraitContext::disallowed()),
825 default
826 .as_ref()
827 .map(|x| self.lower_const_body(x)),
828 ),
829 ),
830 TraitItemKind::Method(ref sig, None) => {
831 let names = self.lower_fn_params_to_names(&sig.decl);
832 let (generics, sig) = self.lower_method_sig(
833 &i.generics,
834 sig,
835 trait_item_def_id,
836 false,
837 None,
838 );
839 (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Required(names)))
840 }
841 TraitItemKind::Method(ref sig, Some(ref body)) => {
842 let body_id = self.lower_fn_body_block(&sig.decl, body);
843 let (generics, sig) = self.lower_method_sig(
844 &i.generics,
845 sig,
846 trait_item_def_id,
847 false,
848 None,
849 );
850 (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id)))
851 }
852 TraitItemKind::Type(ref bounds, ref default) => {
853 let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
854 let kind = hir::TraitItemKind::Type(
855 self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
856 default
857 .as_ref()
858 .map(|x| self.lower_ty(x, ImplTraitContext::disallowed())),
859 );
860
861 (generics, kind)
862 },
863 TraitItemKind::Macro(..) => bug!("macro item shouldn't exist at this point"),
864 };
865
866 hir::TraitItem {
867 hir_id: self.lower_node_id(i.id),
868 ident: i.ident,
869 attrs: self.lower_attrs(&i.attrs),
870 generics,
871 kind,
872 span: i.span,
873 }
874 }
875
876 fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
877 let (kind, has_default) = match i.kind {
878 TraitItemKind::Const(_, ref default) => {
879 (hir::AssocItemKind::Const, default.is_some())
880 }
881 TraitItemKind::Type(_, ref default) => {
882 (hir::AssocItemKind::Type, default.is_some())
883 }
884 TraitItemKind::Method(ref sig, ref default) => (
885 hir::AssocItemKind::Method {
886 has_self: sig.decl.has_self(),
887 },
888 default.is_some(),
889 ),
890 TraitItemKind::Macro(..) => unimplemented!(),
891 };
892 hir::TraitItemRef {
893 id: hir::TraitItemId { hir_id: self.lower_node_id(i.id) },
894 ident: i.ident,
895 span: i.span,
896 defaultness: self.lower_defaultness(Defaultness::Default, has_default),
897 kind,
898 }
899 }
900
901 fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
902 let impl_item_def_id = self.resolver.definitions().local_def_id(i.id);
903
904 let (generics, kind) = match i.kind {
905 ImplItemKind::Const(ref ty, ref expr) => (
906 self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
907 hir::ImplItemKind::Const(
908 self.lower_ty(ty, ImplTraitContext::disallowed()),
909 self.lower_const_body(expr),
910 ),
911 ),
912 ImplItemKind::Method(ref sig, ref body) => {
913 self.current_item = Some(i.span);
914 let body_id = self.lower_maybe_async_body(
915 &sig.decl, sig.header.asyncness.node, body
916 );
917 let impl_trait_return_allow = !self.is_in_trait_impl;
918 let (generics, sig) = self.lower_method_sig(
919 &i.generics,
920 sig,
921 impl_item_def_id,
922 impl_trait_return_allow,
923 sig.header.asyncness.node.opt_return_id(),
924 );
925
926 (generics, hir::ImplItemKind::Method(sig, body_id))
927 }
928 ImplItemKind::TyAlias(ref ty) => (
929 self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
930 hir::ImplItemKind::TyAlias(self.lower_ty(ty, ImplTraitContext::disallowed())),
931 ),
932 ImplItemKind::OpaqueTy(ref bounds) => (
933 self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
934 hir::ImplItemKind::OpaqueTy(
935 self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
936 ),
937 ),
938 ImplItemKind::Macro(..) => bug!("`TyMac` should have been expanded by now"),
939 };
940
941 hir::ImplItem {
942 hir_id: self.lower_node_id(i.id),
943 ident: i.ident,
944 attrs: self.lower_attrs(&i.attrs),
945 generics,
946 vis: self.lower_visibility(&i.vis, None),
947 defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
948 kind,
949 span: i.span,
950 }
951
952 // [1] since `default impl` is not yet implemented, this is always true in impls
953 }
954
955 fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
956 hir::ImplItemRef {
957 id: hir::ImplItemId { hir_id: self.lower_node_id(i.id) },
958 ident: i.ident,
959 span: i.span,
960 vis: self.lower_visibility(&i.vis, Some(i.id)),
961 defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
962 kind: match i.kind {
963 ImplItemKind::Const(..) => hir::AssocItemKind::Const,
964 ImplItemKind::TyAlias(..) => hir::AssocItemKind::Type,
965 ImplItemKind::OpaqueTy(..) => hir::AssocItemKind::OpaqueTy,
966 ImplItemKind::Method(ref sig, _) => hir::AssocItemKind::Method {
967 has_self: sig.decl.has_self(),
968 },
969 ImplItemKind::Macro(..) => unimplemented!(),
970 },
971 }
972
973 // [1] since `default impl` is not yet implemented, this is always true in impls
974 }
975
976 /// If an `explicit_owner` is given, this method allocates the `HirId` in
977 /// the address space of that item instead of the item currently being
978 /// lowered. This can happen during `lower_impl_item_ref()` where we need to
979 /// lower a `Visibility` value although we haven't lowered the owning
980 /// `ImplItem` in question yet.
981 fn lower_visibility(
982 &mut self,
983 v: &Visibility,
984 explicit_owner: Option<NodeId>,
985 ) -> hir::Visibility {
986 let node = match v.node {
987 VisibilityKind::Public => hir::VisibilityKind::Public,
988 VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
989 VisibilityKind::Restricted { ref path, id } => {
990 debug!("lower_visibility: restricted path id = {:?}", id);
991 let lowered_id = if let Some(owner) = explicit_owner {
992 self.lower_node_id_with_owner(id, owner)
993 } else {
994 self.lower_node_id(id)
995 };
996 let res = self.expect_full_res(id);
997 let res = self.lower_res(res);
998 hir::VisibilityKind::Restricted {
999 path: P(self.lower_path_extra(
1000 res,
1001 path,
1002 ParamMode::Explicit,
1003 explicit_owner,
1004 )),
1005 hir_id: lowered_id,
1006 }
1007 },
1008 VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
1009 };
1010 respan(v.span, node)
1011 }
1012
1013 fn lower_defaultness(&self, d: Defaultness, has_value: bool) -> hir::Defaultness {
1014 match d {
1015 Defaultness::Default => hir::Defaultness::Default {
1016 has_value: has_value,
1017 },
1018 Defaultness::Final => {
1019 assert!(has_value);
1020 hir::Defaultness::Final
1021 }
1022 }
1023 }
1024
1025 fn lower_impl_polarity(&mut self, i: ImplPolarity) -> hir::ImplPolarity {
1026 match i {
1027 ImplPolarity::Positive => hir::ImplPolarity::Positive,
1028 ImplPolarity::Negative => hir::ImplPolarity::Negative,
1029 }
1030 }
1031
1032 fn record_body(&mut self, params: HirVec<hir::Param>, value: hir::Expr) -> hir::BodyId {
1033 let body = hir::Body {
1034 generator_kind: self.generator_kind,
1035 params,
1036 value,
1037 };
1038 let id = body.id();
1039 self.bodies.insert(id, body);
1040 id
1041 }
1042
1043 fn lower_body(
1044 &mut self,
1045 f: impl FnOnce(&mut LoweringContext<'_>) -> (HirVec<hir::Param>, hir::Expr),
1046 ) -> hir::BodyId {
1047 let prev_gen_kind = self.generator_kind.take();
1048 let (parameters, result) = f(self);
1049 let body_id = self.record_body(parameters, result);
1050 self.generator_kind = prev_gen_kind;
1051 body_id
1052 }
1053
1054 fn lower_param(&mut self, param: &Param) -> hir::Param {
1055 hir::Param {
1056 attrs: self.lower_attrs(&param.attrs),
1057 hir_id: self.lower_node_id(param.id),
1058 pat: self.lower_pat(&param.pat),
1059 span: param.span,
1060 }
1061 }
1062
1063 pub(super) fn lower_fn_body(
1064 &mut self,
1065 decl: &FnDecl,
1066 body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
1067 ) -> hir::BodyId {
1068 self.lower_body(|this| (
1069 decl.inputs.iter().map(|x| this.lower_param(x)).collect(),
1070 body(this),
1071 ))
1072 }
1073
1074 fn lower_fn_body_block(&mut self, decl: &FnDecl, body: &Block) -> hir::BodyId {
1075 self.lower_fn_body(decl, |this| this.lower_block_expr(body))
1076 }
1077
1078 pub(super) fn lower_const_body(&mut self, expr: &Expr) -> hir::BodyId {
1079 self.lower_body(|this| (hir_vec![], this.lower_expr(expr)))
1080 }
1081
1082 fn lower_maybe_async_body(
1083 &mut self,
1084 decl: &FnDecl,
1085 asyncness: IsAsync,
1086 body: &Block,
1087 ) -> hir::BodyId {
1088 let closure_id = match asyncness {
1089 IsAsync::Async { closure_id, .. } => closure_id,
1090 IsAsync::NotAsync => return self.lower_fn_body_block(decl, body),
1091 };
1092
1093 self.lower_body(|this| {
1094 let mut parameters: Vec<hir::Param> = Vec::new();
1095 let mut statements: Vec<hir::Stmt> = Vec::new();
1096
1097 // Async function parameters are lowered into the closure body so that they are
1098 // captured and so that the drop order matches the equivalent non-async functions.
1099 //
1100 // from:
1101 //
1102 // async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {
1103 // <body>
1104 // }
1105 //
1106 // into:
1107 //
1108 // fn foo(__arg0: <ty>, __arg1: <ty>, __arg2: <ty>) {
1109 // async move {
1110 // let __arg2 = __arg2;
1111 // let <pattern> = __arg2;
1112 // let __arg1 = __arg1;
1113 // let <pattern> = __arg1;
1114 // let __arg0 = __arg0;
1115 // let <pattern> = __arg0;
1116 // drop-temps { <body> } // see comments later in fn for details
1117 // }
1118 // }
1119 //
1120 // If `<pattern>` is a simple ident, then it is lowered to a single
1121 // `let <pattern> = <pattern>;` statement as an optimization.
1122 //
1123 // Note that the body is embedded in `drop-temps`; an
1124 // equivalent desugaring would be `return { <body>
1125 // };`. The key point is that we wish to drop all the
1126 // let-bound variables and temporaries created in the body
1127 // (and its tail expression!) before we drop the
1128 // parameters (c.f. rust-lang/rust#64512).
1129 for (index, parameter) in decl.inputs.iter().enumerate() {
1130 let parameter = this.lower_param(parameter);
1131 let span = parameter.pat.span;
1132
1133 // Check if this is a binding pattern, if so, we can optimize and avoid adding a
1134 // `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
1135 let (ident, is_simple_parameter) = match parameter.pat.kind {
1136 hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _) =>
1137 (ident, true),
1138 _ => {
1139 // Replace the ident for bindings that aren't simple.
1140 let name = format!("__arg{}", index);
1141 let ident = Ident::from_str(&name);
1142
1143 (ident, false)
1144 },
1145 };
1146
1147 let desugared_span =
1148 this.mark_span_with_reason(DesugaringKind::Async, span, None);
1149
1150 // Construct a parameter representing `__argN: <ty>` to replace the parameter of the
1151 // async function.
1152 //
1153 // If this is the simple case, this parameter will end up being the same as the
1154 // original parameter, but with a different pattern id.
1155 let mut stmt_attrs = ThinVec::new();
1156 stmt_attrs.extend(parameter.attrs.iter().cloned());
1157 let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
1158 let new_parameter = hir::Param {
1159 attrs: parameter.attrs,
1160 hir_id: parameter.hir_id,
1161 pat: new_parameter_pat,
1162 span: parameter.span,
1163 };
1164
1165
1166 if is_simple_parameter {
1167 // If this is the simple case, then we only insert one statement that is
1168 // `let <pat> = <pat>;`. We re-use the original argument's pattern so that
1169 // `HirId`s are densely assigned.
1170 let expr = this.expr_ident(desugared_span, ident, new_parameter_id);
1171 let stmt = this.stmt_let_pat(
1172 stmt_attrs,
1173 desugared_span,
1174 Some(P(expr)),
1175 parameter.pat,
1176 hir::LocalSource::AsyncFn
1177 );
1178 statements.push(stmt);
1179 } else {
1180 // If this is not the simple case, then we construct two statements:
1181 //
1182 // ```
1183 // let __argN = __argN;
1184 // let <pat> = __argN;
1185 // ```
1186 //
1187 // The first statement moves the parameter into the closure and thus ensures
1188 // that the drop order is correct.
1189 //
1190 // The second statement creates the bindings that the user wrote.
1191
1192 // Construct the `let mut __argN = __argN;` statement. It must be a mut binding
1193 // because the user may have specified a `ref mut` binding in the next
1194 // statement.
1195 let (move_pat, move_id) = this.pat_ident_binding_mode(
1196 desugared_span, ident, hir::BindingAnnotation::Mutable);
1197 let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
1198 let move_stmt = this.stmt_let_pat(
1199 ThinVec::new(),
1200 desugared_span,
1201 Some(P(move_expr)),
1202 move_pat,
1203 hir::LocalSource::AsyncFn
1204 );
1205
1206 // Construct the `let <pat> = __argN;` statement. We re-use the original
1207 // parameter's pattern so that `HirId`s are densely assigned.
1208 let pattern_expr = this.expr_ident(desugared_span, ident, move_id);
1209 let pattern_stmt = this.stmt_let_pat(
1210 stmt_attrs,
1211 desugared_span,
1212 Some(P(pattern_expr)),
1213 parameter.pat,
1214 hir::LocalSource::AsyncFn
1215 );
1216
1217 statements.push(move_stmt);
1218 statements.push(pattern_stmt);
1219 };
1220
1221 parameters.push(new_parameter);
1222 }
1223
1224 let async_expr = this.make_async_expr(
1225 CaptureBy::Value,
1226 closure_id,
1227 None,
1228 body.span,
1229 hir::AsyncGeneratorKind::Fn,
1230 |this| {
1231 // Create a block from the user's function body:
1232 let user_body = this.lower_block_expr(body);
1233
1234 // Transform into `drop-temps { <user-body> }`, an expression:
1235 let desugared_span = this.mark_span_with_reason(
1236 DesugaringKind::Async,
1237 user_body.span,
1238 None,
1239 );
1240 let user_body = this.expr_drop_temps(
1241 desugared_span,
1242 P(user_body),
1243 ThinVec::new(),
1244 );
1245
1246 // As noted above, create the final block like
1247 //
1248 // ```
1249 // {
1250 // let $param_pattern = $raw_param;
1251 // ...
1252 // drop-temps { <user-body> }
1253 // }
1254 // ```
1255 let body = this.block_all(
1256 desugared_span,
1257 statements.into(),
1258 Some(P(user_body)),
1259 );
1260 this.expr_block(P(body), ThinVec::new())
1261 });
1262 (HirVec::from(parameters), this.expr(body.span, async_expr, ThinVec::new()))
1263 })
1264 }
1265
1266 fn lower_method_sig(
1267 &mut self,
1268 generics: &Generics,
1269 sig: &MethodSig,
1270 fn_def_id: DefId,
1271 impl_trait_return_allow: bool,
1272 is_async: Option<NodeId>,
1273 ) -> (hir::Generics, hir::MethodSig) {
1274 let header = self.lower_fn_header(sig.header);
1275 let (generics, decl) = self.add_in_band_defs(
1276 generics,
1277 fn_def_id,
1278 AnonymousLifetimeMode::PassThrough,
1279 |this, idty| this.lower_fn_decl(
1280 &sig.decl,
1281 Some((fn_def_id, idty)),
1282 impl_trait_return_allow,
1283 is_async,
1284 ),
1285 );
1286 (generics, hir::MethodSig { header, decl })
1287 }
1288
1289 fn lower_is_auto(&mut self, a: IsAuto) -> hir::IsAuto {
1290 match a {
1291 IsAuto::Yes => hir::IsAuto::Yes,
1292 IsAuto::No => hir::IsAuto::No,
1293 }
1294 }
1295
1296 fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
1297 hir::FnHeader {
1298 unsafety: self.lower_unsafety(h.unsafety),
1299 asyncness: self.lower_asyncness(h.asyncness.node),
1300 constness: self.lower_constness(h.constness),
1301 abi: h.abi,
1302 }
1303 }
1304
1305 pub(super) fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
1306 match u {
1307 Unsafety::Unsafe => hir::Unsafety::Unsafe,
1308 Unsafety::Normal => hir::Unsafety::Normal,
1309 }
1310 }
1311
1312 fn lower_constness(&mut self, c: Spanned<Constness>) -> hir::Constness {
1313 match c.node {
1314 Constness::Const => hir::Constness::Const,
1315 Constness::NotConst => hir::Constness::NotConst,
1316 }
1317 }
1318
1319 fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
1320 match a {
1321 IsAsync::Async { .. } => hir::IsAsync::Async,
1322 IsAsync::NotAsync => hir::IsAsync::NotAsync,
1323 }
1324 }
1325
1326 pub(super) fn lower_generics(
1327 &mut self,
1328 generics: &Generics,
1329 itctx: ImplTraitContext<'_>)
1330 -> hir::Generics
1331 {
1332 // Collect `?Trait` bounds in where clause and move them to parameter definitions.
1333 // FIXME: this could probably be done with less rightward drift. It also looks like two
1334 // control paths where `report_error` is called are the only paths that advance to after the
1335 // match statement, so the error reporting could probably just be moved there.
1336 let mut add_bounds: NodeMap<Vec<_>> = Default::default();
1337 for pred in &generics.where_clause.predicates {
1338 if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
1339 'next_bound: for bound in &bound_pred.bounds {
1340 if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound {
1341 let report_error = |this: &mut Self| {
1342 this.diagnostic().span_err(
1343 bound_pred.bounded_ty.span,
1344 "`?Trait` bounds are only permitted at the \
1345 point where a type parameter is declared",
1346 );
1347 };
1348 // Check if the where clause type is a plain type parameter.
1349 match bound_pred.bounded_ty.kind {
1350 TyKind::Path(None, ref path)
1351 if path.segments.len() == 1
1352 && bound_pred.bound_generic_params.is_empty() =>
1353 {
1354 if let Some(Res::Def(DefKind::TyParam, def_id)) = self.resolver
1355 .get_partial_res(bound_pred.bounded_ty.id)
1356 .map(|d| d.base_res())
1357 {
1358 if let Some(node_id) =
1359 self.resolver.definitions().as_local_node_id(def_id)
1360 {
1361 for param in &generics.params {
1362 match param.kind {
1363 GenericParamKind::Type { .. } => {
1364 if node_id == param.id {
1365 add_bounds.entry(param.id)
1366 .or_default()
1367 .push(bound.clone());
1368 continue 'next_bound;
1369 }
1370 }
1371 _ => {}
1372 }
1373 }
1374 }
1375 }
1376 report_error(self)
1377 }
1378 _ => report_error(self),
1379 }
1380 }
1381 }
1382 }
1383 }
1384
1385 hir::Generics {
1386 params: self.lower_generic_params(&generics.params, &add_bounds, itctx),
1387 where_clause: self.lower_where_clause(&generics.where_clause),
1388 span: generics.span,
1389 }
1390 }
1391
1392 fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause {
1393 self.with_anonymous_lifetime_mode(
1394 AnonymousLifetimeMode::ReportError,
1395 |this| {
1396 hir::WhereClause {
1397 predicates: wc.predicates
1398 .iter()
1399 .map(|predicate| this.lower_where_predicate(predicate))
1400 .collect(),
1401 span: wc.span,
1402 }
1403 },
1404 )
1405 }
1406
1407 fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
1408 match *pred {
1409 WherePredicate::BoundPredicate(WhereBoundPredicate {
1410 ref bound_generic_params,
1411 ref bounded_ty,
1412 ref bounds,
1413 span,
1414 }) => {
1415 self.with_in_scope_lifetime_defs(
1416 &bound_generic_params,
1417 |this| {
1418 hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
1419 bound_generic_params: this.lower_generic_params(
1420 bound_generic_params,
1421 &NodeMap::default(),
1422 ImplTraitContext::disallowed(),
1423 ),
1424 bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
1425 bounds: bounds
1426 .iter()
1427 .filter_map(|bound| match *bound {
1428 // Ignore `?Trait` bounds.
1429 // They were copied into type parameters already.
1430 GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
1431 _ => Some(this.lower_param_bound(
1432 bound,
1433 ImplTraitContext::disallowed(),
1434 )),
1435 })
1436 .collect(),
1437 span,
1438 })
1439 },
1440 )
1441 }
1442 WherePredicate::RegionPredicate(WhereRegionPredicate {
1443 ref lifetime,
1444 ref bounds,
1445 span,
1446 }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
1447 span,
1448 lifetime: self.lower_lifetime(lifetime),
1449 bounds: self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
1450 }),
1451 WherePredicate::EqPredicate(WhereEqPredicate {
1452 id,
1453 ref lhs_ty,
1454 ref rhs_ty,
1455 span,
1456 }) => {
1457 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
1458 hir_id: self.lower_node_id(id),
1459 lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::disallowed()),
1460 rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::disallowed()),
1461 span,
1462 })
1463 },
1464 }
1465 }
1466 }