Skip to content

Commit

Permalink
Auto merge of rust-lang#125120 - compiler-errors:rollup-mnjybwv, r=co…
Browse files Browse the repository at this point in the history
…mpiler-errors

Rollup of 7 pull requests

Successful merges:

 - rust-lang#119838 (style-guide: When breaking binops handle multi-line first operand better)
 - rust-lang#124844 (Use a proper probe for shadowing impl)
 - rust-lang#125047 (Migrate `run-make/issue-14500` to new `rmake.rs` format)
 - rust-lang#125080 (only find segs chain for missing methods when no available candidates)
 - rust-lang#125088 (Uplift `AliasTy` and `AliasTerm`)
 - rust-lang#125100 (Don't do post-method-probe error reporting steps if we're in a suggestion)
 - rust-lang#125118 (Use new utility functions/methods in run-make tests)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed May 14, 2024
2 parents bdfd941 + 31016d5 commit ac385a5
Show file tree
Hide file tree
Showing 42 changed files with 1,042 additions and 599 deletions.
6 changes: 6 additions & 0 deletions compiler/rustc_errors/src/diagnostic_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::ExistentialTrait
}
}

impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::UnevaluatedConst<I> {
fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
format!("{self:?}").into_diag_arg()
}
}

into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);

impl IntoDiagArg for bool {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -938,14 +938,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}

pub fn get_conversion_methods(
pub fn get_conversion_methods_for_diagnostic(
&self,
span: Span,
expected: Ty<'tcx>,
checked_ty: Ty<'tcx>,
hir_id: hir::HirId,
) -> Vec<AssocItem> {
let methods = self.probe_for_return_type(
let methods = self.probe_for_return_type_for_diagnostic(
span,
probe::Mode::MethodCall,
expected,
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2414,7 +2414,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let guar = if field.name == kw::Empty {
self.dcx().span_delayed_bug(field.span, "field name with no name")
} else if self.method_exists(field, base_ty, expr.hir_id, expected.only_has_type(self)) {
} else if self.method_exists_for_diagnostic(
field,
base_ty,
expr.hir_id,
expected.only_has_type(self),
) {
self.ban_take_value_of_method(expr, base_ty, field)
} else if !base_ty.is_primitive_ty() {
self.ban_nonexisting_field(field, base, expr, base_ty)
Expand Down Expand Up @@ -2600,7 +2605,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut err = self.private_field_err(field, base_did);

// Also check if an accessible method exists, which is often what is meant.
if self.method_exists(field, expr_t, expr.hir_id, return_ty)
if self.method_exists_for_diagnostic(field, expr_t, expr.hir_id, return_ty)
&& !self.expr_in_place(expr.hir_id)
{
self.suggest_method_call(
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
) -> bool {
let expr = expr.peel_blocks();
let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
let methods =
self.get_conversion_methods_for_diagnostic(expr.span, expected, found, expr.hir_id);

if let Some((suggestion, msg, applicability, verbose, annotation)) =
self.suggest_deref_or_ref(expr, found, expected)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub enum CandidateSource {
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Determines whether the type `self_ty` supports a visible method named `method_name` or not.
#[instrument(level = "debug", skip(self))]
pub fn method_exists(
pub fn method_exists_for_diagnostic(
&self,
method_name: Ident,
self_ty: Ty<'tcx>,
Expand All @@ -102,7 +102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
probe::Mode::MethodCall,
method_name,
return_type,
IsSuggestion(false),
IsSuggestion(true),
self_ty,
call_expr_id,
ProbeScope::TraitsInScope,
Expand Down
23 changes: 22 additions & 1 deletion compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ pub(crate) struct ProbeContext<'a, 'tcx> {
>,

scope_expr_id: HirId,

/// Is this probe being done for a diagnostic? This will skip some error reporting
/// machinery, since we don't particularly care about, for example, similarly named
/// candidates if we're *reporting* similarly named candidates.
is_suggestion: IsSuggestion,
}

impl<'a, 'tcx> Deref for ProbeContext<'a, 'tcx> {
Expand Down Expand Up @@ -220,7 +225,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// would use to decide if a method is a plausible fit for
/// ambiguity purposes).
#[instrument(level = "debug", skip(self, candidate_filter))]
pub fn probe_for_return_type(
pub fn probe_for_return_type_for_diagnostic(
&self,
span: Span,
mode: Mode,
Expand Down Expand Up @@ -459,6 +464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&orig_values,
steps.steps,
scope_expr_id,
is_suggestion,
);

probe_cx.assemble_inherent_candidates();
Expand Down Expand Up @@ -553,6 +559,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
orig_steps_var_values: &'a OriginalQueryValues<'tcx>,
steps: &'tcx [CandidateStep<'tcx>],
scope_expr_id: HirId,
is_suggestion: IsSuggestion,
) -> ProbeContext<'a, 'tcx> {
ProbeContext {
fcx,
Expand All @@ -570,6 +577,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
static_candidates: RefCell::new(Vec::new()),
unsatisfied_predicates: RefCell::new(Vec::new()),
scope_expr_id,
is_suggestion,
}
}

Expand Down Expand Up @@ -944,6 +952,18 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
return r;
}

// If it's a `lookup_probe_for_diagnostic`, then quit early. No need to
// probe for other candidates.
if self.is_suggestion.0 {
return Err(MethodError::NoMatch(NoMatchData {
static_candidates: vec![],
unsatisfied_predicates: vec![],
out_of_scope_traits: vec![],
similar_candidate: None,
mode: self.mode,
}));
}

debug!("pick: actual search failed, assemble diagnostics");

let static_candidates = std::mem::take(self.static_candidates.get_mut());
Expand Down Expand Up @@ -1631,6 +1651,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.orig_steps_var_values,
self.steps,
self.scope_expr_id,
IsSuggestion(true),
);
pcx.allow_similar_names = true;
pcx.assemble_inherent_candidates();
Expand Down
42 changes: 35 additions & 7 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

let label_span_not_found = |err: &mut Diag<'_>| {
let mut find_candidate_for_method = false;

let mut label_span_not_found = |err: &mut Diag<'_>| {
if unsatisfied_predicates.is_empty() {
err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
let is_string_or_ref_str = match rcvr_ty.kind() {
Expand Down Expand Up @@ -1219,6 +1221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.note(format!(
"the {item_kind} was found for\n{type_candidates}{additional_types}"
));
find_candidate_for_method = mode == Mode::MethodCall;
}
}
} else {
Expand Down Expand Up @@ -1371,9 +1374,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}
}
// If an appropriate error source is not found, check method chain for possible candiates
if unsatisfied_predicates.is_empty()
&& let Mode::MethodCall = mode

if !find_candidate_for_method {
self.lookup_segments_chain_for_no_match_method(
&mut err,
item_name,
item_kind,
source,
no_match_data,
);
}

self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
Some(err)
}

/// If an appropriate error source is not found, check method chain for possible candidates
fn lookup_segments_chain_for_no_match_method(
&self,
err: &mut Diag<'_>,
item_name: Ident,
item_kind: &str,
source: SelfSource<'tcx>,
no_match_data: &NoMatchData<'tcx>,
) {
if no_match_data.unsatisfied_predicates.is_empty()
&& let Mode::MethodCall = no_match_data.mode
&& let SelfSource::MethodCall(mut source_expr) = source
{
let mut stack_methods = vec![];
Expand All @@ -1394,6 +1420,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.unwrap_or(Ty::new_misc_error(self.tcx)),
);

// FIXME: `probe_for_name_many` searches for methods in inherent implementations,
// so it may return a candidate that doesn't belong to this `revr_ty`. We need to
// check whether the instantiated type matches the received one.
for _matched_method in self.probe_for_name_many(
Mode::MethodCall,
item_name,
Expand All @@ -1416,8 +1445,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}
}
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
Some(err)
}

fn find_likely_intended_associated_item(
Expand Down Expand Up @@ -2814,7 +2841,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some(output_ty) => self.resolve_vars_if_possible(output_ty),
_ => return,
};
let method_exists = self.method_exists(item_name, output_ty, call.hir_id, return_type);
let method_exists =
self.method_exists_for_diagnostic(item_name, output_ty, call.hir_id, return_type);
debug!("suggest_await_before_method: is_method_exist={}", method_exists);
if method_exists {
err.span_suggestion_verbose(
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/traits/solve/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ pub enum ProbeKind<'tcx> {
/// do a probe to find out what projection type(s) may be used to prove that
/// the source type upholds all of the target type's object bounds.
UpcastProjectionCompatibility,
/// Looking for param-env candidates that satisfy the trait ref for a projection.
ShadowedEnvProbing,
/// Try to unify an opaque type with an existing key in the storage.
OpaqueTypeStorageLookup { result: QueryResult<'tcx> },
}
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/traits/solve/inspect/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
ProbeKind::TraitCandidate { source, result } => {
write!(self.f, "CANDIDATE {source:?}: {result:?}")
}
ProbeKind::ShadowedEnvProbing => {
write!(self.f, "PROBING FOR IMPLS SHADOWED BY PARAM-ENV CANDIDATE:")
}
}?;

self.nested(|this| {
Expand Down
14 changes: 11 additions & 3 deletions compiler/rustc_middle/src/ty/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::LocalDefId;
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
use rustc_type_ir::ConstKind as IrConstKind;
use rustc_type_ir::{TypeFlags, WithCachedTypeInfo};
use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};

mod int;
mod kind;
Expand All @@ -20,7 +19,8 @@ use rustc_span::Span;
use rustc_span::DUMMY_SP;
pub use valtree::*;

pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>;

#[cfg(target_pointer_width = "64")]
rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
Expand Down Expand Up @@ -184,6 +184,14 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
Const::new_bound(tcx, debruijn, var, ty)
}

fn new_unevaluated(
interner: TyCtxt<'tcx>,
uv: ty::UnevaluatedConst<'tcx>,
ty: Ty<'tcx>,
) -> Self {
Const::new_unevaluated(interner, uv, ty)
}

fn ty(self) -> Ty<'tcx> {
self.ty()
}
Expand Down
30 changes: 4 additions & 26 deletions compiler/rustc_middle/src/ty/consts/kind.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
use super::Const;
use crate::mir;
use crate::ty::abstract_const::CastKind;
use crate::ty::GenericArgsRef;
use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
use rustc_hir::def_id::DefId;
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};

/// An unevaluated (potentially generic) constant used in the type-system.
#[derive(Copy, Clone, Eq, PartialEq, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct UnevaluatedConst<'tcx> {
pub def: DefId,
pub args: GenericArgsRef<'tcx>,
}

impl rustc_errors::IntoDiagArg for UnevaluatedConst<'_> {
fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
format!("{self:?}").into_diag_arg()
}
}

impl<'tcx> UnevaluatedConst<'tcx> {
#[extension(pub(crate) trait UnevaluatedConstEvalExt<'tcx>)]
impl<'tcx> ty::UnevaluatedConst<'tcx> {
/// FIXME(RalfJung): I cannot explain what this does or why it makes sense, but not doing this
/// hurts performance.
#[inline]
pub(crate) fn prepare_for_eval(
fn prepare_for_eval(
self,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
Expand Down Expand Up @@ -55,13 +40,6 @@ impl<'tcx> UnevaluatedConst<'tcx> {
}
}

impl<'tcx> UnevaluatedConst<'tcx> {
#[inline]
pub fn new(def: DefId, args: GenericArgsRef<'tcx>) -> UnevaluatedConst<'tcx> {
UnevaluatedConst { def, args }
}
}

#[derive(Copy, Clone, Eq, PartialEq, Hash)]
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
pub enum Expr<'tcx> {
Expand Down
Loading

0 comments on commit ac385a5

Please sign in to comment.