From a421cfed74a10a46a082f747448992ea603559ce Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Sat, 6 Feb 2021 23:41:42 +0900 Subject: [PATCH 1/3] Add regression test to ensure `#[allow(unstable_name_collisions)]` works --- src/test/ui/inference/issue-81522.rs | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/test/ui/inference/issue-81522.rs diff --git a/src/test/ui/inference/issue-81522.rs b/src/test/ui/inference/issue-81522.rs new file mode 100644 index 0000000000000..902f8fdde58e9 --- /dev/null +++ b/src/test/ui/inference/issue-81522.rs @@ -0,0 +1,31 @@ +// Regression test for #81522. +// Ensures that `#[allow(unstable_name_collisions)]` appended to things other than function +// suppresses the corresponding diagnostics emitted from inside them. +// But note that this attribute doesn't work for macro invocations if it is appended directly. + +// aux-build:inference_unstable_iterator.rs +// aux-build:inference_unstable_itertools.rs +// run-pass + +extern crate inference_unstable_iterator; +extern crate inference_unstable_itertools; + +#[allow(unused_imports)] +use inference_unstable_iterator::IpuIterator; +use inference_unstable_itertools::IpuItertools; + +fn main() { + // expression statement + #[allow(unstable_name_collisions)] + 'x'.ipu_flatten(); + + // let statement + #[allow(unstable_name_collisions)] + let _ = 'x'.ipu_flatten(); + + // block expression + #[allow(unstable_name_collisions)] + { + 'x'.ipu_flatten(); + } +} From 120e5bdac00f9066491e34401d381b107aea06d6 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Tue, 9 Feb 2021 20:49:08 +0900 Subject: [PATCH 2/3] Pass HirId of expr in question instead of function body --- .../rustc_typeck/src/check/method/probe.rs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 0742549f8904e..7142be9c09ed5 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -83,6 +83,8 @@ struct ProbeContext<'a, 'tcx> { unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option>)>, is_suggestion: IsSuggestion, + + scope_expr_id: hir::HirId, } impl<'a, 'tcx> Deref for ProbeContext<'a, 'tcx> { @@ -285,7 +287,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, scope_expr_id, ProbeScope::AllTraits, - |probe_cx| probe_cx.pick(), + |probe_cx| probe_cx.pick(scope_expr_id), ) .ok() .map(|pick| pick.item) @@ -317,7 +319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, scope_expr_id, scope, - |probe_cx| probe_cx.pick(), + |probe_cx| probe_cx.pick(scope_expr_id), ) } @@ -448,6 +450,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { orig_values, steps.steps, is_suggestion, + scope_expr_id, ); probe_cx.assemble_inherent_candidates(); @@ -547,6 +550,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { orig_steps_var_values: OriginalQueryValues<'tcx>, steps: Lrc>>, is_suggestion: IsSuggestion, + scope_expr_id: hir::HirId, ) -> ProbeContext<'a, 'tcx> { ProbeContext { fcx, @@ -564,6 +568,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { private_candidate: None, unsatisfied_predicates: Vec::new(), is_suggestion, + scope_expr_id, } } @@ -1031,7 +1036,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /////////////////////////////////////////////////////////////////////////// // THE ACTUAL SEARCH - fn pick(mut self) -> PickResult<'tcx> { + fn pick(mut self, scope_expr_id: hir::HirId) -> PickResult<'tcx> { assert!(self.method_name.is_some()); if let Some(r) = self.pick_core() { @@ -1077,7 +1082,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if let Some((kind, def_id)) = private_candidate { return Err(MethodError::PrivateMatch(kind, def_id, out_of_scope_traits)); } - let lev_candidate = self.probe_for_lev_candidate()?; + let lev_candidate = self.probe_for_lev_candidate(scope_expr_id)?; Err(MethodError::NoMatch(NoMatchData::new( static_candidates, @@ -1312,7 +1317,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ) { self.tcx.struct_span_lint_hir( lint::builtin::UNSTABLE_NAME_COLLISIONS, - self.fcx.body_id, + self.scope_expr_id, self.span, |lint| { let def_kind = stable_pick.item.kind.as_def_kind(); @@ -1580,7 +1585,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// Similarly to `probe_for_return_type`, this method attempts to find the best matching /// candidate method where the method name may have been misspelt. Similarly to other /// Levenshtein based suggestions, we provide at most one such suggestion. - fn probe_for_lev_candidate(&mut self) -> Result, MethodError<'tcx>> { + fn probe_for_lev_candidate( + &mut self, + scope_expr_id: hir::HirId, + ) -> Result, MethodError<'tcx>> { debug!("probing for method names similar to {:?}", self.method_name); let steps = self.steps.clone(); @@ -1594,6 +1602,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.orig_steps_var_values.clone(), steps, IsSuggestion(true), + scope_expr_id, ); pcx.allow_similar_names = true; pcx.assemble_inherent_candidates(); From 06b3636f4ed23c1ad0ed18ecc1408147ec862c1a Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Sat, 27 Feb 2021 20:55:00 +0900 Subject: [PATCH 3/3] Remove unnecessary passing of scope_expr_id --- compiler/rustc_typeck/src/check/method/probe.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 7142be9c09ed5..8bf7a5f522360 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -287,7 +287,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, scope_expr_id, ProbeScope::AllTraits, - |probe_cx| probe_cx.pick(scope_expr_id), + |probe_cx| probe_cx.pick(), ) .ok() .map(|pick| pick.item) @@ -319,7 +319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, scope_expr_id, scope, - |probe_cx| probe_cx.pick(scope_expr_id), + |probe_cx| probe_cx.pick(), ) } @@ -1036,7 +1036,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /////////////////////////////////////////////////////////////////////////// // THE ACTUAL SEARCH - fn pick(mut self, scope_expr_id: hir::HirId) -> PickResult<'tcx> { + fn pick(mut self) -> PickResult<'tcx> { assert!(self.method_name.is_some()); if let Some(r) = self.pick_core() { @@ -1082,7 +1082,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if let Some((kind, def_id)) = private_candidate { return Err(MethodError::PrivateMatch(kind, def_id, out_of_scope_traits)); } - let lev_candidate = self.probe_for_lev_candidate(scope_expr_id)?; + let lev_candidate = self.probe_for_lev_candidate()?; Err(MethodError::NoMatch(NoMatchData::new( static_candidates, @@ -1585,10 +1585,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// Similarly to `probe_for_return_type`, this method attempts to find the best matching /// candidate method where the method name may have been misspelt. Similarly to other /// Levenshtein based suggestions, we provide at most one such suggestion. - fn probe_for_lev_candidate( - &mut self, - scope_expr_id: hir::HirId, - ) -> Result, MethodError<'tcx>> { + fn probe_for_lev_candidate(&mut self) -> Result, MethodError<'tcx>> { debug!("probing for method names similar to {:?}", self.method_name); let steps = self.steps.clone(); @@ -1602,7 +1599,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.orig_steps_var_values.clone(), steps, IsSuggestion(true), - scope_expr_id, + self.scope_expr_id, ); pcx.allow_similar_names = true; pcx.assemble_inherent_candidates();