From 8f13705e3b5cb563cee1c43446c0a682514a6f15 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 4 Oct 2020 22:48:57 +0200 Subject: [PATCH 1/7] fix def collector for impl trait --- compiler/rustc_resolve/src/def_collector.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 5d5088de31b97..d7a1d30b0e48b 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -239,13 +239,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) { From 5ac268c43557102dabcd3dc45b2bcaf01cb228ee Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 5 Oct 2020 00:25:51 +0200 Subject: [PATCH 2/7] do not lower patterns in impl Trait --- compiler/rustc_ast_lowering/src/lib.rs | 5 +++++ src/test/ui/impl-trait/closure-in-impl-trait.rs | 14 ++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 src/test/ui/impl-trait/closure-in-impl-trait.rs diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a28d022c66139..64c034f7ec935 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -538,6 +538,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } self.visit_fn_ret_ty(&f.decl.output) } + TyKind::ImplTrait(_, ref bounds) => { + self.with_hir_id_owner(None, |this| { + walk_list!(this, visit_param_bound, bounds); + }); + } _ => visit::walk_ty(self, t), } } diff --git a/src/test/ui/impl-trait/closure-in-impl-trait.rs b/src/test/ui/impl-trait/closure-in-impl-trait.rs new file mode 100644 index 0000000000000..3593a1d5c8d10 --- /dev/null +++ b/src/test/ui/impl-trait/closure-in-impl-trait.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(unused_must_use)] +fn bug() -> impl Iterator { + std::iter::empty() +} + +fn ok() -> Box> { + Box::new(std::iter::empty()) +} + +fn main() { + for _item in ok::() {} + for _item in bug::() {} +} From a5d2db4a58b4f3c196ed58d3a95cd7c7b61d746b Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 5 Oct 2020 01:19:58 +0200 Subject: [PATCH 3/7] arg position --- src/test/ui/impl-trait/closure-in-impl-trait-arg.rs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/test/ui/impl-trait/closure-in-impl-trait-arg.rs diff --git a/src/test/ui/impl-trait/closure-in-impl-trait-arg.rs b/src/test/ui/impl-trait/closure-in-impl-trait-arg.rs new file mode 100644 index 0000000000000..3cfce459e37dc --- /dev/null +++ b/src/test/ui/impl-trait/closure-in-impl-trait-arg.rs @@ -0,0 +1,7 @@ +// run-pass +#![allow(unused_must_use)] +fn bug(_: impl Iterator) {} + +fn main() { + bug(std::iter::empty()); +} From f865e3d22f93664c85059f88ceef433718c4f2f0 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 5 Oct 2020 01:27:10 +0200 Subject: [PATCH 4/7] bodge --- compiler/rustc_ast_lowering/src/lib.rs | 19 ++++++++++------ .../rustc_middle/src/hir/map/collector.rs | 22 +++++++++++++++++-- compiler/rustc_passes/src/hir_id_validator.rs | 12 ++++++++++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 64c034f7ec935..41e1aafd9bdad 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -538,9 +538,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } self.visit_fn_ret_ty(&f.decl.output) } - TyKind::ImplTrait(_, ref bounds) => { - self.with_hir_id_owner(None, |this| { - walk_list!(this, visit_param_bound, bounds); + 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), @@ -1351,10 +1352,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 { diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index d6869ab88751a..516c9b6752b97 100644 --- a/compiler/rustc_middle/src/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs @@ -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>) { diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 24695f5cdfa04..7d4bafc10896f 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -163,4 +163,16 @@ 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 + { + // Do nothing because bodging is fun. + } else { + intravisit::walk_generic_param(self, param); + } + } } From 236689d6eb241e92bea7449c07ba55783926391f Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 5 Oct 2020 01:43:15 +0200 Subject: [PATCH 5/7] split SyntheticTyParamKind --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_hir/src/hir.rs | 2 ++ compiler/rustc_typeck/src/astconv/generics.rs | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 41e1aafd9bdad..6e60191892f21 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2210,7 +2210,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::Rustc) .next(), }; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 636f67a77c890..52d24a2eb4821 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -508,6 +508,8 @@ impl Generics<'hir> { #[derive(HashStable_Generic)] pub enum SyntheticTyParamKind { ImplTrait, + // Created by the `#[rustc_synthetic]` attribute. + Rustc, } /// A where-clause in a definition. diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index b867798c76cf7..a877dfcfcb753 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -550,7 +550,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let explicit = !seg.infer_args; let impl_trait = generics.params.iter().any(|param| match param.kind { ty::GenericParamDefKind::Type { - synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), + synthetic: + Some(hir::SyntheticTyParamKind::ImplTrait | hir::SyntheticTyParamKind::Rustc), .. } => true, _ => false, From 604bc876e03a4169a1fb42408d778c65ab39cec2 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 5 Oct 2020 02:01:32 +0200 Subject: [PATCH 6/7] implement nits --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_passes/src/hir_id_validator.rs | 3 ++- compiler/rustc_typeck/src/astconv/generics.rs | 20 +++++++++++-------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 6e60191892f21..a70309b64c1e9 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2210,7 +2210,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .attrs .iter() .filter(|attr| self.sess.check_name(attr, sym::rustc_synthetic)) - .map(|_| hir::SyntheticTyParamKind::Rustc) + .map(|_| hir::SyntheticTyParamKind::FromAttr) .next(), }; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 52d24a2eb4821..befdfdbd7cf9c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -509,7 +509,7 @@ impl Generics<'hir> { pub enum SyntheticTyParamKind { ImplTrait, // Created by the `#[rustc_synthetic]` attribute. - Rustc, + FromAttr, } /// A where-clause in a definition. diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 7d4bafc10896f..6d1a5fcc10b0f 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -170,7 +170,8 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> { .. } = param.kind { - // Do nothing because bodging is fun. + // 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); } diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index a877dfcfcb753..3bfb2d3f1b0f9 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -548,14 +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 | hir::SyntheticTyParamKind::Rustc), - .. - } => 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 From 567d55ef9ef4c441365227aeb14880eef639c349 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 22 Oct 2020 21:04:28 +0200 Subject: [PATCH 7/7] fix save-analysis --- compiler/rustc_save_analysis/src/dump_visitor.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index ce484858cbb66..dbb5e3cc9f066 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -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)); @@ -351,7 +360,8 @@ impl<'tcx> DumpVisitor<'tcx> { hir::GenericParamKind::Const { .. } => {} } } - self.visit_generics(generics); + + self.visit_generics(generics) } fn process_fn(