Skip to content

Commit

Permalink
Auto merge of rust-lang#123823 - matthiaskrgr:rollup-8zdtggx, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#122882 (Avoid a panic in `set_output_capture` in the default panic handler)
 - rust-lang#123523 (Account for trait/impl difference when suggesting changing argument from ref to mut ref)
 - rust-lang#123744 (Silence `unused_imports` for redundant imports)
 - rust-lang#123784 (Replace `document.write` with `document.head.insertAdjacent`)
 - rust-lang#123798 (Avoid invalid socket address in length calculation)
 - rust-lang#123804 (Stop using `HirId` for fn-like parents since closures are not `OwnerNode`s)
 - rust-lang#123806 (Panic on overflow in `BorrowedCursor::advance`)
 - rust-lang#123820 (Add my former address to .mailmap)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Apr 11, 2024
2 parents 616a8f8 + d2e9ec7 commit a07f3eb
Show file tree
Hide file tree
Showing 46 changed files with 330 additions and 367 deletions.
1 change: 1 addition & 0 deletions .mailmap
Expand Up @@ -543,6 +543,7 @@ Takashi Idobe <idobetakashi@gmail.com>
Takayuki Maeda <takoyaki0316@gmail.com>
Tamir Duberstein <tamird@gmail.com> Tamir Duberstein <tamird@squareup.com>
Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
Tau Gärtli <git@tau.garden> <ruben.schmidmeister@icloud.com>
Tero Hänninen <lgvz@users.noreply.github.com> Tero Hänninen <tejohann@kapsi.fi>
The8472 <git@infinite-source.de>
Theo Belaire <theo.belaire@gmail.com> Theo Belaire <tyr.god.of.war.42@gmail.com>
Expand Down
89 changes: 54 additions & 35 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Expand Up @@ -21,7 +21,7 @@ use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;

use crate::diagnostics::BorrowedContentSource;
use crate::util::FindAssignments;
use crate::MirBorrowckCtxt;
use crate::{session_diagnostics, MirBorrowckCtxt};

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(crate) enum AccessKind {
Expand Down Expand Up @@ -234,7 +234,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
Some(mir::BorrowKind::Mut { kind: mir::MutBorrowKind::Default }),
|_kind, var_span| {
let place = self.describe_any_place(access_place.as_ref());
crate::session_diagnostics::CaptureVarCause::MutableBorrowUsePlaceClosure {
session_diagnostics::CaptureVarCause::MutableBorrowUsePlaceClosure {
place,
var_span,
}
Expand Down Expand Up @@ -667,19 +667,26 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// User cannot make signature of a trait mutable without changing the
/// trait. So we find if this error belongs to a trait and if so we move
/// suggestion to the trait or disable it if it is out of scope of this crate
fn is_error_in_trait(&self, local: Local) -> (bool, Option<Span>) {
///
/// The returned values are:
/// - is the current item an assoc `fn` of an impl that corresponds to a trait def? if so, we
/// have to suggest changing both the impl `fn` arg and the trait `fn` arg
/// - is the trait from the local crate? If not, we can't suggest changing signatures
/// - `Span` of the argument in the trait definition
fn is_error_in_trait(&self, local: Local) -> (bool, bool, Option<Span>) {
if self.body.local_kind(local) != LocalKind::Arg {
return (false, None);
return (false, false, None);
}
let my_def = self.body.source.def_id();
let my_hir = self.infcx.tcx.local_def_id_to_hir_id(my_def.as_local().unwrap());
let Some(td) =
self.infcx.tcx.impl_of_method(my_def).and_then(|x| self.infcx.tcx.trait_id_of_impl(x))
else {
return (false, None);
return (false, false, None);
};
(
true,
td.is_local(),
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;
Expand All @@ -695,19 +702,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
break;
}
f_in_trait_opt.and_then(|f_in_trait| {
match self.infcx.tcx.hir_node(f_in_trait) {
Node::TraitItem(hir::TraitItem {
kind:
hir::TraitItemKind::Fn(
hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. },
_,
),
..
}) => {
let hir::Ty { span, .. } = *inputs.get(local.index() - 1)?;
Some(span)
}
_ => None,
if let Node::TraitItem(ti) = self.infcx.tcx.hir_node(f_in_trait)
&& let hir::TraitItemKind::Fn(sig, _) = ti.kind
&& let Some(ty) = sig.decl.inputs.get(local.index() - 1)
&& let hir::TyKind::Ref(_, mut_ty) = ty.kind
&& let hir::Mutability::Not = mut_ty.mutbl
&& sig.decl.implicit_self.has_implicit_self()
{
Some(ty.span)
} else {
None
}
})
}
Expand Down Expand Up @@ -1061,20 +1065,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let (pointer_sigil, pointer_desc) =
if local_decl.ty.is_ref() { ("&", "reference") } else { ("*const", "pointer") };

let (is_trait_sig, local_trait) = self.is_error_in_trait(local);
if is_trait_sig && local_trait.is_none() {
let (is_trait_sig, is_local, local_trait) = self.is_error_in_trait(local);

if is_trait_sig && !is_local {
// Do not suggest to change the signature when the trait comes from another crate.
err.span_label(
local_decl.source_info.span,
format!("this is an immutable {pointer_desc}"),
);
return;
}

let decl_span = match local_trait {
Some(span) => span,
None => local_decl.source_info.span,
};
let decl_span = local_decl.source_info.span;

let label = match *local_decl.local_info() {
LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => {
let suggestion = suggest_ampmut_self(self.infcx.tcx, decl_span);
Some((true, decl_span, suggestion))
let additional =
local_trait.map(|span| (span, suggest_ampmut_self(self.infcx.tcx, span)));
Some((true, decl_span, suggestion, additional))
}

LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
Expand Down Expand Up @@ -1113,7 +1121,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// don't create labels for compiler-generated spans
Some(_) => None,
None => {
let label = if name != kw::SelfLower {
let (has_sugg, decl_span, sugg) = if name != kw::SelfLower {
suggest_ampmut(
self.infcx.tcx,
local_decl.ty,
Expand All @@ -1140,7 +1148,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
),
}
};
Some(label)
Some((has_sugg, decl_span, sugg, None))
}
}
}
Expand All @@ -1151,22 +1159,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
})) => {
let pattern_span: Span = local_decl.source_info.span;
suggest_ref_mut(self.infcx.tcx, pattern_span)
.map(|span| (true, span, "mut ".to_owned()))
.map(|span| (true, span, "mut ".to_owned(), None))
}

_ => unreachable!(),
};

match label {
Some((true, err_help_span, suggested_code)) => {
err.span_suggestion_verbose(
err_help_span,
format!("consider changing this to be a mutable {pointer_desc}"),
suggested_code,
Some((true, err_help_span, suggested_code, additional)) => {
let mut sugg = vec![(err_help_span, suggested_code)];
if let Some(s) = additional {
sugg.push(s);
}

err.multipart_suggestion_verbose(
format!(
"consider changing this to be a mutable {pointer_desc}{}",
if is_trait_sig {
" in the `impl` method and the `trait` definition"
} else {
""
}
),
sugg,
Applicability::MachineApplicable,
);
}
Some((false, err_label_span, message)) => {
Some((false, err_label_span, message, _)) => {
let def_id = self.body.source.def_id();
let hir_id = if let Some(local_def_id) = def_id.as_local()
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
Expand Down
15 changes: 5 additions & 10 deletions compiler/rustc_hir_typeck/src/coercion.rs
Expand Up @@ -2004,16 +2004,17 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
}
}

let parent_id = fcx.tcx.hir().get_parent_item(id);
let mut parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id);
let mut parent_id = fcx.tcx.hir().get_parent_item(id).def_id;
let mut parent_item = fcx.tcx.hir_node_by_def_id(parent_id);
// When suggesting return, we need to account for closures and async blocks, not just items.
for (_, node) in fcx.tcx.hir().parent_iter(id) {
match node {
hir::Node::Expr(&hir::Expr {
kind: hir::ExprKind::Closure(hir::Closure { .. }),
kind: hir::ExprKind::Closure(hir::Closure { def_id, .. }),
..
}) => {
parent_item = node;
parent_id = *def_id;
break;
}
hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => break,
Expand All @@ -2023,13 +2024,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {

if let (Some(expr), Some(_), Some(fn_decl)) = (expression, blk_id, parent_item.fn_decl()) {
fcx.suggest_missing_break_or_return_expr(
&mut err,
expr,
fn_decl,
expected,
found,
id,
parent_id.into(),
&mut err, expr, fn_decl, expected, found, id, parent_id,
);
}

Expand Down
22 changes: 6 additions & 16 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Expand Up @@ -942,7 +942,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn get_node_fn_decl(
&self,
node: Node<'tcx>,
) -> Option<(hir::HirId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> {
) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> {
match node {
Node::Item(&hir::Item {
ident,
Expand All @@ -953,25 +953,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// This is less than ideal, it will not suggest a return type span on any
// method called `main`, regardless of whether it is actually the entry point,
// but it will still present it as the reason for the expected type.
Some((
hir::HirId::make_owner(owner_id.def_id),
&sig.decl,
ident,
ident.name != sym::main,
))
Some((owner_id.def_id, &sig.decl, ident, ident.name != sym::main))
}
Node::TraitItem(&hir::TraitItem {
ident,
kind: hir::TraitItemKind::Fn(ref sig, ..),
owner_id,
..
}) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, true)),
}) => Some((owner_id.def_id, &sig.decl, ident, true)),
Node::ImplItem(&hir::ImplItem {
ident,
kind: hir::ImplItemKind::Fn(ref sig, ..),
owner_id,
..
}) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, false)),
}) => Some((owner_id.def_id, &sig.decl, ident, false)),
Node::Expr(&hir::Expr {
hir_id,
kind:
Expand Down Expand Up @@ -1001,12 +996,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}) => (ident, sig, owner_id),
_ => return None,
};
Some((
hir::HirId::make_owner(owner_id.def_id),
&sig.decl,
ident,
ident.name != sym::main,
))
Some((owner_id.def_id, &sig.decl, ident, ident.name != sym::main))
}
_ => None,
}
Expand All @@ -1017,7 +1007,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn get_fn_decl(
&self,
blk_id: hir::HirId,
) -> Option<(hir::HirId, &'tcx hir::FnDecl<'tcx>, bool)> {
) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, bool)> {
// Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
// `while` before reaching it, as block tail returns are not available in them.
self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
Expand Down
18 changes: 10 additions & 8 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Expand Up @@ -9,6 +9,7 @@ use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
use crate::rustc_middle::ty::Article;
use core::cmp::min;
use core::iter;
use hir::def_id::LocalDefId;
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
use rustc_data_structures::packed::Pu128;
use rustc_errors::{Applicability, Diag, MultiSpan};
Expand Down Expand Up @@ -796,7 +797,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>,
found: Ty<'tcx>,
can_suggest: bool,
fn_id: hir::HirId,
fn_id: LocalDefId,
) -> bool {
let found =
self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
Expand Down Expand Up @@ -923,7 +924,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err: &mut Diag<'_>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
fn_id: hir::HirId,
fn_id: LocalDefId,
) {
// Only apply the suggestion if:
// - the return type is a generic parameter
Expand All @@ -937,7 +938,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let ty::Param(expected_ty_as_param) = expected.kind() else { return };

let fn_node = self.tcx.hir_node(fn_id);
let fn_node = self.tcx.hir_node_by_def_id(fn_id);

let hir::Node::Item(hir::Item {
kind:
Expand Down Expand Up @@ -1031,7 +1032,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>,
found: Ty<'tcx>,
id: hir::HirId,
fn_id: hir::HirId,
fn_id: LocalDefId,
) {
if !expected.is_unit() {
return;
Expand Down Expand Up @@ -1083,11 +1084,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let can_return = match fn_decl.output {
hir::FnRetTy::Return(ty) => {
let ty = self.lowerer().lower_ty(ty);
let bound_vars = self.tcx.late_bound_vars(fn_id);
let bound_vars = self.tcx.late_bound_vars(self.tcx.local_def_id_to_hir_id(fn_id));
let ty = self
.tcx
.instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars));
let ty = match self.tcx.asyncness(fn_id.owner) {
let ty = match self.tcx.asyncness(fn_id) {
ty::Asyncness::Yes => self.get_impl_future_output_ty(ty).unwrap_or_else(|| {
span_bug!(
fn_decl.output.span(),
Expand All @@ -1108,8 +1109,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => false,
};
if can_return
&& let Some(owner_node) = self.tcx.hir_node(fn_id).as_owner()
&& let Some(span) = expr.span.find_ancestor_inside(*owner_node.span())
&& let Some(span) = expr.span.find_ancestor_inside(
self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
)
{
err.multipart_suggestion(
"you might have meant to return this value",
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_resolve/src/imports.rs
Expand Up @@ -1391,13 +1391,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let mut redundant_spans: Vec<_> = redundant_span.present_items().collect();
redundant_spans.sort();
redundant_spans.dedup();
/* FIXME(unused_imports): Add this back as a new lint
self.lint_buffer.buffer_lint_with_diagnostic(
UNUSED_IMPORTS,
id,
import.span,
format!("the item `{source}` is imported redundantly"),
BuiltinLintDiag::RedundantImport(redundant_spans, source),
);
*/
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/lib.rs
Expand Up @@ -177,7 +177,7 @@ enum ImplTraitContext {

/// Used for tracking import use types which will be used for redundant import checking.
/// ### Used::Scope Example
/// ```rust,compile_fail
/// ```rust,ignore (redundant_imports)
/// #![deny(unused_imports)]
/// use std::mem::drop;
/// fn main() {
Expand Down
5 changes: 3 additions & 2 deletions library/core/src/io/borrowed_buf.rs
Expand Up @@ -249,9 +249,10 @@ impl<'a> BorrowedCursor<'a> {
/// Panics if there are less than `n` bytes initialized.
#[inline]
pub fn advance(&mut self, n: usize) -> &mut Self {
assert!(self.buf.init >= self.buf.filled + n);
let filled = self.buf.filled.strict_add(n);
assert!(filled <= self.buf.init);

self.buf.filled += n;
self.buf.filled = filled;
self
}

Expand Down

0 comments on commit a07f3eb

Please sign in to comment.