Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #122555

Merged
merged 16 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 8 additions & 22 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
use crate::diagnostics::{find_all_local_uses, CapturedMessageOpt};
use crate::{
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
InitializationRequiringAction, MirBorrowckCtxt, WriteKind,
};

use super::{
Expand Down Expand Up @@ -114,7 +114,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
self.buffer_error(err);
} else {
if let Some((reported_place, _)) = self.has_move_error(&move_out_indices) {
if self.prefixes(*reported_place, PrefixSet::All).any(|p| p == used_place) {
if used_place.is_prefix_of(*reported_place) {
debug!(
"report_use_of_moved_or_uninitialized place: error suppressed mois={:?}",
move_out_indices
Expand Down Expand Up @@ -422,8 +422,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(None, &[][..], 0)
};
if let Some(def_id) = def_id
&& let node =
self.infcx.tcx.hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id))
&& let node = self.infcx.tcx.hir_node_by_def_id(def_id)
&& let Some(fn_sig) = node.fn_sig()
&& let Some(ident) = node.ident()
&& let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
Expand Down Expand Up @@ -1995,34 +1994,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
kind: Option<WriteKind>,
) {
let drop_span = place_span.1;
let root_place =
self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap();
let borrowed_local = borrow.borrowed_place.local;

let borrow_spans = self.retrieve_borrow_spans(borrow);
let borrow_span = borrow_spans.var_or_use_path_span();

assert!(root_place.projection.is_empty());
let proper_span = self.body.local_decls[root_place.local].source_info.span;

let root_place_projection = self.infcx.tcx.mk_place_elems(root_place.projection);
let proper_span = self.body.local_decls[borrowed_local].source_info.span;

if self.access_place_error_reported.contains(&(
Place { local: root_place.local, projection: root_place_projection },
borrow_span,
)) {
if self.access_place_error_reported.contains(&(Place::from(borrowed_local), borrow_span)) {
debug!(
"suppressing access_place error when borrow doesn't live long enough for {:?}",
borrow_span
);
return;
}

self.access_place_error_reported.insert((
Place { local: root_place.local, projection: root_place_projection },
borrow_span,
));
self.access_place_error_reported.insert((Place::from(borrowed_local), borrow_span));

let borrowed_local = borrow.borrowed_place.local;
if self.body.local_decls[borrowed_local].is_ref_to_thread_local() {
let err =
self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span);
Expand Down Expand Up @@ -2544,9 +2532,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
};
(format!("{local_kind}`{place_desc}`"), format!("`{place_desc}` is borrowed here"))
} else {
let root_place =
self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap();
let local = root_place.local;
let local = borrow.borrowed_place.local;
match self.body.local_kind(local) {
LocalKind::Arg => (
"function parameter".to_string(),
Expand Down
11 changes: 3 additions & 8 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,11 +672,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
(
true,
td.as_local().and_then(|tld| match self.infcx.tcx.opt_hir_node_by_def_id(tld) {
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, _, _, items),
..
})) => {
td.as_local().and_then(|tld| match self.infcx.tcx.hir_node_by_def_id(tld) {
Node::Item(hir::Item { kind: hir::ItemKind::Trait(_, _, _, _, items), .. }) => {
let mut f_in_trait_opt = None;
for hir::TraitItemRef { id: fi, kind: k, .. } in *items {
let hi = fi.hir_id();
Expand Down Expand Up @@ -1475,11 +1472,9 @@ fn get_mut_span_in_struct_field<'tcx>(
if let ty::Ref(_, ty, _) = ty.kind()
&& let ty::Adt(def, _) = ty.kind()
&& let field = def.all_fields().nth(field.index())?
// Use the HIR types to construct the diagnostic message.
&& let node = tcx.opt_hir_node_by_def_id(field.did.as_local()?)?
// Now we're dealing with the actual struct that we're going to suggest a change to,
// we can expect a field that is an immutable reference to a type.
&& let hir::Node::Field(field) = node
&& let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.as_local()?)
&& let hir::TyKind::Ref(lt, hir::MutTy { mutbl: hir::Mutability::Not, ty }) = field.ty.kind
{
return Some(lt.ident.span.between(ty.span));
Expand Down
89 changes: 21 additions & 68 deletions compiler/rustc_borrowck/src/prefixes.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
//! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an
//! place are formed by stripping away fields and derefs, except that
//! we stop when we reach the deref of a shared reference. [...] "
//!
//! From the NLL RFC:
//! "Shallow prefixes are found by stripping away fields, but stop at
//! any dereference. So: writing a path like `a` is illegal if `a.b`
//! is borrowed. But: writing `a` is legal if `*a` is borrowed,
//! whether or not `a` is a shared or mutable reference. [...] "

use super::MirBorrowckCtxt;

use rustc_hir as hir;
use rustc_middle::mir::{Body, PlaceRef, ProjectionElem};
use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::mir::{PlaceRef, ProjectionElem};

pub trait IsPrefixOf<'tcx> {
fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool;
Expand All @@ -25,9 +20,7 @@ impl<'tcx> IsPrefixOf<'tcx> for PlaceRef<'tcx> {
}
}

pub(super) struct Prefixes<'cx, 'tcx> {
body: &'cx Body<'tcx>,
tcx: TyCtxt<'tcx>,
pub(super) struct Prefixes<'tcx> {
kind: PrefixSet,
next: Option<PlaceRef<'tcx>>,
}
Expand All @@ -39,24 +32,18 @@ pub(super) enum PrefixSet {
All,
/// Stops at any dereference.
Shallow,
/// Stops at the deref of a shared reference.
Supporting,
}

impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// Returns an iterator over the prefixes of `place`
/// (inclusive) from longest to smallest, potentially
/// terminating the iteration early based on `kind`.
pub(super) fn prefixes(
&self,
place_ref: PlaceRef<'tcx>,
kind: PrefixSet,
) -> Prefixes<'cx, 'tcx> {
Prefixes { next: Some(place_ref), kind, body: self.body, tcx: self.infcx.tcx }
pub(super) fn prefixes(&self, place_ref: PlaceRef<'tcx>, kind: PrefixSet) -> Prefixes<'tcx> {
Prefixes { next: Some(place_ref), kind }
}
}

impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
impl<'tcx> Iterator for Prefixes<'tcx> {
type Item = PlaceRef<'tcx>;
fn next(&mut self) -> Option<Self::Item> {
let mut cursor = self.next?;
Expand Down Expand Up @@ -91,57 +78,23 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
panic!("Subtype projection is not allowed before borrow check")
}
ProjectionElem::Deref => {
// (handled below)
match self.kind {
PrefixSet::Shallow => {
// Shallow prefixes are found by stripping away
// fields, but stop at *any* dereference.
// So we can just stop the traversal now.
self.next = None;
return Some(cursor);
}
PrefixSet::All => {
// All prefixes: just blindly enqueue the base
// of the projection.
self.next = Some(cursor_base);
return Some(cursor);
}
}
}
}

assert_eq!(elem, ProjectionElem::Deref);

match self.kind {
PrefixSet::Shallow => {
// Shallow prefixes are found by stripping away
// fields, but stop at *any* dereference.
// So we can just stop the traversal now.
self.next = None;
return Some(cursor);
}
PrefixSet::All => {
// All prefixes: just blindly enqueue the base
// of the projection.
self.next = Some(cursor_base);
return Some(cursor);
}
PrefixSet::Supporting => {
// Fall through!
}
}

assert_eq!(self.kind, PrefixSet::Supporting);
// Supporting prefixes: strip away fields and
// derefs, except we stop at the deref of a shared
// reference.

let ty = cursor_base.ty(self.body, self.tcx).ty;
match ty.kind() {
ty::RawPtr(_) | ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Not) => {
// don't continue traversing over derefs of raw pointers or shared
// borrows.
self.next = None;
return Some(cursor);
}

ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Mut) => {
self.next = Some(cursor_base);
return Some(cursor);
}

ty::Adt(..) if ty.is_box() => {
self.next = Some(cursor_base);
return Some(cursor);
}

_ => panic!("unknown type fed to Projection Deref."),
}
}
}
}
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_hir_analysis/src/check/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir_node(hir_id) {
match tcx.hir_node_by_def_id(def_id.expect_local()) {
Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) => {
generics.params.is_empty().not().then_some(generics.span)
}
Expand All @@ -57,8 +56,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir_node(hir_id) {
match tcx.hir_node_by_def_id(def_id.expect_local()) {
Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) => {
Some(generics.where_clause_span)
}
Expand All @@ -79,8 +77,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir_node(hir_id) {
match tcx.hir_node_by_def_id(def_id.expect_local()) {
Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. }) => {
Some(fn_sig.decl.output.span())
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ fn get_owner_return_paths(
) -> Option<(LocalDefId, ReturnsVisitor<'_>)> {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let parent_id = tcx.hir().get_parent_item(hir_id).def_id;
tcx.opt_hir_node_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| {
tcx.hir_node_by_def_id(parent_id).body_id().map(|body_id| {
let body = tcx.hir().body(body_id);
let mut visitor = ReturnsVisitor::default();
visitor.visit_body(body);
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1969,13 +1969,10 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
// Match the existing behavior.
if pred.is_global() && !pred.has_type_flags(TypeFlags::HAS_BINDER_VARS) {
let pred = self.normalize(span, None, pred);
let hir_node = tcx.opt_hir_node_by_def_id(self.body_def_id);

// only use the span of the predicate clause (#90869)

if let Some(hir::Generics { predicates, .. }) =
hir_node.and_then(|node| node.generics())
{
let hir_node = tcx.hir_node_by_def_id(self.body_def_id);
if let Some(hir::Generics { predicates, .. }) = hir_node.generics() {
span = predicates
.iter()
// There seems to be no better way to find out which predicate we are in
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,10 +609,8 @@ pub(super) fn implied_predicates_with_filter(
return tcx.super_predicates_of(trait_def_id);
};

let trait_hir_id = tcx.local_def_id_to_hir_id(trait_def_id);

let Node::Item(item) = tcx.hir_node(trait_hir_id) else {
bug!("trait_node_id {} is not an item", trait_hir_id);
let Node::Item(item) = tcx.hir_node_by_def_id(trait_def_id) else {
bug!("trait_def_id {trait_def_id:?} is not an item");
};

let (generics, bounds) = match item.kind {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,11 +371,10 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
return mir_opaque_ty.ty;
}

let scope = tcx.local_def_id_to_hir_id(owner_def_id);
debug!(?scope);
debug!(?owner_def_id);
let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty };

match tcx.hir_node(scope) {
match tcx.hir_node_by_def_id(owner_def_id) {
Node::Item(it) => intravisit::walk_item(&mut locator, it),
Node::ImplItem(it) => intravisit::walk_impl_item(&mut locator, it),
Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it),
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_hir_typeck/src/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

// Next, make sure that we have no type expectation.
let Some(ret) = self
.tcx
.opt_hir_node_by_def_id(self.body_id)
.and_then(|owner| owner.fn_decl())
.map(|decl| decl.output.span())
let Some(ret) =
self.tcx.hir_node_by_def_id(self.body_id).fn_decl().map(|decl| decl.output.span())
else {
return;
};
Expand Down
16 changes: 7 additions & 9 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -890,21 +890,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let encl_item_id = self.tcx.hir().get_parent_item(expr.hir_id);

if let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(..),
span: encl_fn_span,
..
}))
| Some(hir::Node::TraitItem(hir::TraitItem {
if let hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(..), span: encl_fn_span, ..
})
| hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
span: encl_fn_span,
..
}))
| Some(hir::Node::ImplItem(hir::ImplItem {
})
| hir::Node::ImplItem(hir::ImplItem {
kind: hir::ImplItemKind::Fn(..),
span: encl_fn_span,
..
})) = self.tcx.opt_hir_node_by_def_id(encl_item_id.def_id)
}) = self.tcx.hir_node_by_def_id(encl_item_id.def_id)
{
// We are inside a function body, so reporting "return statement
// outside of function body" needs an explanation.
Expand Down
15 changes: 5 additions & 10 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2172,16 +2172,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Try to find earlier invocations of this closure to find if the type mismatch
// is because of inference. If we find one, point at them.
let mut call_finder = FindClosureArg { tcx: self.tcx, calls: vec![] };
let node = self
.tcx
.opt_local_def_id_to_hir_id(
self.tcx.hir().get_parent_item(call_expr.hir_id).def_id,
)
.map(|hir_id| self.tcx.hir_node(hir_id));
match node {
Some(hir::Node::Item(item)) => call_finder.visit_item(item),
Some(hir::Node::TraitItem(item)) => call_finder.visit_trait_item(item),
Some(hir::Node::ImplItem(item)) => call_finder.visit_impl_item(item),
let parent_def_id = self.tcx.hir().get_parent_item(call_expr.hir_id).def_id;
match self.tcx.hir_node_by_def_id(parent_def_id) {
hir::Node::Item(item) => call_finder.visit_item(item),
hir::Node::TraitItem(item) => call_finder.visit_trait_item(item),
hir::Node::ImplItem(item) => call_finder.visit_impl_item(item),
_ => {}
}
let typeck = self.typeck_results.borrow();
Expand Down
Loading
Loading