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 #136248

Merged
merged 16 commits into from
Jan 29, 2025
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
25 changes: 10 additions & 15 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,10 +1140,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {

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

LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
Expand Down Expand Up @@ -1202,10 +1201,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
opt_ty_info: None,
..
})) => {
let sugg = suggest_ampmut_self(self.infcx.tcx, decl_span);
let (span, sugg) =
suggest_ampmut_self(self.infcx.tcx, decl_span);
Some(AmpMutSugg {
has_sugg: true,
span: decl_span,
span,
suggestion: sugg,
additional: None,
})
Expand Down Expand Up @@ -1461,17 +1461,12 @@ fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symb
}
}

fn suggest_ampmut_self<'tcx>(tcx: TyCtxt<'tcx>, span: Span) -> String {
fn suggest_ampmut_self(tcx: TyCtxt<'_>, span: Span) -> (Span, String) {
match tcx.sess.source_map().span_to_snippet(span) {
Ok(snippet) => {
let lt_pos = snippet.find('\'');
if let Some(lt_pos) = lt_pos {
format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4])
} else {
"&mut self".to_string()
}
Ok(snippet) if snippet.ends_with("self") => {
(span.with_hi(span.hi() - BytePos(4)).shrink_to_hi(), "mut ".to_string())
}
_ => "&mut self".to_string(),
_ => (span, "&mut self".to_string()),
}
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub trait Callbacks {
fn after_crate_root_parsing(
&mut self,
_compiler: &interface::Compiler,
_queries: &ast::Crate,
_krate: &mut ast::Crate,
) -> Compilation {
Compilation::Continue
}
Expand Down Expand Up @@ -311,7 +311,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))

// Parse the crate root source code (doesn't parse submodules yet)
// Everything else is parsed during macro expansion.
let krate = passes::parse(sess);
let mut krate = passes::parse(sess);

// If pretty printing is requested: Figure out the representation, print it and exit
if let Some(pp_mode) = sess.opts.pretty {
Expand All @@ -328,7 +328,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
return early_exit();
}

if callbacks.after_crate_root_parsing(compiler, &krate) == Compilation::Stop {
if callbacks.after_crate_root_parsing(compiler, &mut krate) == Compilation::Stop {
return early_exit();
}

Expand Down
11 changes: 9 additions & 2 deletions compiler/rustc_hir_typeck/src/place_op.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_errors::Applicability;
use rustc_hir_analysis::autoderef::Autoderef;
use rustc_infer::infer::InferOk;
use rustc_infer::traits::{Obligation, ObligationCauseCode};
use rustc_middle::span_bug;
use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, OverloadedDeref,
Expand Down Expand Up @@ -136,8 +137,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut self_ty = adjusted_ty;
if unsize {
// We only unsize arrays here.
if let ty::Array(element_ty, _) = adjusted_ty.kind() {
self_ty = Ty::new_slice(self.tcx, *element_ty);
if let ty::Array(element_ty, ct) = *adjusted_ty.kind() {
self.register_predicate(Obligation::new(
self.tcx,
self.cause(base_expr.span, ObligationCauseCode::ArrayLen(adjusted_ty)),
self.param_env,
ty::ClauseKind::ConstArgHasType(ct, self.tcx.types.usize),
));
self_ty = Ty::new_slice(self.tcx, element_ty);
} else {
continue;
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ pub enum ObligationCauseCode<'tcx> {
/// A slice or array is WF only if `T: Sized`.
SliceOrArrayElem,

/// An array `[T; N]` can only be indexed (and is only well-formed if) `N` has type usize.
ArrayLen(Ty<'tcx>),

/// A tuple is WF only if its middle elements are `Sized`.
TupleElem,

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_trait_selection/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ trait_selection_explicit_lifetime_required_with_param_type = explicit lifetime r

trait_selection_fn_consider_casting = consider casting the fn item to a fn pointer: `{$casting}`

trait_selection_fn_consider_casting_both = consider casting both fn items to fn pointers using `as {$sig}`

trait_selection_fn_uniq_types = different fn items have unique types, even if their signatures are the same
trait_selection_fps_cast = consider casting to a fn pointer
trait_selection_fps_cast_both = consider casting both fn items to fn pointers using `as {$expected_sig}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1844,7 +1844,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
self.suggest_tuple_pattern(cause, &exp_found, diag);
self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag);
self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
self.suggest_function_pointers(cause, span, &exp_found, diag);
self.suggest_function_pointers(cause, span, &exp_found, terr, diag);
self.suggest_turning_stmt_into_expr(cause, &exp_found, diag);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use rustc_middle::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
StatementAsExpression,
};
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt};
use rustc_span::{Span, sym};
Expand All @@ -20,7 +21,7 @@ use tracing::debug;
use crate::error_reporting::TypeErrCtxt;
use crate::error_reporting::infer::hir::Path;
use crate::errors::{
ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes,
ConsiderAddingAwait, FnConsiderCasting, FnConsiderCastingBoth, FnItemsAreDistinct, FnUniqTypes,
FunctionPointerSuggestion, SuggestAccessingField, SuggestRemoveSemiOrReturnBinding,
SuggestTuplePatternMany, SuggestTuplePatternOne, TypeErrorAdditionalDiags,
};
Expand Down Expand Up @@ -381,14 +382,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}

pub(super) fn suggest_function_pointers(
pub fn suggest_function_pointers_impl(
&self,
cause: &ObligationCause<'tcx>,
span: Span,
span: Option<Span>,
exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
diag: &mut Diag<'_>,
) {
debug!("suggest_function_pointers(cause={:?}, exp_found={:?})", cause, exp_found);
let ty::error::ExpectedFound { expected, found } = exp_found;
let expected_inner = expected.peel_refs();
let found_inner = found.peel_refs();
Expand All @@ -411,6 +410,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
return;
}

let Some(span) = span else {
let casting = format!("{fn_name} as {sig}");
diag.subdiagnostic(FnItemsAreDistinct);
diag.subdiagnostic(FnConsiderCasting { casting });
return;
};

let sugg = match (expected.is_ref(), found.is_ref()) {
(true, false) => FunctionPointerSuggestion::UseRef { span, fn_name },
(false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name },
Expand Down Expand Up @@ -445,6 +451,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}

let fn_name = self.tcx.def_path_str_with_args(*did2, args2);

let Some(span) = span else {
diag.subdiagnostic(FnConsiderCastingBoth { sig: *expected_sig });
return;
};

let sug = if found.is_ref() {
FunctionPointerSuggestion::CastBothRef {
span,
Expand Down Expand Up @@ -488,6 +500,23 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
};
}

pub(super) fn suggest_function_pointers(
&self,
cause: &ObligationCause<'tcx>,
span: Span,
exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
terr: TypeError<'tcx>,
diag: &mut Diag<'_>,
) {
debug!("suggest_function_pointers(cause={:?}, exp_found={:?})", cause, exp_found);

if exp_found.expected.peel_refs().is_fn() && exp_found.found.peel_refs().is_fn() {
self.suggest_function_pointers_impl(Some(span), exp_found, diag);
} else if let TypeError::Sorts(exp_found) = terr {
self.suggest_function_pointers_impl(None, &exp_found, diag);
}
}

pub fn should_suggest_as_ref_kind(
&self,
expected: Ty<'tcx>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1969,6 +1969,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
StringPart::highlighted(exp_found.found.to_string()),
StringPart::normal("`"),
]);
self.suggest_function_pointers_impl(None, &exp_found, err);
}

true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2769,6 +2769,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
ObligationCauseCode::SliceOrArrayElem => {
err.note("slice and array elements must have `Sized` type");
}
ObligationCauseCode::ArrayLen(array_ty) => {
err.note(format!("the length of array `{array_ty}` must be type `usize`"));
}
ObligationCauseCode::TupleElem => {
err.note("only the last element of a tuple may have a dynamically sized type");
}
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_trait_selection/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,12 @@ pub struct FnConsiderCasting {
pub casting: String,
}

#[derive(Subdiagnostic)]
#[help(trait_selection_fn_consider_casting_both)]
pub struct FnConsiderCastingBoth<'a> {
pub sig: Binder<'a, FnSig<'a>>,
}

#[derive(Subdiagnostic)]
pub enum SuggestAccessingField<'a> {
#[suggestion(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
self.require_sized(subty, ObligationCauseCode::SliceOrArrayElem);
// Note that the len being WF is implicitly checked while visiting.
// Here we just check that it's of type usize.
let cause = self.cause(ObligationCauseCode::Misc);
let cause = self.cause(ObligationCauseCode::ArrayLen(t));
self.out.push(traits::Obligation::with_depth(
tcx,
cause,
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/io/pipe/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::io::{Read, Write, pipe};

#[test]
#[cfg(all(windows, unix, not(miri)))]
#[cfg(all(any(unix, windows), not(miri)))]
fn pipe_creation_clone_and_rw() {
let (rx, tx) = pipe().unwrap();

Expand Down
4 changes: 0 additions & 4 deletions src/ci/github-actions/jobs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ runners:
os: windows-2022-8core-32gb
<<: *base-job

- &job-windows-16c
os: windows-2022-16core-64gb
<<: *base-job

- &job-aarch64-linux
# Free some disk space to avoid running out of space during the build.
free_disk: true
Expand Down
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/examples/rustc-driver-example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl rustc_driver::Callbacks for MyCallbacks {
fn after_crate_root_parsing(
&mut self,
_compiler: &Compiler,
krate: &rustc_ast::Crate,
krate: &mut rustc_ast::Crate,
) -> Compilation {
for item in &krate.items {
println!("{}", item_to_string(&item));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl rustc_driver::Callbacks for MyCallbacks {
fn after_crate_root_parsing(
&mut self,
_compiler: &Compiler,
krate: &rustc_ast::Crate,
krate: &mut rustc_ast::Crate,
) -> Compilation {
for item in &krate.items {
println!("{}", item_to_string(&item));
Expand Down
Loading
Loading