From b3bf931aa2ca95c60ec49b7f6519a1e74dae3c1d Mon Sep 17 00:00:00 2001 From: Yan Chen Date: Tue, 20 Sep 2022 14:44:55 -0700 Subject: [PATCH 1/6] Fix missing explanation of where borrowed reference is used when the borrow occurs in loop iteration --- .../src/diagnostics/explain_borrow.rs | 156 +++--------------- .../rustc_borrowck/src/region_infer/mod.rs | 23 ++- .../borrowck-mut-borrow-linear-errors.stderr | 5 +- .../ui/borrowck/two-phase-across-loop.stderr | 5 +- src/test/ui/nll/closures-in-loops.stderr | 16 +- 5 files changed, 63 insertions(+), 142 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 1c01e78abd422..582d683dd3593 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -1,8 +1,5 @@ //! Print diagnostics to explain why values are borrowed. -use std::collections::VecDeque; - -use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, Diagnostic}; use rustc_index::vec::IndexVec; use rustc_infer::infer::NllRegionVariableOrigin; @@ -359,19 +356,37 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let borrow_region_vid = borrow.region; debug!(?borrow_region_vid); - let region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location); + let mut region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location); debug!(?region_sub); - match find_use::find(body, regioncx, tcx, region_sub, location) { + let mut use_location = location; + let mut use_in_later_iteration_of_loop = false; + + if region_sub == borrow_region_vid { + // When `region_sub` is the same as `borrow_region_vid` (the location where the borrow is + // issued is the same location that invalidates the reference), this is likely a loop iteration + // - in this case, try using the loop terminator location in `find_sub_region_live_at`. + if let Some(loop_terminator_location) = + regioncx.find_loop_terminator_location(borrow.region, body) + { + region_sub = self + .regioncx + .find_sub_region_live_at(borrow_region_vid, loop_terminator_location); + debug!("explain_why_borrow_contains_point: region_sub in loop={:?}", region_sub); + use_location = loop_terminator_location; + use_in_later_iteration_of_loop = true; + } + } + + match find_use::find(body, regioncx, tcx, region_sub, use_location) { Some(Cause::LiveVar(local, location)) => { let span = body.source_info(location).span; let spans = self .move_spans(Place::from(local).as_ref(), location) .or_else(|| self.borrow_spans(span, location)); - let borrow_location = location; - if self.is_use_in_later_iteration_of_loop(borrow_location, location) { - let later_use = self.later_use_kind(borrow, spans, location); + if use_in_later_iteration_of_loop { + let later_use = self.later_use_kind(borrow, spans, use_location); BorrowExplanation::UsedLaterInLoop(later_use.0, later_use.1, later_use.2) } else { // Check if the location represents a `FakeRead`, and adapt the error @@ -425,131 +440,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - /// true if `borrow_location` can reach `use_location` by going through a loop and - /// `use_location` is also inside of that loop - fn is_use_in_later_iteration_of_loop( - &self, - borrow_location: Location, - use_location: Location, - ) -> bool { - let back_edge = self.reach_through_backedge(borrow_location, use_location); - back_edge.map_or(false, |back_edge| self.can_reach_head_of_loop(use_location, back_edge)) - } - - /// Returns the outmost back edge if `from` location can reach `to` location passing through - /// that back edge - fn reach_through_backedge(&self, from: Location, to: Location) -> Option { - let mut visited_locations = FxHashSet::default(); - let mut pending_locations = VecDeque::new(); - visited_locations.insert(from); - pending_locations.push_back(from); - debug!("reach_through_backedge: from={:?} to={:?}", from, to,); - - let mut outmost_back_edge = None; - while let Some(location) = pending_locations.pop_front() { - debug!( - "reach_through_backedge: location={:?} outmost_back_edge={:?} - pending_locations={:?} visited_locations={:?}", - location, outmost_back_edge, pending_locations, visited_locations - ); - - if location == to && outmost_back_edge.is_some() { - // We've managed to reach the use location - debug!("reach_through_backedge: found!"); - return outmost_back_edge; - } - - let block = &self.body.basic_blocks[location.block]; - - if location.statement_index < block.statements.len() { - let successor = location.successor_within_block(); - if visited_locations.insert(successor) { - pending_locations.push_back(successor); - } - } else { - pending_locations.extend( - block - .terminator() - .successors() - .map(|bb| Location { statement_index: 0, block: bb }) - .filter(|s| visited_locations.insert(*s)) - .map(|s| { - if self.is_back_edge(location, s) { - match outmost_back_edge { - None => { - outmost_back_edge = Some(location); - } - - Some(back_edge) - if location.dominates(back_edge, &self.dominators) => - { - outmost_back_edge = Some(location); - } - - Some(_) => {} - } - } - - s - }), - ); - } - } - - None - } - - /// true if `from` location can reach `loop_head` location and `loop_head` dominates all the - /// intermediate nodes - fn can_reach_head_of_loop(&self, from: Location, loop_head: Location) -> bool { - self.find_loop_head_dfs(from, loop_head, &mut FxHashSet::default()) - } - - fn find_loop_head_dfs( - &self, - from: Location, - loop_head: Location, - visited_locations: &mut FxHashSet, - ) -> bool { - visited_locations.insert(from); - - if from == loop_head { - return true; - } - - if loop_head.dominates(from, &self.dominators) { - let block = &self.body.basic_blocks[from.block]; - - if from.statement_index < block.statements.len() { - let successor = from.successor_within_block(); - - if !visited_locations.contains(&successor) - && self.find_loop_head_dfs(successor, loop_head, visited_locations) - { - return true; - } - } else { - for bb in block.terminator().successors() { - let successor = Location { statement_index: 0, block: bb }; - - if !visited_locations.contains(&successor) - && self.find_loop_head_dfs(successor, loop_head, visited_locations) - { - return true; - } - } - } - } - - false - } - - /// True if an edge `source -> target` is a backedge -- in other words, if the target - /// dominates the source. - fn is_back_edge(&self, source: Location, target: Location) -> bool { - target.dominates(source, &self.dominators) - } - /// Determine how the borrow was later used. /// First span returned points to the location of the conflicting use /// Second span if `Some` is returned in the case of closures and points diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 244e6e3422d83..347c358183377 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -15,7 +15,7 @@ use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; use rustc_middle::mir::{ Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, - ConstraintCategory, Local, Location, ReturnConstraint, + ConstraintCategory, Local, Location, ReturnConstraint, TerminatorKind, }; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCauseCode; @@ -2236,6 +2236,27 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { self.universe_causes[&universe].clone() } + + /// Tries to find the terminator of the loop in which the region 'r' resides. + /// Returns the location of the terminator if found. + pub(crate) fn find_loop_terminator_location( + &self, + r: RegionVid, + body: &Body<'_>, + ) -> Option { + let scc = self.constraint_sccs.scc(r.to_region_vid()); + let locations = self.scc_values.locations_outlived_by(scc); + for location in locations { + let bb = &body[location.block]; + if let Some(terminator) = &bb.terminator { + // terminator of a loop should be TerminatorKind::FalseUnwind + if let TerminatorKind::FalseUnwind { .. } = terminator.kind { + return Some(location); + } + } + } + None + } } impl<'tcx> RegionDefinition<'tcx> { diff --git a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr index 15ac737606d66..d2b845619c784 100644 --- a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr +++ b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr @@ -25,7 +25,10 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time --> $DIR/borrowck-mut-borrow-linear-errors.rs:12:30 | LL | _ => { addr.push(&mut x); } - | ^^^^^^ `x` was mutably borrowed here in the previous iteration of the loop + | ----------^^^^^^- + | | | + | | `x` was mutably borrowed here in the previous iteration of the loop + | first borrow used here, in later iteration of loop error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/two-phase-across-loop.stderr b/src/test/ui/borrowck/two-phase-across-loop.stderr index 95896c6bbf987..22f9b39dfeecb 100644 --- a/src/test/ui/borrowck/two-phase-across-loop.stderr +++ b/src/test/ui/borrowck/two-phase-across-loop.stderr @@ -2,7 +2,10 @@ error[E0499]: cannot borrow `foo` as mutable more than once at a time --> $DIR/two-phase-across-loop.rs:17:22 | LL | strings.push(foo.get_string()); - | ^^^^^^^^^^^^^^^^ `foo` was mutably borrowed here in the previous iteration of the loop + | -------------^^^^^^^^^^^^^^^^- + | | | + | | `foo` was mutably borrowed here in the previous iteration of the loop + | first borrow used here, in later iteration of loop error: aborting due to previous error diff --git a/src/test/ui/nll/closures-in-loops.stderr b/src/test/ui/nll/closures-in-loops.stderr index 2be0460df1fc6..1c1a31d356d6f 100644 --- a/src/test/ui/nll/closures-in-loops.stderr +++ b/src/test/ui/nll/closures-in-loops.stderr @@ -13,17 +13,21 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time --> $DIR/closures-in-loops.rs:13:16 | LL | v.push(|| x = String::new()); - | ^^ - borrows occur due to use of `x` in closure - | | - | `x` was mutably borrowed here in the previous iteration of the loop + | -------^^------------------- + | | | | + | | | borrows occur due to use of `x` in closure + | | `x` was mutably borrowed here in the previous iteration of the loop + | first borrow used here, in later iteration of loop error[E0524]: two closures require unique access to `x` at the same time --> $DIR/closures-in-loops.rs:20:16 | LL | v.push(|| *x = String::new()); - | ^^ -- borrows occur due to use of `x` in closure - | | - | closures are constructed here in different iterations of loop + | -------^^-------------------- + | | | | + | | | borrows occur due to use of `x` in closure + | | closures are constructed here in different iterations of loop + | first borrow used here, in later iteration of loop error: aborting due to 3 previous errors From 0227d8d55512d9fee22532f10459b4dc96de1b1e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Oct 2022 08:28:14 +0000 Subject: [PATCH 2/6] Enable `x.py check` for miri --- src/bootstrap/check.rs | 6 ++---- src/bootstrap/doc.rs | 35 ++++++----------------------------- src/bootstrap/test.rs | 4 ++-- src/bootstrap/tool.rs | 23 +++++++++-------------- 4 files changed, 19 insertions(+), 49 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 229851238f1d0..d553dd4e0425f 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -451,14 +451,12 @@ macro_rules! tool_check_step { } tool_check_step!(Rustdoc, "src/tools/rustdoc", "src/librustdoc", SourceType::InTree); -// Clippy and Rustfmt are hybrids. They are external tools, but use a git subtree instead +// Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead // of a submodule. Since the SourceType only drives the deny-warnings // behavior, treat it as in-tree so that any new warnings in clippy will be // rejected. tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree); -// Miri on the other hand is treated as out of tree, since InTree also causes it to -// be run as part of `check`, which can fail on platforms which libffi-sys has no support for. -tool_check_step!(Miri, "src/tools/miri", SourceType::Submodule); +tool_check_step!(Miri, "src/tools/miri", SourceType::InTree); tool_check_step!(Rls, "src/tools/rls", SourceType::InTree); tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 819af6587484d..eaeb5674d7d1e 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -734,7 +734,7 @@ impl Step for Rustc { } macro_rules! tool_doc { - ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?], in_tree = $in_tree:expr $(,)?) => { + ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(,)?) => { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct $tool { target: TargetSelection, @@ -790,12 +790,6 @@ macro_rules! tool_doc { t!(fs::create_dir_all(&out_dir)); t!(symlink_dir_force(&builder.config, &out, &out_dir)); - let source_type = if $in_tree == true { - SourceType::InTree - } else { - SourceType::Submodule - }; - // Build cargo command. let mut cargo = prepare_tool_cargo( builder, @@ -804,7 +798,7 @@ macro_rules! tool_doc { target, "doc", $path, - source_type, + SourceType::InTree, &[], ); @@ -820,38 +814,21 @@ macro_rules! tool_doc { cargo.rustdocflag("--show-type-layout"); cargo.rustdocflag("--generate-link-to-definition"); cargo.rustdocflag("-Zunstable-options"); - if $in_tree == true { - builder.run(&mut cargo.into()); - } else { - // Allow out-of-tree docs to fail (since the tool might be in a broken state). - if !builder.try_run(&mut cargo.into()) { - builder.info(&format!( - "WARNING: tool {} failed to document; ignoring failure because it is an out-of-tree tool", - stringify!($tool).to_lowercase(), - )); - } - } + builder.run(&mut cargo.into()); } } } } -tool_doc!( - Rustdoc, - "rustdoc-tool", - "src/tools/rustdoc", - ["rustdoc", "rustdoc-json-types"], - in_tree = true -); +tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", ["rustdoc", "rustdoc-json-types"],); tool_doc!( Rustfmt, "rustfmt-nightly", "src/tools/rustfmt", ["rustfmt-nightly", "rustfmt-config_proc_macro"], - in_tree = true ); -tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"], in_tree = true); -tool_doc!(Miri, "miri", "src/tools/miri", ["miri"], in_tree = false); +tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"]); +tool_doc!(Miri, "miri", "src/tools/miri", ["miri"]); #[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ErrorIndex { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 8d4914097787f..45d46f57d6e7c 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -503,7 +503,7 @@ impl Step for Miri { host, "run", "src/tools/miri/cargo-miri", - SourceType::Submodule, + SourceType::InTree, &[], ); cargo.add_rustc_lib_path(builder, compiler); @@ -550,7 +550,7 @@ impl Step for Miri { host, "test", "src/tools/miri", - SourceType::Submodule, + SourceType::InTree, &[], ); cargo.add_rustc_lib_path(builder, compiler); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d6e7f7872703e..d2d5a3be5edb1 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -795,7 +795,6 @@ macro_rules! tool_extended { $path:expr, $tool_name:expr, stable = $stable:expr, - $(in_tree = $in_tree:expr,)? $(tool_std = $tool_std:literal,)? $extra_deps:block;)+) => { $( @@ -848,11 +847,7 @@ macro_rules! tool_extended { path: $path, extra_features: $sel.extra_features, is_optional_tool: true, - source_type: if false $(|| $in_tree)* { - SourceType::InTree - } else { - SourceType::Submodule - }, + source_type: SourceType::InTree, }) } } @@ -865,17 +860,17 @@ macro_rules! tool_extended { // Note: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to // invoke Cargo to build bootstrap. See the comment there for more details. tool_extended!((self, builder), - Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {}; - CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {}; - Clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {}; - Miri, "src/tools/miri", "miri", stable=false, in_tree=true, {}; - CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, in_tree=true, {}; + Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true, {}; + CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true, {}; + Clippy, "src/tools/clippy", "clippy-driver", stable=true, {}; + Miri, "src/tools/miri", "miri", stable=false, {}; + CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true, {}; // FIXME: tool_std is not quite right, we shouldn't allow nightly features. // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0, // and this is close enough for now. - Rls, "src/tools/rls", "rls", stable=true, in_tree=true, tool_std=true, {}; - RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {}; - Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {}; + Rls, "src/tools/rls", "rls", stable=true, tool_std=true, {}; + RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true, {}; + Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, {}; ); impl<'a> Builder<'a> { From c4b9b6532bb7742f97863f59629c8b797654ceea Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 13 Oct 2022 07:38:29 +0000 Subject: [PATCH 3/6] Remove unused macro argument --- src/bootstrap/tool.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d2d5a3be5edb1..27dccf7938a3e 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -794,9 +794,9 @@ macro_rules! tool_extended { $($name:ident, $path:expr, $tool_name:expr, - stable = $stable:expr, - $(tool_std = $tool_std:literal,)? - $extra_deps:block;)+) => { + stable = $stable:expr + $(,tool_std = $tool_std:literal)? + ;)+) => { $( #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct $name { @@ -838,7 +838,6 @@ macro_rules! tool_extended { #[allow(unused_mut)] fn run(mut $sel, $builder: &Builder<'_>) -> Option { - $extra_deps $builder.ensure(ToolBuild { compiler: $sel.compiler, target: $sel.target, @@ -860,17 +859,17 @@ macro_rules! tool_extended { // Note: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to // invoke Cargo to build bootstrap. See the comment there for more details. tool_extended!((self, builder), - Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true, {}; - CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true, {}; - Clippy, "src/tools/clippy", "clippy-driver", stable=true, {}; - Miri, "src/tools/miri", "miri", stable=false, {}; - CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true, {}; + Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true; + CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true; + Clippy, "src/tools/clippy", "clippy-driver", stable=true; + Miri, "src/tools/miri", "miri", stable=false; + CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true; // FIXME: tool_std is not quite right, we shouldn't allow nightly features. // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0, // and this is close enough for now. - Rls, "src/tools/rls", "rls", stable=true, tool_std=true, {}; - RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true, {}; - Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, {}; + Rls, "src/tools/rls", "rls", stable=true, tool_std=true; + RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true; + Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true; ); impl<'a> Builder<'a> { From b3b6fbc8341a008347cad370af1210aa4efa3080 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Fri, 14 Oct 2022 01:42:23 +0000 Subject: [PATCH 4/6] Update pkg-config --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0cc7f8a1c7ce3..9f7cc44d160bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2652,9 +2652,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.18" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "polonius-engine" From 49f34bd8147a84229cc6641f2d386f09ee12c7e5 Mon Sep 17 00:00:00 2001 From: Gimgim <93856041+gimbles@users.noreply.github.com> Date: Sat, 15 Oct 2022 15:28:29 +0530 Subject: [PATCH 5/6] Surround type with backticks --- compiler/rustc_const_eval/src/transform/validate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 87b7c55bf7fb5..fbb129f97247e 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -284,7 +284,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { this.fail( location, format!( - "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is {:?}", + "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is `{:?}`", parent, f, ty, f_ty ) ) From 7334526c3803d9d9a5a9b017618aa95d618f687a Mon Sep 17 00:00:00 2001 From: Yutaro Ohno Date: Fri, 14 Oct 2022 17:53:09 +0900 Subject: [PATCH 6/6] pretty: fix to print some lifetimes on HIR pretty-print --- compiler/rustc_hir_pretty/src/lib.rs | 6 +++++- src/test/pretty/issue-85089.pp | 20 ++++++++++++++++++++ src/test/pretty/issue-85089.rs | 16 ++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/test/pretty/issue-85089.pp create mode 100644 src/test/pretty/issue-85089.rs diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 729139adc2de8..da27554a2292b 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1687,7 +1687,11 @@ impl<'a> State<'a> { let mut nonelided_generic_args: bool = false; let elide_lifetimes = generic_args.args.iter().all(|arg| match arg { - GenericArg::Lifetime(lt) => lt.is_elided(), + GenericArg::Lifetime(lt) if lt.is_elided() => true, + GenericArg::Lifetime(_) => { + nonelided_generic_args = true; + false + } _ => { nonelided_generic_args = true; true diff --git a/src/test/pretty/issue-85089.pp b/src/test/pretty/issue-85089.pp new file mode 100644 index 0000000000000..f84e9df04a2ac --- /dev/null +++ b/src/test/pretty/issue-85089.pp @@ -0,0 +1,20 @@ +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +// Test to print lifetimes on HIR pretty-printing. + +// pretty-compare-only +// pretty-mode:hir +// pp-exact:issue-85089.pp + +trait A<'x> { } +trait B<'x> { } + +struct Foo<'b> { + bar: &'b dyn for<'a> A<'a>, +} + +impl <'a> B<'a> for dyn for<'b> A<'b> { } + +impl <'a> A<'a> for Foo<'a> { } diff --git a/src/test/pretty/issue-85089.rs b/src/test/pretty/issue-85089.rs new file mode 100644 index 0000000000000..eb45d473119d4 --- /dev/null +++ b/src/test/pretty/issue-85089.rs @@ -0,0 +1,16 @@ +// Test to print lifetimes on HIR pretty-printing. + +// pretty-compare-only +// pretty-mode:hir +// pp-exact:issue-85089.pp + +trait A<'x> {} +trait B<'x> {} + +struct Foo<'b> { + pub bar: &'b dyn for<'a> A<'a>, +} + +impl<'a> B<'a> for dyn for<'b> A<'b> {} + +impl<'a> A<'a> for Foo<'a> {}