Skip to content

Commit

Permalink
Auto merge of #77546 - lcnr:impl-trait-closure, r=eddyb
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
bors committed Oct 25, 2020
2 parents 17cc9b6 + 567d55e commit 3e0dd24
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 19 deletions.
20 changes: 15 additions & 5 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
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),
}
}
Expand Down Expand Up @@ -1347,10 +1353,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// 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),
);
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,
ImplTraitContext::Universal(in_band_ty_params),
)
});
// Set the name to `impl Bound1 + Bound2`.
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
in_band_ty_params.push(hir::GenericParam {
Expand Down Expand Up @@ -2201,7 +2211,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.attrs
.iter()
.filter(|attr| self.sess.check_name(attr, sym::rustc_synthetic))
.map(|_| hir::SyntheticTyParamKind::ImplTrait)
.map(|_| hir::SyntheticTyParamKind::FromAttr)
.next(),
};

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,8 @@ impl Generics<'hir> {
#[derive(HashStable_Generic)]
pub enum SyntheticTyParamKind {
ImplTrait,
// Created by the `#[rustc_synthetic]` attribute.
FromAttr,
}

/// A where-clause in a definition.
Expand Down
22 changes: 20 additions & 2 deletions compiler/rustc_middle/src/hir/map/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,26 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
}

fn visit_generic_param(&mut self, param: &'hir GenericParam<'hir>) {
self.insert(param.span, param.hir_id, Node::GenericParam(param));
intravisit::walk_generic_param(self, param);
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));
intravisit::walk_generic_param(self, param);
}
}

fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_passes/src/hir_id_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// 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);
}
}
}
8 changes: 4 additions & 4 deletions compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,13 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {

fn visit_ty(&mut self, ty: &'a Ty) {
match ty.kind {
TyKind::MacCall(..) => return self.visit_macro_invoc(ty.id),
TyKind::MacCall(..) => self.visit_macro_invoc(ty.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) {
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_save_analysis/src/dump_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,15 @@ impl<'tcx> DumpVisitor<'tcx> {
for param in generics.params {
match param.kind {
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 { .. } => {
let param_ss = param.name.ident().span;
let name = escape(self.span.snippet(param_ss));
Expand Down Expand Up @@ -351,7 +360,8 @@ impl<'tcx> DumpVisitor<'tcx> {
hir::GenericParamKind::Const { .. } => {}
}
}
self.visit_generics(generics);

self.visit_generics(generics)
}

fn process_fn(
Expand Down
19 changes: 12 additions & 7 deletions compiler/rustc_typeck/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,13 +548,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
generics: &ty::Generics,
) -> bool {
let explicit = !seg.infer_args;
let impl_trait = generics.params.iter().any(|param| match param.kind {
ty::GenericParamDefKind::Type {
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
..
} => true,
_ => false,
});
let impl_trait =
generics.params.iter().any(|param| match param.kind {
ty::GenericParamDefKind::Type {
synthetic:
Some(
hir::SyntheticTyParamKind::ImplTrait
| hir::SyntheticTyParamKind::FromAttr,
),
..
} => true,
_ => false,
});

if explicit && impl_trait {
let spans = seg
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/impl-trait/closure-in-impl-trait-arg.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 14 additions & 0 deletions src/test/ui/impl-trait/closure-in-impl-trait.rs
Original file line number Diff line number Diff line change
@@ -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>() {}
}

0 comments on commit 3e0dd24

Please sign in to comment.