Auto merge of #77546 - lcnr:impl-trait-closure, r=eddyb
fix def collector for impl trait fixes #77329 We now consistently make `impl Trait` a hir owner, requiring some special casing for synthetic generic params. r? `@eddyb`
This commit is contained in:
commit
3e0dd24a6c
9 changed files with 98 additions and 19 deletions
|
@ -538,6 +538,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
self.visit_fn_ret_ty(&f.decl.output)
|
self.visit_fn_ret_ty(&f.decl.output)
|
||||||
}
|
}
|
||||||
|
TyKind::ImplTrait(def_node_id, _) => {
|
||||||
|
self.lctx.allocate_hir_id_counter(def_node_id);
|
||||||
|
self.with_hir_id_owner(Some(def_node_id), |this| {
|
||||||
|
visit::walk_ty(this, t);
|
||||||
|
});
|
||||||
|
}
|
||||||
_ => visit::walk_ty(self, t),
|
_ => visit::walk_ty(self, t),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1347,10 +1353,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// Add a definition for the in-band `Param`.
|
// Add a definition for the in-band `Param`.
|
||||||
let def_id = self.resolver.local_def_id(def_node_id);
|
let def_id = self.resolver.local_def_id(def_node_id);
|
||||||
|
|
||||||
let hir_bounds = self.lower_param_bounds(
|
self.allocate_hir_id_counter(def_node_id);
|
||||||
|
|
||||||
|
let hir_bounds = self.with_hir_id_owner(def_node_id, |this| {
|
||||||
|
this.lower_param_bounds(
|
||||||
bounds,
|
bounds,
|
||||||
ImplTraitContext::Universal(in_band_ty_params),
|
ImplTraitContext::Universal(in_band_ty_params),
|
||||||
);
|
)
|
||||||
|
});
|
||||||
// Set the name to `impl Bound1 + Bound2`.
|
// Set the name to `impl Bound1 + Bound2`.
|
||||||
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
|
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
|
||||||
in_band_ty_params.push(hir::GenericParam {
|
in_band_ty_params.push(hir::GenericParam {
|
||||||
|
@ -2201,7 +2211,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
.attrs
|
.attrs
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|attr| self.sess.check_name(attr, sym::rustc_synthetic))
|
.filter(|attr| self.sess.check_name(attr, sym::rustc_synthetic))
|
||||||
.map(|_| hir::SyntheticTyParamKind::ImplTrait)
|
.map(|_| hir::SyntheticTyParamKind::FromAttr)
|
||||||
.next(),
|
.next(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -486,6 +486,8 @@ impl Generics<'hir> {
|
||||||
#[derive(HashStable_Generic)]
|
#[derive(HashStable_Generic)]
|
||||||
pub enum SyntheticTyParamKind {
|
pub enum SyntheticTyParamKind {
|
||||||
ImplTrait,
|
ImplTrait,
|
||||||
|
// Created by the `#[rustc_synthetic]` attribute.
|
||||||
|
FromAttr,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A where-clause in a definition.
|
/// A where-clause in a definition.
|
||||||
|
|
|
@ -360,9 +360,27 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_generic_param(&mut self, param: &'hir GenericParam<'hir>) {
|
fn visit_generic_param(&mut self, param: &'hir GenericParam<'hir>) {
|
||||||
|
if let hir::GenericParamKind::Type {
|
||||||
|
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
|
||||||
|
..
|
||||||
|
} = param.kind
|
||||||
|
{
|
||||||
|
debug_assert_eq!(
|
||||||
|
param.hir_id.owner,
|
||||||
|
self.definitions.opt_hir_id_to_local_def_id(param.hir_id).unwrap()
|
||||||
|
);
|
||||||
|
self.with_dep_node_owner(param.hir_id.owner, param, |this, hash| {
|
||||||
|
this.insert_with_hash(param.span, param.hir_id, Node::GenericParam(param), hash);
|
||||||
|
|
||||||
|
this.with_parent(param.hir_id, |this| {
|
||||||
|
intravisit::walk_generic_param(this, param);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
self.insert(param.span, param.hir_id, Node::GenericParam(param));
|
self.insert(param.span, param.hir_id, Node::GenericParam(param));
|
||||||
intravisit::walk_generic_param(self, param);
|
intravisit::walk_generic_param(self, param);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
|
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
|
|
|
@ -163,4 +163,17 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
|
||||||
// we are currently in. So for those it's correct that they have a
|
// we are currently in. So for those it's correct that they have a
|
||||||
// different owner.
|
// different owner.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_generic_param(&mut self, param: &'hir hir::GenericParam<'hir>) {
|
||||||
|
if let hir::GenericParamKind::Type {
|
||||||
|
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
|
||||||
|
..
|
||||||
|
} = param.kind
|
||||||
|
{
|
||||||
|
// Synthetic impl trait parameters are owned by the node of the desugared type.
|
||||||
|
// This means it is correct for them to have a different owner.
|
||||||
|
} else {
|
||||||
|
intravisit::walk_generic_param(self, param);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,13 +240,13 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
TyKind::MacCall(..) => return self.visit_macro_invoc(ty.id),
|
TyKind::MacCall(..) => self.visit_macro_invoc(ty.id),
|
||||||
TyKind::ImplTrait(node_id, _) => {
|
TyKind::ImplTrait(node_id, _) => {
|
||||||
self.create_def(node_id, DefPathData::ImplTrait, ty.span);
|
let parent_def = self.create_def(node_id, DefPathData::ImplTrait, ty.span);
|
||||||
|
self.with_parent(parent_def, |this| visit::walk_ty(this, ty));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => visit::walk_ty(self, ty),
|
||||||
}
|
}
|
||||||
visit::walk_ty(self, ty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||||
|
|
|
@ -320,6 +320,15 @@ impl<'tcx> DumpVisitor<'tcx> {
|
||||||
for param in generics.params {
|
for param in generics.params {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
hir::GenericParamKind::Lifetime { .. } => {}
|
hir::GenericParamKind::Lifetime { .. } => {}
|
||||||
|
hir::GenericParamKind::Type {
|
||||||
|
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
return self
|
||||||
|
.nest_typeck_results(self.tcx.hir().local_def_id(param.hir_id), |this| {
|
||||||
|
this.visit_generics(generics)
|
||||||
|
});
|
||||||
|
}
|
||||||
hir::GenericParamKind::Type { .. } => {
|
hir::GenericParamKind::Type { .. } => {
|
||||||
let param_ss = param.name.ident().span;
|
let param_ss = param.name.ident().span;
|
||||||
let name = escape(self.span.snippet(param_ss));
|
let name = escape(self.span.snippet(param_ss));
|
||||||
|
@ -351,7 +360,8 @@ impl<'tcx> DumpVisitor<'tcx> {
|
||||||
hir::GenericParamKind::Const { .. } => {}
|
hir::GenericParamKind::Const { .. } => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.visit_generics(generics);
|
|
||||||
|
self.visit_generics(generics)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_fn(
|
fn process_fn(
|
||||||
|
|
|
@ -548,9 +548,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
generics: &ty::Generics,
|
generics: &ty::Generics,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let explicit = !seg.infer_args;
|
let explicit = !seg.infer_args;
|
||||||
let impl_trait = generics.params.iter().any(|param| match param.kind {
|
let impl_trait =
|
||||||
|
generics.params.iter().any(|param| match param.kind {
|
||||||
ty::GenericParamDefKind::Type {
|
ty::GenericParamDefKind::Type {
|
||||||
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
|
synthetic:
|
||||||
|
Some(
|
||||||
|
hir::SyntheticTyParamKind::ImplTrait
|
||||||
|
| hir::SyntheticTyParamKind::FromAttr,
|
||||||
|
),
|
||||||
..
|
..
|
||||||
} => true,
|
} => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
7
src/test/ui/impl-trait/closure-in-impl-trait-arg.rs
Normal file
7
src/test/ui/impl-trait/closure-in-impl-trait-arg.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// run-pass
|
||||||
|
#![allow(unused_must_use)]
|
||||||
|
fn bug(_: impl Iterator<Item = [(); { |x: u32| { x }; 4 }]>) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
bug(std::iter::empty());
|
||||||
|
}
|
14
src/test/ui/impl-trait/closure-in-impl-trait.rs
Normal file
14
src/test/ui/impl-trait/closure-in-impl-trait.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// run-pass
|
||||||
|
#![allow(unused_must_use)]
|
||||||
|
fn bug<T>() -> impl Iterator<Item = [(); { |x: u32| { x }; 4 }]> {
|
||||||
|
std::iter::empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ok<T>() -> Box<dyn Iterator<Item = [(); { |x: u32| { x }; 4 }]>> {
|
||||||
|
Box::new(std::iter::empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
for _item in ok::<u32>() {}
|
||||||
|
for _item in bug::<u32>() {}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue