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 8 pull requests #125349

Merged
merged 29 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cfb0479
Fix `read_exact` and `read_buf_exact` for `&[u8]` and `io:Cursor`
a1phyr May 14, 2024
b092b5d
Note for E0599 if shadowed bindings has the method.
surechen Apr 23, 2024
a197ff3
Address review comments
a1phyr May 20, 2024
8d3bc55
Fix up a few more tests
saethlin Apr 17, 2024
e0632d7
Add only-unix to sigpipe tests
saethlin Apr 18, 2024
18b0a07
Handle a few more simple tests
saethlin Apr 18, 2024
281178d
Add a Windows version of foreign2.rs
saethlin Apr 18, 2024
70147cd
Patch up foreign-fn-linkname.rs
saethlin Apr 18, 2024
7a906e1
Port stdout-during-shutdown
saethlin Apr 18, 2024
f45a7a2
Fix feature-gates/rustc-private.rs
saethlin Apr 18, 2024
30379f9
Update tests/incremental/foreign.rs
saethlin Apr 19, 2024
aa31281
Remove Windows dependency on libc
saethlin Apr 18, 2024
39ef149
Undo accidental change to tests/ui/sanitizer/thread.rs
saethlin May 14, 2024
ba8fba9
Update books
rustbot May 20, 2024
c170bf9
switch to the default implementation of `write_vectored`
stlankes May 20, 2024
7b1527f
hir pretty: fix block indent
Noratrieb May 15, 2024
d39dc0a
switch also the default implementation for read_vectored
stlankes May 20, 2024
82df0c3
move fixpoint step into subfunction
lcnr May 13, 2024
ee0f20b
move global cache lookup into fn
lcnr May 13, 2024
f99c9ff
track cycle participants per entry
lcnr May 20, 2024
fa1b7f2
Remove some `Path::to_str` from `rustc_codegen_llvm`
tbu- May 20, 2024
8903de3
Rollup merge of #124050 - saethlin:less-sysroot-libc, r=ChrisDenton
matthiaskrgr May 20, 2024
e275d2d
Rollup merge of #124283 - surechen:fix_123558, r=estebank
matthiaskrgr May 20, 2024
62da957
Rollup merge of #125123 - a1phyr:fix-read_exact, r=workingjubilee
matthiaskrgr May 20, 2024
4b26045
Rollup merge of #125158 - Nilstrieb:block-indent, r=compiler-errors
matthiaskrgr May 20, 2024
e97103f
Rollup merge of #125308 - lcnr:search-graph-5, r=compiler-errors
matthiaskrgr May 20, 2024
75728fe
Rollup merge of #125332 - rustbot:docs-update, r=ehuss
matthiaskrgr May 20, 2024
73bb47e
Rollup merge of #125333 - hermit-os:fuse, r=workingjubilee
matthiaskrgr May 20, 2024
63fa01e
Rollup merge of #125346 - tbu-:pr_rm_path_to_str, r=wesleywiser
matthiaskrgr May 20, 2024
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
29 changes: 14 additions & 15 deletions compiler/rustc_codegen_llvm/src/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,21 +200,20 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
_ => panic!("unsupported arch {}", sess.target.arch),
};
let mut dlltool_cmd = std::process::Command::new(&dlltool);
dlltool_cmd.args([
"-d",
def_file_path.to_str().unwrap(),
"-D",
lib_name,
"-l",
output_path.to_str().unwrap(),
"-m",
dlltool_target_arch,
"-f",
dlltool_target_bitness,
"--no-leading-underscore",
"--temp-prefix",
temp_prefix.to_str().unwrap(),
]);
dlltool_cmd
.arg("-d")
.arg(def_file_path)
.arg("-D")
.arg(lib_name)
.arg("-l")
.arg(&output_path)
.arg("-m")
.arg(dlltool_target_arch)
.arg("-f")
.arg(dlltool_target_bitness)
.arg("--no-leading-underscore")
.arg("--temp-prefix")
.arg(temp_prefix);

match dlltool_cmd.output() {
Err(e) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1454,7 +1454,7 @@ impl<'a> State<'a> {
self.word_space(":");
}
// containing cbox, will be closed by print-block at `}`
self.cbox(INDENT_UNIT);
self.cbox(0);
// head-box, will be closed by print-block after `{`
self.ibox(0);
self.print_block(blk);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if segment.ident.name != kw::Empty {
if let Some(err) = self.report_method_error(
span,
Some(rcvr),
rcvr_t,
segment.ident,
SelfSource::MethodCall(rcvr),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if item_name.name != kw::Empty {
if let Some(e) = self.report_method_error(
span,
None,
ty.normalized,
item_name,
SelfSource::QPath(qself),
Expand Down
213 changes: 207 additions & 6 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::errors::{self, CandidateTraitNote, NoAssociatedItem};
use crate::Expectation;
use crate::FnCtxt;
use core::ops::ControlFlow;
use hir::Expr;
use rustc_ast::ast::Mutability;
use rustc_attr::parse_confusables;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
Expand All @@ -19,7 +20,6 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_hir::PatKind::Binding;
use rustc_hir::PathSegment;
use rustc_hir::{ExprKind, Node, QPath};
use rustc_infer::infer::{self, RegionVariableOrigin};
Expand All @@ -46,7 +46,7 @@ use std::borrow::Cow;

use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope};
use super::{CandidateSource, MethodError, NoMatchData};
use rustc_hir::intravisit::Visitor;
use rustc_hir::intravisit::{self, Visitor};

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
Expand Down Expand Up @@ -188,6 +188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn report_method_error(
&self,
span: Span,
rcvr_opt: Option<&'tcx hir::Expr<'tcx>>,
rcvr_ty: Ty<'tcx>,
item_name: Ident,
source: SelfSource<'tcx>,
Expand All @@ -212,6 +213,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
MethodError::NoMatch(mut no_match_data) => {
return self.report_no_match_method_error(
span,
rcvr_opt,
rcvr_ty,
item_name,
source,
Expand Down Expand Up @@ -356,9 +358,197 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err
}

pub fn suggest_use_shadowed_binding_with_method(
&self,
rcvr_opt: Option<&'tcx hir::Expr<'tcx>>,
method_name: Ident,
ty_str_reported: &str,
err: &mut Diag<'_>,
) {
#[derive(Debug)]
struct LetStmt {
ty_hir_id_opt: Option<hir::HirId>,
binding_id: hir::HirId,
span: Span,
init_hir_id: hir::HirId,
}

// Used for finding suggest binding.
// ```rust
// earlier binding for suggesting:
// let y = vec![1, 2];
// now binding:
// if let Some(y) = x {
// y.push(y);
// }
// ```
struct LetVisitor<'a, 'tcx> {
// Error binding which don't have `method_name`.
binding_name: Symbol,
binding_id: hir::HirId,
// Used for check if the suggest binding has `method_name`.
fcx: &'a FnCtxt<'a, 'tcx>,
call_expr: &'tcx Expr<'tcx>,
method_name: Ident,
// Suggest the binding which is shallowed.
sugg_let: Option<LetStmt>,
}

impl<'a, 'tcx> LetVisitor<'a, 'tcx> {
// Check scope of binding.
fn is_sub_scope(&self, sub_id: hir::ItemLocalId, super_id: hir::ItemLocalId) -> bool {
let scope_tree = self.fcx.tcx.region_scope_tree(self.fcx.body_id);
if let Some(sub_var_scope) = scope_tree.var_scope(sub_id)
&& let Some(super_var_scope) = scope_tree.var_scope(super_id)
&& scope_tree.is_subscope_of(sub_var_scope, super_var_scope)
{
return true;
}
false
}

// Check if an earlier shadowed binding make `the receiver` of a MethodCall has the method.
// If it does, record the earlier binding for subsequent notes.
fn check_and_add_sugg_binding(&mut self, binding: LetStmt) -> bool {
if !self.is_sub_scope(self.binding_id.local_id, binding.binding_id.local_id) {
return false;
}

// Get the earlier shadowed binding'ty and use it to check the method.
if let Some(ty_hir_id) = binding.ty_hir_id_opt
&& let Some(tyck_ty) = self.fcx.node_ty_opt(ty_hir_id)
{
if self
.fcx
.lookup_probe_for_diagnostic(
self.method_name,
tyck_ty,
self.call_expr,
ProbeScope::TraitsInScope,
None,
)
.is_ok()
{
self.sugg_let = Some(binding);
return true;
} else {
return false;
}
}

// If the shadowed binding has an an itializer expression,
// use the initializer expression'ty to try to find the method again.
// For example like: `let mut x = Vec::new();`,
// `Vec::new()` is the itializer expression.
if let Some(self_ty) = self.fcx.node_ty_opt(binding.init_hir_id)
&& self
.fcx
.lookup_probe_for_diagnostic(
self.method_name,
self_ty,
self.call_expr,
ProbeScope::TraitsInScope,
None,
)
.is_ok()
{
self.sugg_let = Some(binding);
return true;
}
return false;
}
}

impl<'v> Visitor<'v> for LetVisitor<'_, '_> {
type Result = ControlFlow<()>;
fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) -> Self::Result {
if let hir::StmtKind::Let(&hir::LetStmt { pat, ty, init, .. }) = ex.kind
&& let hir::PatKind::Binding(_, binding_id, binding_name, ..) = pat.kind
&& let Some(init) = init
&& binding_name.name == self.binding_name
&& binding_id != self.binding_id
{
if self.check_and_add_sugg_binding(LetStmt {
ty_hir_id_opt: if let Some(ty) = ty { Some(ty.hir_id) } else { None },
binding_id: binding_id,
span: pat.span,
init_hir_id: init.hir_id,
}) {
return ControlFlow::Break(());
}
ControlFlow::Continue(())
} else {
hir::intravisit::walk_stmt(self, ex)
}
}

// Used for find the error binding.
// When the visitor reaches this point, all the shadowed bindings
// have been found, so the visitor ends.
fn visit_pat(&mut self, p: &'v hir::Pat<'v>) -> Self::Result {
match p.kind {
hir::PatKind::Binding(_, binding_id, binding_name, _) => {
if binding_name.name == self.binding_name && binding_id == self.binding_id {
return ControlFlow::Break(());
}
}
_ => {
intravisit::walk_pat(self, p);
}
}
ControlFlow::Continue(())
}
}

if let Some(rcvr) = rcvr_opt
&& let hir::ExprKind::Path(QPath::Resolved(_, path)) = rcvr.kind
&& let hir::def::Res::Local(recv_id) = path.res
&& let Some(segment) = path.segments.first()
{
let map = self.infcx.tcx.hir();
let body_id = self.tcx.hir().body_owned_by(self.body_id);
let body = map.body(body_id);

if let Node::Expr(call_expr) = self.tcx.parent_hir_node(rcvr.hir_id) {
let mut let_visitor = LetVisitor {
fcx: self,
call_expr,
binding_name: segment.ident.name,
binding_id: recv_id,
method_name,
sugg_let: None,
};
let_visitor.visit_body(body);
if let Some(sugg_let) = let_visitor.sugg_let
&& let Some(self_ty) = self.node_ty_opt(sugg_let.init_hir_id)
{
let _sm = self.infcx.tcx.sess.source_map();
let rcvr_name = segment.ident.name;
let mut span = MultiSpan::from_span(sugg_let.span);
span.push_span_label(sugg_let.span,
format!("`{rcvr_name}` of type `{self_ty}` that has method `{method_name}` defined earlier here"));
span.push_span_label(
self.tcx.hir().span(recv_id),
format!(
"earlier `{rcvr_name}` shadowed here with type `{ty_str_reported}`"
),
);
err.span_note(
span,
format!(
"there's an earlier shadowed binding `{rcvr_name}` of type `{self_ty}` \
that has method `{method_name}` available"
),
);
}
}
}
}

pub fn report_no_match_method_error(
&self,
mut span: Span,
rcvr_opt: Option<&'tcx hir::Expr<'tcx>>,
rcvr_ty: Ty<'tcx>,
item_name: Ident,
source: SelfSource<'tcx>,
Expand Down Expand Up @@ -451,7 +641,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source {
self.suggest_missing_writer(rcvr_ty, rcvr_expr)
} else {
tcx.dcx().create_err(NoAssociatedItem {
let mut err = tcx.dcx().create_err(NoAssociatedItem {
span,
item_kind,
item_name,
Expand All @@ -461,9 +651,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
rcvr_ty.prefix_string(self.tcx)
},
ty_str: ty_str_reported,
ty_str: ty_str_reported.clone(),
trait_missing_method,
})
});

if is_method {
self.suggest_use_shadowed_binding_with_method(
rcvr_opt,
item_name,
&ty_str_reported,
&mut err,
);
}

err
};
if tcx.sess.source_map().is_multiline(sugg_span) {
err.span_label(sugg_span.with_hi(span.lo()), "");
Expand Down Expand Up @@ -2240,7 +2441,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
type Result = ControlFlow<Option<&'v hir::Expr<'v>>>;
fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) -> Self::Result {
if let hir::StmtKind::Let(&hir::LetStmt { pat, init, .. }) = ex.kind
&& let Binding(_, _, ident, ..) = pat.kind
&& let hir::PatKind::Binding(_, _, ident, ..) = pat.kind
&& ident.name == self.ident_name
{
ControlFlow::Break(init)
Expand Down
Loading
Loading