-use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
use super::{AstOwner, ImplTraitContext, ImplTraitPosition, ResolverAstLowering};
+use super::{LoweringContext, ParamMode};
use crate::{Arena, FnDeclKind};
use rustc_ast::ptr::P;
use rustc_ast::visit::AssocCtxt;
use rustc_ast::*;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
+use rustc_hir::PredicateOrigin;
use rustc_index::vec::{Idx, IndexVec};
use rustc_session::utils::NtToTokenstream;
use rustc_session::Session;
-use rustc_span::source_map::{respan, DesugaringKind};
+use rustc_span::source_map::DesugaringKind;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use rustc_target::spec::abi;
is_in_loop_condition: false,
is_in_trait_impl: false,
is_in_dyn_type: false,
- anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
generator_kind: None,
task_context: None,
current_item: None,
- lifetimes_to_define: Vec::new(),
- is_collecting_anonymous_lifetimes: None,
- in_scope_lifetimes: Vec::new(),
- allow_try_trait: Some([sym::try_trait_v2][..].into()),
+ captured_lifetimes: None,
+ allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
allow_gen_future: Some([sym::gen_future][..].into()),
allow_into_future: Some([sym::into_future][..].into()),
};
debug_assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID);
self.with_lctx(CRATE_NODE_ID, |lctx| {
- let module = lctx.lower_mod(&c.items, c.spans.inner_span);
+ let module = lctx.lower_mod(&c.items, &c.spans);
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
hir::OwnerNode::Crate(lctx.arena.alloc(module))
})
LocalDefId { local_def_index }
};
- let parent_hir = self.lower_node(parent_id).unwrap().node().expect_item();
+ let parent_hir = self.lower_node(parent_id).unwrap();
self.with_lctx(item.id, |lctx| {
// Evaluate with the lifetimes in `params` in-scope.
// This is used to track which lifetimes have already been defined,
// and which need to be replicated when lowering an async fn.
- match parent_hir.kind {
- hir::ItemKind::Impl(hir::Impl { ref of_trait, ref generics, .. }) => {
+ match parent_hir.node().expect_item().kind {
+ hir::ItemKind::Impl(hir::Impl { ref of_trait, .. }) => {
lctx.is_in_trait_impl = of_trait.is_some();
- lctx.in_scope_lifetimes = generics
- .params
- .iter()
- .filter(|param| {
- matches!(param.kind, hir::GenericParamKind::Lifetime { .. })
- })
- .map(|param| param.name)
- .collect();
- }
- hir::ItemKind::Trait(_, _, ref generics, ..) => {
- lctx.in_scope_lifetimes = generics
- .params
- .iter()
- .filter(|param| {
- matches!(param.kind, hir::GenericParamKind::Lifetime { .. })
- })
- .map(|param| param.name)
- .collect();
}
_ => {}
};
}
impl<'hir> LoweringContext<'_, 'hir> {
- pub(super) fn lower_mod(&mut self, items: &[P<Item>], inner: Span) -> hir::Mod<'hir> {
+ pub(super) fn lower_mod(&mut self, items: &[P<Item>], spans: &ModSpans) -> hir::Mod<'hir> {
hir::Mod {
- inner: self.lower_span(inner),
+ spans: hir::ModSpans {
+ inner_span: self.lower_span(spans.inner_span),
+ inject_use_span: self.lower_span(spans.inject_use_span),
+ },
item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),
}
}
fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
let mut ident = i.ident;
- let mut vis = self.lower_visibility(&i.vis);
+ let vis_span = self.lower_span(i.vis.span);
let hir_id = self.lower_node_id(i.id);
let attrs = self.lower_attrs(hir_id, &i.attrs);
- let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
+ let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind);
let item = hir::Item {
def_id: hir_id.expect_owner(),
ident: self.lower_ident(ident),
kind,
- vis,
+ vis_span,
span: self.lower_span(i.span),
};
self.arena.alloc(item)
hir_id: hir::HirId,
ident: &mut Ident,
attrs: Option<&'hir [Attribute]>,
- vis: &mut hir::Visibility<'hir>,
+ vis_span: Span,
i: &ItemKind,
) -> hir::ItemKind<'hir> {
match *i {
// Start with an empty prefix.
let prefix = Path { segments: vec![], span: use_tree.span, tokens: None };
- self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
+ self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
}
ItemKind::Static(ref t, m, ref e) => {
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
ref body,
..
}) => {
- let fn_def_id = self.resolver.local_def_id(id);
self.with_new_scopes(|this| {
this.current_item = Some(ident.span);
let body_id =
this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());
- let (generics, decl) = this.add_in_band_defs(
- generics,
- fn_def_id,
- AnonymousLifetimeMode::PassThrough,
- |this, idty| {
+ let (generics, decl) =
+ this.add_implicit_generics(generics, id, |this, idty, idpb| {
let ret_id = asyncness.opt_return_id();
this.lower_fn_decl(
&decl,
- Some((fn_def_id, idty)),
+ Some((id, idty, idpb)),
FnDeclKind::Fn,
ret_id,
)
- },
- );
+ });
let sig = hir::FnSig {
decl,
header: this.lower_fn_header(header),
})
}
ItemKind::Mod(_, ref mod_kind) => match mod_kind {
- ModKind::Loaded(items, _, ModSpans { inner_span, inject_use_span: _ }) => {
- hir::ItemKind::Mod(self.lower_mod(items, *inner_span))
+ ModKind::Loaded(items, _, spans) => {
+ hir::ItemKind::Mod(self.lower_mod(items, spans))
}
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
},
//
// type Foo = Foo1
// opaque type Foo1: Trait
- let ty = self.lower_ty(
- ty,
- ImplTraitContext::TypeAliasesOpaqueTy {
- capturable_lifetimes: &mut FxHashSet::default(),
- },
- );
+ let ty = self.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy);
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, where_clauses, true);
let generics = self.lower_generics(
// method, it will not be considered an in-band
// lifetime to be added, but rather a reference to a
// parent lifetime.
- let lowered_trait_def_id = hir_id.expect_owner();
- let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
- ast_generics,
- lowered_trait_def_id,
- AnonymousLifetimeMode::CreateParameter,
- |this, _| {
+ let (generics, (trait_ref, lowered_ty)) =
+ self.add_implicit_generics(ast_generics, id, |this, _, _| {
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
this.lower_trait_ref(
trait_ref,
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
(trait_ref, lowered_ty)
- },
- );
-
- let new_impl_items =
- self.with_in_scope_lifetime_defs(&ast_generics.params, |this| {
- this.arena.alloc_from_iter(
- impl_items.iter().map(|item| this.lower_impl_item_ref(item)),
- )
});
+ let new_impl_items = self
+ .arena
+ .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
+
// `defaultness.has_value()` is never called for an `impl`, always `true` in order
// to not cause an assertion failure inside the `lower_defaultness` function.
let has_val = true;
ImplPolarity::Positive => ImplPolarity::Positive,
ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)),
};
- hir::ItemKind::Impl(hir::Impl {
+ hir::ItemKind::Impl(self.arena.alloc(hir::Impl {
unsafety: self.lower_unsafety(unsafety),
polarity,
defaultness,
of_trait: trait_ref,
self_ty: lowered_ty,
items: new_impl_items,
- })
+ }))
}
ItemKind::Trait(box Trait {
is_auto,
tree: &UseTree,
prefix: &Path,
id: NodeId,
- vis: &mut hir::Visibility<'hir>,
+ vis_span: Span,
ident: &mut Ident,
attrs: Option<&'hir [Attribute]>,
) -> hir::ItemKind<'hir> {
debug!("lower_use_tree(tree={:?})", tree);
- debug!("lower_use_tree: vis = {:?}", vis);
let path = &tree.prefix;
let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
let res = this.lower_res(res);
let path = this.lower_path_extra(res, &path, ParamMode::Explicit);
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
- let vis = this.rebuild_vis(&vis);
if let Some(attrs) = attrs {
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
}
def_id: new_id,
ident: this.lower_ident(ident),
kind,
- vis,
+ vis_span,
span: this.lower_span(span),
};
hir::OwnerNode::Item(this.arena.alloc(item))
// own its own names, we have to adjust the owner before
// lowering the rest of the import.
self.with_hir_id_owner(id, |this| {
- let mut vis = this.rebuild_vis(&vis);
let mut ident = *ident;
let kind =
- this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
+ this.lower_use_tree(use_tree, &prefix, id, vis_span, &mut ident, attrs);
if let Some(attrs) = attrs {
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
}
def_id: new_hir_id,
ident: this.lower_ident(ident),
kind,
- vis,
+ vis_span,
span: this.lower_span(use_tree.span),
};
hir::OwnerNode::Item(this.arena.alloc(item))
});
}
- // Subtle and a bit hacky: we lower the privacy level
- // of the list stem to "private" most of the time, but
- // not for "restricted" paths. The key thing is that
- // we don't want it to stay as `pub` (with no caveats)
- // because that affects rustdoc and also the lints
- // about `pub` items. But we can't *always* make it
- // private -- particularly not for restricted paths --
- // because it contains node-ids that would then be
- // unused, failing the check that HirIds are "densely
- // assigned".
- match vis.node {
- hir::VisibilityKind::Public
- | hir::VisibilityKind::Crate(_)
- | hir::VisibilityKind::Inherited => {
- *vis = respan(
- self.lower_span(prefix.span.shrink_to_lo()),
- hir::VisibilityKind::Inherited,
- );
- }
- hir::VisibilityKind::Restricted { .. } => {
- // Do nothing here, as described in the comment on the match.
- }
- }
-
let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
let res = self.lower_res(res);
let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit);
}
}
- /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
- /// many times in the HIR tree; for each occurrence, we need to assign distinct
- /// `NodeId`s. (See, e.g., #56128.)
- fn rebuild_use_path(&mut self, path: &hir::Path<'hir>) -> &'hir hir::Path<'hir> {
- debug!("rebuild_use_path(path = {:?})", path);
- let segments =
- self.arena.alloc_from_iter(path.segments.iter().map(|seg| hir::PathSegment {
- ident: seg.ident,
- hir_id: seg.hir_id.map(|_| self.next_id()),
- res: seg.res,
- args: None,
- infer_args: seg.infer_args,
- }));
- self.arena.alloc(hir::Path { span: path.span, res: path.res, segments })
- }
-
- fn rebuild_vis(&mut self, vis: &hir::Visibility<'hir>) -> hir::Visibility<'hir> {
- let vis_kind = match vis.node {
- hir::VisibilityKind::Public => hir::VisibilityKind::Public,
- hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
- hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
- hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
- hir::VisibilityKind::Restricted {
- path: self.rebuild_use_path(path),
- hir_id: self.next_id(),
- }
- }
- };
- respan(self.lower_span(vis.span), vis_kind)
- }
-
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
let hir_id = self.lower_node_id(i.id);
let def_id = hir_id.expect_owner();
kind: match i.kind {
ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => {
let fdec = &sig.decl;
- let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
- generics,
- def_id,
- AnonymousLifetimeMode::PassThrough,
- |this, _| {
+ let (generics, (fn_dec, fn_args)) =
+ self.add_implicit_generics(generics, i.id, |this, _, _| {
(
// Disallow `impl Trait` in foreign items.
this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
this.lower_fn_params_to_names(fdec),
)
- },
- );
+ });
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
}
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
},
- vis: self.lower_visibility(&i.vis),
+ vis_span: self.lower_span(i.vis.span),
span: self.lower_span(i.span),
};
self.arena.alloc(item)
// FIXME(jseyfried): positional field hygiene.
None => Ident::new(sym::integer(index), self.lower_span(f.span)),
},
- vis: self.lower_visibility(&f.vis),
+ vis_span: self.lower_span(f.vis.span),
ty,
}
}
}
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
let names = self.lower_fn_params_to_names(&sig.decl);
- let (generics, sig) = self.lower_method_sig(
- generics,
- sig,
- trait_item_def_id,
- FnDeclKind::Trait,
- None,
- );
+ let (generics, sig) =
+ self.lower_method_sig(generics, sig, i.id, FnDeclKind::Trait, None);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
}
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
let (generics, sig) = self.lower_method_sig(
generics,
sig,
- trait_item_def_id,
+ i.id,
FnDeclKind::Trait,
asyncness.opt_return_id(),
);
}
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
- let impl_item_def_id = self.resolver.local_def_id(i.id);
-
let (generics, kind) = match &i.kind {
AssocItemKind::Const(_, ty, expr) => {
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
let (generics, sig) = self.lower_method_sig(
generics,
sig,
- impl_item_def_id,
+ i.id,
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
asyncness.opt_return_id(),
);
hir::ImplItemKind::TyAlias(ty)
}
Some(ty) => {
- let ty = self.lower_ty(
- ty,
- ImplTraitContext::TypeAliasesOpaqueTy {
- capturable_lifetimes: &mut FxHashSet::default(),
- },
- );
+ let ty = self.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy);
hir::ImplItemKind::TyAlias(ty)
}
};
def_id: hir_id.expect_owner(),
ident: self.lower_ident(i.ident),
generics,
- vis: self.lower_visibility(&i.vis),
kind,
+ vis_span: self.lower_span(i.vis.span),
span: self.lower_span(i.span),
};
self.arena.alloc(item)
}
}
- /// If an `explicit_owner` is given, this method allocates the `HirId` in
- /// the address space of that item instead of the item currently being
- /// lowered. This can happen during `lower_impl_item_ref()` where we need to
- /// lower a `Visibility` value although we haven't lowered the owning
- /// `ImplItem` in question yet.
- fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility<'hir> {
- let node = match v.kind {
- VisibilityKind::Public => hir::VisibilityKind::Public,
- VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
- VisibilityKind::Restricted { ref path, id } => {
- debug!("lower_visibility: restricted path id = {:?}", id);
- let lowered_id = self.lower_node_id(id);
- hir::VisibilityKind::Restricted {
- path: self.lower_path(id, path, ParamMode::Explicit),
- hir_id: lowered_id,
- }
- }
- VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
- };
- respan(self.lower_span(v.span), node)
- }
-
fn lower_defaultness(
&self,
d: Defaultness,
&mut self,
generics: &Generics,
sig: &FnSig,
- fn_def_id: LocalDefId,
+ id: NodeId,
kind: FnDeclKind,
is_async: Option<NodeId>,
- ) -> (hir::Generics<'hir>, hir::FnSig<'hir>) {
+ ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
let header = self.lower_fn_header(sig.header);
- let (generics, decl) = self.add_in_band_defs(
- generics,
- fn_def_id,
- AnonymousLifetimeMode::PassThrough,
- |this, idty| this.lower_fn_decl(&sig.decl, Some((fn_def_id, idty)), kind, is_async),
- );
+ let (generics, decl) = self.add_implicit_generics(generics, id, |this, idty, idpb| {
+ this.lower_fn_decl(&sig.decl, Some((id, idty, idpb)), kind, is_async)
+ });
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
}
pub(super) fn lower_generics_mut(
&mut self,
generics: &Generics,
- itctx: ImplTraitContext<'_, 'hir>,
+ mut itctx: ImplTraitContext<'_, 'hir>,
) -> GenericsCtor<'hir> {
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
}
}
+ let mut predicates = SmallVec::new();
+ predicates.extend(generics.params.iter().filter_map(|param| {
+ let bounds = self.lower_param_bounds(¶m.bounds, itctx.reborrow());
+ self.lower_generic_bound_predicate(
+ param.ident,
+ param.id,
+ ¶m.kind,
+ bounds,
+ PredicateOrigin::GenericParam,
+ )
+ }));
+ predicates.extend(
+ generics
+ .where_clause
+ .predicates
+ .iter()
+ .map(|predicate| self.lower_where_predicate(predicate)),
+ );
+
GenericsCtor {
- params: self.lower_generic_params_mut(&generics.params, itctx).collect(),
- where_clause: self.lower_where_clause(&generics.where_clause),
+ params: self.lower_generic_params_mut(&generics.params).collect(),
+ predicates,
+ has_where_clause: !generics.where_clause.predicates.is_empty(),
+ where_clause_span: self.lower_span(generics.where_clause.span),
span: self.lower_span(generics.span),
}
}
&mut self,
generics: &Generics,
itctx: ImplTraitContext<'_, 'hir>,
- ) -> hir::Generics<'hir> {
+ ) -> &'hir hir::Generics<'hir> {
let generics_ctor = self.lower_generics_mut(generics, itctx);
generics_ctor.into_generics(self.arena)
}
- fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause<'hir> {
- self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
- hir::WhereClause {
- predicates: this.arena.alloc_from_iter(
- wc.predicates.iter().map(|predicate| this.lower_where_predicate(predicate)),
- ),
- span: this.lower_span(wc.span),
+ pub(super) fn lower_generic_bound_predicate(
+ &mut self,
+ ident: Ident,
+ id: NodeId,
+ kind: &GenericParamKind,
+ bounds: &'hir [hir::GenericBound<'hir>],
+ origin: PredicateOrigin,
+ ) -> Option<hir::WherePredicate<'hir>> {
+ // Do not create a clause if we do not have anything inside it.
+ if bounds.is_empty() {
+ return None;
+ }
+ let ident = self.lower_ident(ident);
+ let param_span = ident.span;
+ let span = bounds
+ .iter()
+ .fold(Some(param_span.shrink_to_hi()), |span: Option<Span>, bound| {
+ let bound_span = bound.span();
+ // We include bounds that come from a `#[derive(_)]` but point at the user's code,
+ // as we use this method to get a span appropriate for suggestions.
+ if !bound_span.can_be_used_for_suggestions() {
+ None
+ } else if let Some(span) = span {
+ Some(span.to(bound_span))
+ } else {
+ Some(bound_span)
+ }
+ })
+ .unwrap_or(param_span.shrink_to_hi());
+ match kind {
+ GenericParamKind::Const { .. } => None,
+ GenericParamKind::Type { .. } => {
+ let def_id = self.resolver.local_def_id(id).to_def_id();
+ let ty_path = self.arena.alloc(hir::Path {
+ span: param_span,
+ res: Res::Def(DefKind::TyParam, def_id),
+ segments: self.arena.alloc_from_iter([hir::PathSegment::from_ident(ident)]),
+ });
+ let ty_id = self.next_id();
+ let bounded_ty =
+ self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path));
+ Some(hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
+ bounded_ty: self.arena.alloc(bounded_ty),
+ bounds,
+ span,
+ bound_generic_params: &[],
+ origin,
+ }))
}
- })
+ GenericParamKind::Lifetime => {
+ let ident_span = self.lower_span(ident.span);
+ let ident = self.lower_ident(ident);
+ let res = self.resolver.get_lifetime_res(id).unwrap_or_else(|| {
+ panic!("Missing resolution for lifetime {:?} at {:?}", id, ident.span)
+ });
+ let lt_id = self.resolver.next_node_id();
+ let lifetime = self.new_named_lifetime_with_res(lt_id, ident_span, ident, res);
+ Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
+ lifetime,
+ span,
+ bounds,
+ in_where_clause: false,
+ }))
+ }
+ }
}
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
ref bounded_ty,
ref bounds,
span,
- }) => self.with_in_scope_lifetime_defs(&bound_generic_params, |this| {
- hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
- bound_generic_params: this.lower_generic_params(
- bound_generic_params,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
- ),
- bounded_ty: this.lower_ty(
- bounded_ty,
- ImplTraitContext::Disallowed(ImplTraitPosition::Type),
- ),
- bounds: this.arena.alloc_from_iter(bounds.iter().map(|bound| {
- this.lower_param_bound(
- bound,
- ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
- )
- })),
- span: this.lower_span(span),
- })
+ }) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
+ bound_generic_params: self.lower_generic_params(bound_generic_params),
+ bounded_ty: self
+ .lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
+ bounds: self.arena.alloc_from_iter(bounds.iter().map(|bound| {
+ self.lower_param_bound(
+ bound,
+ ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+ )
+ })),
+ span: self.lower_span(span),
+ origin: PredicateOrigin::WhereClause,
}),
WherePredicate::RegionPredicate(WhereRegionPredicate {
ref lifetime,
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
+ in_where_clause: true,
}),
WherePredicate::EqPredicate(WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span }) => {
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
/// Helper struct for delayed construction of Generics.
pub(super) struct GenericsCtor<'hir> {
pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>,
- where_clause: hir::WhereClause<'hir>,
+ pub(super) predicates: SmallVec<[hir::WherePredicate<'hir>; 4]>,
+ has_where_clause: bool,
+ where_clause_span: Span,
span: Span,
}
impl<'hir> GenericsCtor<'hir> {
- pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> hir::Generics<'hir> {
- hir::Generics {
+ pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> &'hir hir::Generics<'hir> {
+ arena.alloc(hir::Generics {
params: arena.alloc_from_iter(self.params),
- where_clause: self.where_clause,
+ predicates: arena.alloc_from_iter(self.predicates),
+ has_where_clause: self.has_where_clause,
+ where_clause_span: self.where_clause_span,
span: self.span,
- }
+ })
}
}