Store all generic bounds as where predicates.

This commit is contained in:
Camille GILLOT
2022-02-07 22:58:30 +01:00
parent 05b29f9a92
commit 94449e6101
30 changed files with 770 additions and 953 deletions

View File

@@ -259,7 +259,7 @@ enum ImplTraitContext<'b, 'a> {
/// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
///
/// Newly generated parameters should be inserted into the given `Vec`.
Universal(&'b mut Vec<hir::GenericParam<'a>>, LocalDefId),
Universal(&'b mut Vec<hir::GenericParam<'a>>, &'b mut Vec<hir::WherePredicate<'a>>, LocalDefId),
/// Treat `impl Trait` as shorthand for a new opaque type.
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
@@ -303,7 +303,7 @@ impl<'a> ImplTraitContext<'_, 'a> {
fn reborrow<'this>(&'this mut self) -> ImplTraitContext<'this, 'a> {
use self::ImplTraitContext::*;
match self {
Universal(params, parent) => Universal(params, *parent),
Universal(params, bounds, parent) => Universal(params, bounds, *parent),
ReturnPositionOpaqueTy { origin } => ReturnPositionOpaqueTy { origin: *origin },
TypeAliasesOpaqueTy => TypeAliasesOpaqueTy,
Disallowed(pos) => Disallowed(*pos),
@@ -704,7 +704,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
Some(hir::GenericParam {
hir_id,
name,
bounds: &[],
span: self.lower_span(ident.span),
pure_wrt_drop: false,
kind: hir::GenericParamKind::Lifetime { kind },
@@ -718,14 +717,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
generics: &Generics,
parent_node_id: NodeId,
f: impl FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
f: impl FnOnce(
&mut Self,
&mut Vec<hir::GenericParam<'hir>>,
&mut Vec<hir::WherePredicate<'hir>>,
) -> T,
) -> (&'hir hir::Generics<'hir>, T) {
let mut impl_trait_defs = Vec::new();
let mut impl_trait_bounds = Vec::new();
let mut lowered_generics = self.lower_generics_mut(
generics,
ImplTraitContext::Universal(&mut impl_trait_defs, self.current_hir_id_owner),
ImplTraitContext::Universal(
&mut impl_trait_defs,
&mut impl_trait_bounds,
self.current_hir_id_owner,
),
);
let res = f(self, &mut impl_trait_defs);
let res = f(self, &mut impl_trait_defs, &mut impl_trait_bounds);
let extra_lifetimes = self.resolver.take_extra_lifetime_params(parent_node_id);
lowered_generics.params.extend(
@@ -736,6 +744,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
})
.chain(impl_trait_defs),
);
lowered_generics.predicates.extend(impl_trait_bounds);
let lowered_generics = lowered_generics.into_generics(self.arena);
(lowered_generics, res)
@@ -999,7 +1008,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// so desugar to
//
// fn foo(x: dyn Iterator<Item = impl Debug>)
ImplTraitContext::Universal(_, parent) if self.is_in_dyn_type => {
ImplTraitContext::Universal(_, _, parent) if self.is_in_dyn_type => {
parent_def_id = parent;
(true, itctx)
}
@@ -1188,10 +1197,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
TyKind::BareFn(ref f) => self.with_lifetime_binder(t.id, |this| {
hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
generic_params: this.lower_generic_params(
&f.generic_params,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
generic_params: this.lower_generic_params(&f.generic_params),
unsafety: this.lower_unsafety(f.unsafety),
abi: this.lower_extern(f.ext),
decl: this.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None),
@@ -1274,13 +1280,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|this| this.lower_param_bounds(bounds, nested_itctx),
)
}
ImplTraitContext::Universal(in_band_ty_params, parent_def_id) => {
ImplTraitContext::Universal(
in_band_ty_params,
in_band_ty_bounds,
parent_def_id,
) => {
// Add a definition for the in-band `Param`.
let def_id = self.resolver.local_def_id(def_node_id);
let hir_bounds = self.lower_param_bounds(
bounds,
ImplTraitContext::Universal(in_band_ty_params, parent_def_id),
ImplTraitContext::Universal(
in_band_ty_params,
in_band_ty_bounds,
parent_def_id,
),
);
// Set the name to `impl Bound1 + Bound2`.
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
@@ -1288,10 +1302,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir_id: self.lower_node_id(def_node_id),
name: ParamName::Plain(self.lower_ident(ident)),
pure_wrt_drop: false,
bounds: hir_bounds,
span: self.lower_span(span),
kind: hir::GenericParamKind::Type { default: None, synthetic: true },
});
if let Some(preds) = self.lower_generic_bound_predicate(
ident,
def_node_id,
&GenericParamKind::Type { default: None },
hir_bounds,
) {
in_band_ty_bounds.push(preds)
}
hir::TyKind::Path(hir::QPath::Resolved(
None,
@@ -1374,7 +1395,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
name: p_name,
span,
pure_wrt_drop: false,
bounds: &[],
kind: hir::GenericParamKind::Lifetime { kind },
}
},
@@ -1386,6 +1406,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
generics: self.arena.alloc(hir::Generics {
params: lifetime_defs,
predicates: &[],
has_where_clause: false,
where_clause_span: lctx.lower_span(span),
span: lctx.lower_span(span),
}),
@@ -1463,7 +1484,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_fn_decl(
&mut self,
decl: &FnDecl,
mut in_band_ty_params: Option<(NodeId, &mut Vec<hir::GenericParam<'hir>>)>,
mut in_band_ty_params: Option<(
NodeId,
&mut Vec<hir::GenericParam<'hir>>,
&mut Vec<hir::WherePredicate<'hir>>,
)>,
kind: FnDeclKind,
make_ret_async: Option<NodeId>,
) -> &'hir hir::FnDecl<'hir> {
@@ -1486,10 +1511,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
inputs = &inputs[..inputs.len() - 1];
}
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
if let Some((_, ibty)) = &mut in_band_ty_params {
if let Some((_, ibty, ibpb)) = &mut in_band_ty_params {
self.lower_ty_direct(
&param.ty,
ImplTraitContext::Universal(ibty, self.current_hir_id_owner),
ImplTraitContext::Universal(ibty, ibpb, self.current_hir_id_owner),
)
} else {
self.lower_ty_direct(
@@ -1518,7 +1543,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
match decl.output {
FnRetTy::Ty(ref ty) => {
let context = match in_band_ty_params {
Some((node_id, _)) if kind.impl_trait_return_allowed() => {
Some((node_id, _, _)) if kind.impl_trait_return_allowed() => {
let fn_def_id = self.resolver.local_def_id(node_id);
ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
@@ -1709,7 +1734,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
name: p_name,
span,
pure_wrt_drop: false,
bounds: &[],
kind: hir::GenericParamKind::Lifetime { kind },
}
}));
@@ -1719,6 +1743,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
generics: this.arena.alloc(hir::Generics {
params: generic_params,
predicates: &[],
has_where_clause: false,
where_clause_span: this.lower_span(span),
span: this.lower_span(span),
}),
@@ -1925,26 +1950,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_generic_params_mut<'s>(
&'s mut self,
params: &'s [GenericParam],
mut itctx: ImplTraitContext<'s, 'hir>,
) -> impl Iterator<Item = hir::GenericParam<'hir>> + Captures<'a> + Captures<'s> {
params.iter().map(move |param| self.lower_generic_param(param, itctx.reborrow()))
params.iter().map(move |param| self.lower_generic_param(param))
}
fn lower_generic_params(
&mut self,
params: &[GenericParam],
itctx: ImplTraitContext<'_, 'hir>,
) -> &'hir [hir::GenericParam<'hir>] {
self.arena.alloc_from_iter(self.lower_generic_params_mut(params, itctx))
fn lower_generic_params(&mut self, params: &[GenericParam]) -> &'hir [hir::GenericParam<'hir>] {
self.arena.alloc_from_iter(self.lower_generic_params_mut(params))
}
fn lower_generic_param(
&mut self,
param: &GenericParam,
mut itctx: ImplTraitContext<'_, 'hir>,
) -> hir::GenericParam<'hir> {
let bounds: Vec<_> = self.lower_param_bounds_mut(&param.bounds, itctx.reborrow()).collect();
fn lower_generic_param(&mut self, param: &GenericParam) -> hir::GenericParam<'hir> {
let (name, kind) = match param.kind {
GenericParamKind::Lifetime => {
let param_name = if param.ident.name == kw::StaticLifetime
@@ -1991,7 +2005,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
name,
span: self.lower_span(param.span()),
pure_wrt_drop: self.sess.contains_name(&param.attrs, sym::may_dangle),
bounds: self.arena.alloc_from_iter(bounds),
kind,
}
}
@@ -2014,8 +2027,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
p: &PolyTraitRef,
mut itctx: ImplTraitContext<'_, 'hir>,
) -> hir::PolyTraitRef<'hir> {
let bound_generic_params =
self.lower_generic_params(&p.bound_generic_params, itctx.reborrow());
let bound_generic_params = self.lower_generic_params(&p.bound_generic_params);
let trait_ref = self.with_lifetime_binder(p.trait_ref.ref_id, |this| {
this.lower_trait_ref(&p.trait_ref, itctx.reborrow())