Auto merge of #99267 - Dylan-DPC:rollup-d8l7y1o, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #99113 (Simplify [a]rc code a little) - #99131 (Add label for generic arg (+ APIT) and RPIT callables in `label_fn_like`) - #99237 (removed unused CSS and unused HTML IDs) - #99239 (Add myself to the set of people notified when MIR changes.) - #99241 (Remove comment referring to constness.rs) - #99257 (Add regression test for #89436) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
522abf6d88
17 changed files with 357 additions and 162 deletions
|
@ -132,8 +132,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
Some(p) => p,
|
||||
};
|
||||
|
||||
// Keep the patterns in this match ordered the same as the list in
|
||||
// `src/librustc_middle/ty/constness.rs`
|
||||
match intrinsic_name {
|
||||
sym::caller_location => {
|
||||
let span = self.find_closest_untracked_caller_location();
|
||||
|
|
|
@ -128,6 +128,14 @@ impl<'tcx> ClosureKind {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId {
|
||||
match self {
|
||||
ClosureKind::Fn => tcx.lang_items().fn_once_trait().unwrap(),
|
||||
ClosureKind::FnMut => tcx.lang_items().fn_mut_trait().unwrap(),
|
||||
ClosureKind::FnOnce => tcx.lang_items().fn_trait().unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A composite describing a `Place` that is captured by a closure.
|
||||
|
|
|
@ -21,15 +21,18 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::{ExprKind, Node, QPath};
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::infer::TypeTrace;
|
||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{self, Span};
|
||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, StatementAsExpression};
|
||||
use rustc_trait_selection::traits::{
|
||||
self, ObligationCauseCode, SelectionContext, StatementAsExpression,
|
||||
};
|
||||
|
||||
use std::iter;
|
||||
use std::slice;
|
||||
|
@ -89,7 +92,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
args_no_rcvr,
|
||||
false,
|
||||
tuple_arguments,
|
||||
None,
|
||||
method.ok().map(|method| method.def_id),
|
||||
);
|
||||
return self.tcx.ty_error();
|
||||
}
|
||||
|
@ -393,41 +396,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
if !call_appears_satisfied {
|
||||
// Next, let's construct the error
|
||||
let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
|
||||
hir::ExprKind::Call(
|
||||
hir::Expr {
|
||||
span,
|
||||
kind:
|
||||
hir::ExprKind::Path(hir::QPath::Resolved(
|
||||
_,
|
||||
hir::Path { res: Res::Def(DefKind::Ctor(of, _), _), .. },
|
||||
)),
|
||||
..
|
||||
},
|
||||
_,
|
||||
) => (call_span, *span, Some(of)),
|
||||
hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None),
|
||||
hir::ExprKind::MethodCall(path_segment, _, span) => {
|
||||
let ident_span = path_segment.ident.span;
|
||||
let ident_span = if let Some(args) = path_segment.args {
|
||||
ident_span.with_hi(args.span_ext.hi())
|
||||
} else {
|
||||
ident_span
|
||||
};
|
||||
(
|
||||
*span, ident_span, None, // methods are never ctors
|
||||
)
|
||||
}
|
||||
k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
|
||||
};
|
||||
let args_span = error_span.trim_start(full_call_span).unwrap_or(error_span);
|
||||
let call_name = match ctor_of {
|
||||
Some(CtorOf::Struct) => "struct",
|
||||
Some(CtorOf::Variant) => "enum variant",
|
||||
None => "function",
|
||||
};
|
||||
|
||||
let compatibility_diagonal = IndexVec::from_raw(compatibility_diagonal);
|
||||
let provided_args = IndexVec::from_iter(provided_args.iter().take(if c_variadic {
|
||||
minimum_input_count
|
||||
|
@ -451,13 +419,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
compatibility_diagonal,
|
||||
formal_and_expected_inputs,
|
||||
provided_args,
|
||||
full_call_span,
|
||||
error_span,
|
||||
args_span,
|
||||
call_name,
|
||||
c_variadic,
|
||||
err_code,
|
||||
fn_def_id,
|
||||
call_span,
|
||||
call_expr,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -467,14 +433,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>,
|
||||
formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
|
||||
provided_args: IndexVec<ProvidedIdx, &'tcx hir::Expr<'tcx>>,
|
||||
full_call_span: Span,
|
||||
error_span: Span,
|
||||
args_span: Span,
|
||||
call_name: &str,
|
||||
c_variadic: bool,
|
||||
err_code: &str,
|
||||
fn_def_id: Option<DefId>,
|
||||
call_span: Span,
|
||||
call_expr: &hir::Expr<'tcx>,
|
||||
) {
|
||||
// Next, let's construct the error
|
||||
let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
|
||||
hir::ExprKind::Call(
|
||||
hir::Expr {
|
||||
span,
|
||||
kind:
|
||||
hir::ExprKind::Path(hir::QPath::Resolved(
|
||||
_,
|
||||
hir::Path { res: Res::Def(DefKind::Ctor(of, _), _), .. },
|
||||
)),
|
||||
..
|
||||
},
|
||||
_,
|
||||
) => (call_span, *span, Some(of)),
|
||||
hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None),
|
||||
hir::ExprKind::MethodCall(path_segment, _, span) => {
|
||||
let ident_span = path_segment.ident.span;
|
||||
let ident_span = if let Some(args) = path_segment.args {
|
||||
ident_span.with_hi(args.span_ext.hi())
|
||||
} else {
|
||||
ident_span
|
||||
};
|
||||
(
|
||||
*span, ident_span, None, // methods are never ctors
|
||||
)
|
||||
}
|
||||
k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
|
||||
};
|
||||
let args_span = error_span.trim_start(full_call_span).unwrap_or(error_span);
|
||||
let call_name = match ctor_of {
|
||||
Some(CtorOf::Struct) => "struct",
|
||||
Some(CtorOf::Variant) => "enum variant",
|
||||
None => "function",
|
||||
};
|
||||
|
||||
// Don't print if it has error types or is just plain `_`
|
||||
fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
|
||||
tys.into_iter().any(|ty| ty.references_error() || ty.is_ty_var())
|
||||
|
@ -495,6 +494,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
(self.resolve_vars_if_possible(ty), expr.span)
|
||||
})
|
||||
.collect();
|
||||
let callee_expr = match &call_expr.peel_blocks().kind {
|
||||
hir::ExprKind::Call(callee, _) => Some(*callee),
|
||||
hir::ExprKind::MethodCall(_, callee, _) => {
|
||||
if let Some((DefKind::AssocFn, def_id)) =
|
||||
self.typeck_results.borrow().type_dependent_def(call_expr.hir_id)
|
||||
&& let Some(assoc) = tcx.opt_associated_item(def_id)
|
||||
&& assoc.fn_has_self_parameter
|
||||
{
|
||||
Some(&callee[0])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let callee_ty = callee_expr
|
||||
.and_then(|callee_expr| self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr));
|
||||
|
||||
// A "softer" version of the `demand_compatible`, which checks types without persisting them,
|
||||
// and treats error types differently
|
||||
|
@ -631,7 +647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
Applicability::MachineApplicable,
|
||||
);
|
||||
};
|
||||
label_fn_like(tcx, &mut err, fn_def_id);
|
||||
self.label_fn_like(&mut err, fn_def_id, callee_ty);
|
||||
err.emit();
|
||||
return;
|
||||
}
|
||||
|
@ -721,7 +737,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
format!("arguments to this {} are incorrect", call_name),
|
||||
);
|
||||
// Call out where the function is defined
|
||||
label_fn_like(tcx, &mut err, fn_def_id);
|
||||
self.label_fn_like(&mut err, fn_def_id, callee_ty);
|
||||
err.emit();
|
||||
return;
|
||||
}
|
||||
|
@ -1003,7 +1019,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Call out where the function is defined
|
||||
label_fn_like(tcx, &mut err, fn_def_id);
|
||||
self.label_fn_like(&mut err, fn_def_id, callee_ty);
|
||||
|
||||
// And add a suggestion block for all of the parameters
|
||||
let suggestion_text = match suggestion_text {
|
||||
|
@ -1795,47 +1811,126 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn label_fn_like<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>,
|
||||
def_id: Option<DefId>,
|
||||
) {
|
||||
let Some(def_id) = def_id else {
|
||||
return;
|
||||
};
|
||||
fn label_fn_like(
|
||||
&self,
|
||||
err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>,
|
||||
callable_def_id: Option<DefId>,
|
||||
callee_ty: Option<Ty<'tcx>>,
|
||||
) {
|
||||
let Some(mut def_id) = callable_def_id else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(def_span) = tcx.def_ident_span(def_id) {
|
||||
let mut spans: MultiSpan = def_span.into();
|
||||
|
||||
let params = tcx
|
||||
.hir()
|
||||
.get_if_local(def_id)
|
||||
.and_then(|node| node.body_id())
|
||||
.into_iter()
|
||||
.flat_map(|id| tcx.hir().body(id).params);
|
||||
|
||||
for param in params {
|
||||
spans.push_span_label(param.span, "");
|
||||
if let Some(assoc_item) = self.tcx.opt_associated_item(def_id)
|
||||
// Possibly points at either impl or trait item, so try to get it
|
||||
// to point to trait item, then get the parent.
|
||||
// This parent might be an impl in the case of an inherent function,
|
||||
// but the next check will fail.
|
||||
&& let maybe_trait_item_def_id = assoc_item.trait_item_def_id.unwrap_or(def_id)
|
||||
&& let maybe_trait_def_id = self.tcx.parent(maybe_trait_item_def_id)
|
||||
// Just an easy way to check "trait_def_id == Fn/FnMut/FnOnce"
|
||||
&& let Some(call_kind) = ty::ClosureKind::from_def_id(self.tcx, maybe_trait_def_id)
|
||||
&& let Some(callee_ty) = callee_ty
|
||||
{
|
||||
let callee_ty = callee_ty.peel_refs();
|
||||
match *callee_ty.kind() {
|
||||
ty::Param(param) => {
|
||||
let param =
|
||||
self.tcx.generics_of(self.body_id.owner).type_param(¶m, self.tcx);
|
||||
if param.kind.is_synthetic() {
|
||||
// if it's `impl Fn() -> ..` then just fall down to the def-id based logic
|
||||
def_id = param.def_id;
|
||||
} else {
|
||||
// Otherwise, find the predicate that makes this generic callable,
|
||||
// and point at that.
|
||||
let instantiated = self
|
||||
.tcx
|
||||
.explicit_predicates_of(self.body_id.owner)
|
||||
.instantiate_identity(self.tcx);
|
||||
// FIXME(compiler-errors): This could be problematic if something has two
|
||||
// fn-like predicates with different args, but callable types really never
|
||||
// do that, so it's OK.
|
||||
for (predicate, span) in
|
||||
std::iter::zip(instantiated.predicates, instantiated.spans)
|
||||
{
|
||||
if let ty::PredicateKind::Trait(pred) = predicate.kind().skip_binder()
|
||||
&& pred.self_ty().peel_refs() == callee_ty
|
||||
&& ty::ClosureKind::from_def_id(self.tcx, pred.def_id()).is_some()
|
||||
{
|
||||
err.span_note(span, "callable defined here");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::Opaque(new_def_id, _)
|
||||
| ty::Closure(new_def_id, _)
|
||||
| ty::FnDef(new_def_id, _) => {
|
||||
def_id = new_def_id;
|
||||
}
|
||||
_ => {
|
||||
// Look for a user-provided impl of a `Fn` trait, and point to it.
|
||||
let new_def_id = self.probe(|_| {
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
call_kind.to_def_id(self.tcx),
|
||||
self.tcx.mk_substs([
|
||||
ty::GenericArg::from(callee_ty),
|
||||
self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: rustc_span::DUMMY_SP,
|
||||
})
|
||||
.into(),
|
||||
].into_iter()),
|
||||
);
|
||||
let obligation = traits::Obligation::new(
|
||||
traits::ObligationCause::dummy(),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}),
|
||||
);
|
||||
match SelectionContext::new(&self).select(&obligation) {
|
||||
Ok(Some(traits::ImplSource::UserDefined(impl_source))) => {
|
||||
Some(impl_source.impl_def_id)
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
});
|
||||
if let Some(new_def_id) = new_def_id {
|
||||
def_id = new_def_id;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let def_kind = tcx.def_kind(def_id);
|
||||
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
|
||||
} else {
|
||||
match tcx.hir().get_if_local(def_id) {
|
||||
Some(hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure(hir::Closure { fn_decl_span, .. }),
|
||||
..
|
||||
})) => {
|
||||
let spans: MultiSpan = (*fn_decl_span).into();
|
||||
if let Some(def_span) = self.tcx.def_ident_span(def_id) && !def_span.is_dummy() {
|
||||
let mut spans: MultiSpan = def_span.into();
|
||||
|
||||
// Note: We don't point to param spans here because they overlap
|
||||
// with the closure span itself
|
||||
let params = self
|
||||
.tcx
|
||||
.hir()
|
||||
.get_if_local(def_id)
|
||||
.and_then(|node| node.body_id())
|
||||
.into_iter()
|
||||
.flat_map(|id| self.tcx.hir().body(id).params);
|
||||
|
||||
err.span_note(spans, "closure defined here");
|
||||
for param in params {
|
||||
spans.push_span_label(param.span, "");
|
||||
}
|
||||
_ => {}
|
||||
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
|
||||
} else {
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
err.span_note(
|
||||
self.tcx.def_span(def_id),
|
||||
&format!("{} defined here", def_kind.descr(def_id)),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,6 +124,7 @@
|
|||
#![cfg_attr(test, feature(new_uninit))]
|
||||
#![feature(nonnull_slice_from_raw_parts)]
|
||||
#![feature(pattern)]
|
||||
#![feature(pointer_byte_offsets)]
|
||||
#![feature(ptr_internals)]
|
||||
#![feature(ptr_metadata)]
|
||||
#![feature(ptr_sub_ptr)]
|
||||
|
|
|
@ -907,8 +907,7 @@ impl<T: ?Sized> Rc<T> {
|
|||
let offset = unsafe { data_offset(ptr) };
|
||||
|
||||
// Reverse the offset to find the original RcBox.
|
||||
let rc_ptr =
|
||||
unsafe { (ptr as *mut u8).offset(-offset).with_metadata_of(ptr as *mut RcBox<T>) };
|
||||
let rc_ptr = unsafe { ptr.byte_sub(offset) as *mut RcBox<T> };
|
||||
|
||||
unsafe { Self::from_ptr(rc_ptr) }
|
||||
}
|
||||
|
@ -2331,7 +2330,7 @@ impl<T: ?Sized> Weak<T> {
|
|||
let offset = unsafe { data_offset(ptr) };
|
||||
// Thus, we reverse the offset to get the whole RcBox.
|
||||
// SAFETY: the pointer originated from a Weak, so this offset is safe.
|
||||
unsafe { (ptr as *mut u8).offset(-offset).with_metadata_of(ptr as *mut RcBox<T>) }
|
||||
unsafe { ptr.byte_sub(offset) as *mut RcBox<T> }
|
||||
};
|
||||
|
||||
// SAFETY: we now have recovered the original Weak pointer, so can create the Weak.
|
||||
|
@ -2684,7 +2683,7 @@ impl<T: ?Sized> Unpin for Rc<T> {}
|
|||
///
|
||||
/// The pointer must point to (and have valid metadata for) a previously
|
||||
/// valid instance of T, but the T is allowed to be dropped.
|
||||
unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
|
||||
unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> usize {
|
||||
// Align the unsized value to the end of the RcBox.
|
||||
// Because RcBox is repr(C), it will always be the last field in memory.
|
||||
// SAFETY: since the only unsized types possible are slices, trait objects,
|
||||
|
@ -2695,7 +2694,7 @@ unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn data_offset_align(align: usize) -> isize {
|
||||
fn data_offset_align(align: usize) -> usize {
|
||||
let layout = Layout::new::<RcBox<()>>();
|
||||
(layout.size() + layout.padding_needed_for(align)) as isize
|
||||
layout.size() + layout.padding_needed_for(align)
|
||||
}
|
||||
|
|
|
@ -908,8 +908,7 @@ impl<T: ?Sized> Arc<T> {
|
|||
let offset = data_offset(ptr);
|
||||
|
||||
// Reverse the offset to find the original ArcInner.
|
||||
let arc_ptr =
|
||||
(ptr as *mut u8).offset(-offset).with_metadata_of(ptr as *mut ArcInner<T>);
|
||||
let arc_ptr = ptr.byte_sub(offset) as *mut ArcInner<T>;
|
||||
|
||||
Self::from_ptr(arc_ptr)
|
||||
}
|
||||
|
@ -1942,7 +1941,7 @@ impl<T: ?Sized> Weak<T> {
|
|||
let offset = unsafe { data_offset(ptr) };
|
||||
// Thus, we reverse the offset to get the whole RcBox.
|
||||
// SAFETY: the pointer originated from a Weak, so this offset is safe.
|
||||
unsafe { (ptr as *mut u8).offset(-offset).with_metadata_of(ptr as *mut ArcInner<T>) }
|
||||
unsafe { ptr.byte_sub(offset) as *mut ArcInner<T> }
|
||||
};
|
||||
|
||||
// SAFETY: we now have recovered the original Weak pointer, so can create the Weak.
|
||||
|
@ -2749,7 +2748,7 @@ impl<T: ?Sized> Unpin for Arc<T> {}
|
|||
///
|
||||
/// The pointer must point to (and have valid metadata for) a previously
|
||||
/// valid instance of T, but the T is allowed to be dropped.
|
||||
unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
|
||||
unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> usize {
|
||||
// Align the unsized value to the end of the ArcInner.
|
||||
// Because RcBox is repr(C), it will always be the last field in memory.
|
||||
// SAFETY: since the only unsized types possible are slices, trait objects,
|
||||
|
@ -2760,7 +2759,7 @@ unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn data_offset_align(align: usize) -> isize {
|
||||
fn data_offset_align(align: usize) -> usize {
|
||||
let layout = Layout::new::<ArcInner<()>>();
|
||||
(layout.size() + layout.padding_needed_for(align)) as isize
|
||||
layout.size() + layout.padding_needed_for(align)
|
||||
}
|
||||
|
|
|
@ -1442,7 +1442,6 @@ static DEFAULT_ID_MAP: Lazy<FxHashMap<Cow<'static, str>, usize>> = Lazy::new(||
|
|||
fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
|
||||
let mut map = FxHashMap::default();
|
||||
// This is the list of IDs used in Javascript.
|
||||
map.insert("help".into(), 1);
|
||||
map.insert("settings".into(), 1);
|
||||
map.insert("not-displayed".into(), 1);
|
||||
map.insert("alternative-display".into(), 1);
|
||||
|
@ -1455,7 +1454,6 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
|
|||
map.insert("help-button".into(), 1);
|
||||
map.insert("main-content".into(), 1);
|
||||
map.insert("crate-search".into(), 1);
|
||||
map.insert("render-detail".into(), 1);
|
||||
map.insert("toggle-all-docs".into(), 1);
|
||||
map.insert("all-types".into(), 1);
|
||||
map.insert("default-settings".into(), 1);
|
||||
|
|
|
@ -1733,13 +1733,12 @@ details.rustdoc-toggle[open] > summary.hideme > span {
|
|||
display: none;
|
||||
}
|
||||
|
||||
details.undocumented[open] > summary::before,
|
||||
details.rustdoc-toggle[open] > summary::before,
|
||||
details.rustdoc-toggle[open] > summary.hideme::before {
|
||||
background-image: /* AUTOREPLACE: */url("toggle-minus.svg");
|
||||
}
|
||||
|
||||
details.undocumented > summary::before, details.rustdoc-toggle > summary::before {
|
||||
details.rustdoc-toggle > summary::before {
|
||||
background-image: /* AUTOREPLACE: */url("toggle-plus.svg");
|
||||
}
|
||||
|
||||
|
|
|
@ -174,13 +174,11 @@ body.source .example-wrap pre.rust a {
|
|||
}
|
||||
|
||||
details.rustdoc-toggle > summary.hideme > span,
|
||||
details.rustdoc-toggle > summary::before,
|
||||
details.undocumented > summary::before {
|
||||
details.rustdoc-toggle > summary::before {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
details.rustdoc-toggle > summary::before,
|
||||
details.undocumented > summary::before {
|
||||
details.rustdoc-toggle > summary::before {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
|
@ -218,17 +216,6 @@ details.undocumented > summary::before {
|
|||
background: none;
|
||||
}
|
||||
|
||||
#help > div {
|
||||
background: #14191f;
|
||||
box-shadow: 0px 6px 20px 0px black;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#help span.bottom, #help span.top {
|
||||
border-color: #5c6773;
|
||||
}
|
||||
|
||||
.rightside,
|
||||
.out-of-band {
|
||||
color: grey;
|
||||
|
|
|
@ -148,13 +148,11 @@ body.source .example-wrap pre.rust a {
|
|||
}
|
||||
|
||||
details.rustdoc-toggle > summary.hideme > span,
|
||||
details.rustdoc-toggle > summary::before,
|
||||
details.undocumented > summary::before {
|
||||
details.rustdoc-toggle > summary::before {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
details.rustdoc-toggle > summary::before,
|
||||
details.undocumented > summary::before {
|
||||
details.rustdoc-toggle > summary::before {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
|
@ -179,20 +177,6 @@ details.undocumented > summary::before {
|
|||
.stab.portability { background: #F3DFFF; border-color: #b07bdb; color: #2f2f2f; }
|
||||
.stab.portability > code { background: none; }
|
||||
|
||||
#help > div {
|
||||
background: #4d4d4d;
|
||||
border-color: #bfbfbf;
|
||||
}
|
||||
|
||||
#help span.bottom, #help span.top {
|
||||
border-color: #bfbfbf;
|
||||
}
|
||||
|
||||
#help dt {
|
||||
border-color: #bfbfbf;
|
||||
background: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
.rightside,
|
||||
.out-of-band {
|
||||
color: grey;
|
||||
|
|
|
@ -140,8 +140,7 @@ body.source .example-wrap pre.rust a {
|
|||
}
|
||||
|
||||
details.rustdoc-toggle > summary.hideme > span,
|
||||
details.rustdoc-toggle > summary::before,
|
||||
details.undocumented > summary::before {
|
||||
details.rustdoc-toggle > summary::before {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
|
@ -161,15 +160,6 @@ details.undocumented > summary::before {
|
|||
.stab.portability { background: #F3DFFF; border-color: #b07bdb; }
|
||||
.stab.portability > code { background: none; }
|
||||
|
||||
#help > div {
|
||||
background: #e9e9e9;
|
||||
border-color: #bfbfbf;
|
||||
}
|
||||
|
||||
#help span.bottom, #help span.top {
|
||||
border-color: #bfbfbf;
|
||||
}
|
||||
|
||||
.rightside,
|
||||
.out-of-band {
|
||||
color: grey;
|
||||
|
|
26
src/test/ui/argument-suggestions/exotic-calls.rs
Normal file
26
src/test/ui/argument-suggestions/exotic-calls.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
fn foo<T: Fn()>(t: T) {
|
||||
t(1i32);
|
||||
//~^ ERROR this function takes 0 arguments but 1 argument was supplied
|
||||
}
|
||||
|
||||
fn bar(t: impl Fn()) {
|
||||
t(1i32);
|
||||
//~^ ERROR this function takes 0 arguments but 1 argument was supplied
|
||||
}
|
||||
|
||||
fn baz() -> impl Fn() {
|
||||
|| {}
|
||||
}
|
||||
|
||||
fn baz2() {
|
||||
baz()(1i32)
|
||||
//~^ ERROR this function takes 0 arguments but 1 argument was supplied
|
||||
}
|
||||
|
||||
fn qux() {
|
||||
let x = || {};
|
||||
x(1i32);
|
||||
//~^ ERROR this function takes 0 arguments but 1 argument was supplied
|
||||
}
|
||||
|
||||
fn main() {}
|
67
src/test/ui/argument-suggestions/exotic-calls.stderr
Normal file
67
src/test/ui/argument-suggestions/exotic-calls.stderr
Normal file
|
@ -0,0 +1,67 @@
|
|||
error[E0057]: this function takes 0 arguments but 1 argument was supplied
|
||||
--> $DIR/exotic-calls.rs:2:5
|
||||
|
|
||||
LL | t(1i32);
|
||||
| ^ ---- argument of type `i32` unexpected
|
||||
|
|
||||
note: callable defined here
|
||||
--> $DIR/exotic-calls.rs:1:11
|
||||
|
|
||||
LL | fn foo<T: Fn()>(t: T) {
|
||||
| ^^^^
|
||||
help: remove the extra argument
|
||||
|
|
||||
LL | t();
|
||||
| ~~~
|
||||
|
||||
error[E0057]: this function takes 0 arguments but 1 argument was supplied
|
||||
--> $DIR/exotic-calls.rs:7:5
|
||||
|
|
||||
LL | t(1i32);
|
||||
| ^ ---- argument of type `i32` unexpected
|
||||
|
|
||||
note: type parameter defined here
|
||||
--> $DIR/exotic-calls.rs:6:11
|
||||
|
|
||||
LL | fn bar(t: impl Fn()) {
|
||||
| ^^^^^^^^^
|
||||
help: remove the extra argument
|
||||
|
|
||||
LL | t();
|
||||
| ~~~
|
||||
|
||||
error[E0057]: this function takes 0 arguments but 1 argument was supplied
|
||||
--> $DIR/exotic-calls.rs:16:5
|
||||
|
|
||||
LL | baz()(1i32)
|
||||
| ^^^^^ ---- argument of type `i32` unexpected
|
||||
|
|
||||
note: opaque type defined here
|
||||
--> $DIR/exotic-calls.rs:11:13
|
||||
|
|
||||
LL | fn baz() -> impl Fn() {
|
||||
| ^^^^^^^^^
|
||||
help: remove the extra argument
|
||||
|
|
||||
LL | baz()()
|
||||
|
|
||||
|
||||
error[E0057]: this function takes 0 arguments but 1 argument was supplied
|
||||
--> $DIR/exotic-calls.rs:22:5
|
||||
|
|
||||
LL | x(1i32);
|
||||
| ^ ---- argument of type `i32` unexpected
|
||||
|
|
||||
note: closure defined here
|
||||
--> $DIR/exotic-calls.rs:21:13
|
||||
|
|
||||
LL | let x = || {};
|
||||
| ^^
|
||||
help: remove the extra argument
|
||||
|
|
||||
LL | x();
|
||||
| ~~~
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0057`.
|
|
@ -0,0 +1,44 @@
|
|||
// check-pass
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
trait MiniYokeable<'a> {
|
||||
type Output;
|
||||
}
|
||||
|
||||
struct MiniYoke<Y: for<'a> MiniYokeable<'a>> {
|
||||
pub yokeable: Y,
|
||||
}
|
||||
|
||||
fn map_project_broken<Y, P>(
|
||||
source: MiniYoke<Y>,
|
||||
f: impl for<'a> FnOnce(
|
||||
<Y as MiniYokeable<'a>>::Output,
|
||||
core::marker::PhantomData<&'a ()>,
|
||||
) -> <P as MiniYokeable<'a>>::Output,
|
||||
) -> MiniYoke<P>
|
||||
where
|
||||
Y: for<'a> MiniYokeable<'a>,
|
||||
P: for<'a> MiniYokeable<'a>
|
||||
{
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
struct Bar<'a> {
|
||||
string_1: &'a str,
|
||||
string_2: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> MiniYokeable<'a> for Bar<'static> {
|
||||
type Output = Bar<'a>;
|
||||
}
|
||||
|
||||
impl<'a> MiniYokeable<'a> for &'static str {
|
||||
type Output = &'a str;
|
||||
}
|
||||
|
||||
fn demo_broken(bar: MiniYoke<Bar<'static>>) -> MiniYoke<&'static str> {
|
||||
map_project_broken(bar, |bar, _| bar.string_1)
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -4,11 +4,11 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied
|
|||
LL | |t| f(t);
|
||||
| ^ - argument unexpected
|
||||
|
|
||||
note: associated function defined here
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
note: callable defined here
|
||||
--> $DIR/issue-16939.rs:4:12
|
||||
|
|
||||
LL | extern "rust-call" fn call(&self, args: Args) -> Self::Output;
|
||||
| ^^^^
|
||||
LL | fn _foo<F: Fn()> (f: F) {
|
||||
| ^^^^
|
||||
help: remove the extra argument
|
||||
|
|
||||
LL | |t| f();
|
||||
|
|
|
@ -6,11 +6,11 @@ LL | let ans = s("what");
|
|||
| |
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
note: associated function defined here
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
note: implementation defined here
|
||||
--> $DIR/overloaded-calls-bad.rs:10:1
|
||||
|
|
||||
LL | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
|
||||
| ^^^^^^^^
|
||||
LL | impl FnMut<(isize,)> for S {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0057]: this function takes 1 argument but 0 arguments were supplied
|
||||
--> $DIR/overloaded-calls-bad.rs:29:15
|
||||
|
@ -18,11 +18,11 @@ error[E0057]: this function takes 1 argument but 0 arguments were supplied
|
|||
LL | let ans = s();
|
||||
| ^-- an argument of type `isize` is missing
|
||||
|
|
||||
note: associated function defined here
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
note: implementation defined here
|
||||
--> $DIR/overloaded-calls-bad.rs:10:1
|
||||
|
|
||||
LL | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
|
||||
| ^^^^^^^^
|
||||
LL | impl FnMut<(isize,)> for S {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: provide the argument
|
||||
|
|
||||
LL | let ans = s(/* isize */);
|
||||
|
@ -36,11 +36,11 @@ LL | let ans = s("burma", "shave");
|
|||
| |
|
||||
| expected `isize`, found `&str`
|
||||
|
|
||||
note: associated function defined here
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
note: implementation defined here
|
||||
--> $DIR/overloaded-calls-bad.rs:10:1
|
||||
|
|
||||
LL | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
|
||||
| ^^^^^^^^
|
||||
LL | impl FnMut<(isize,)> for S {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: remove the extra argument
|
||||
|
|
||||
LL | let ans = s(/* isize */);
|
||||
|
|
|
@ -340,4 +340,4 @@ cc = ["@rust-lang/rustfmt"]
|
|||
|
||||
[mentions."compiler/rustc_middle/src/mir/syntax.rs"]
|
||||
message = "This PR changes MIR"
|
||||
cc = ["@oli-obk", "@RalfJung", "@JakobDegen", "@davidtwco", "@celinval"]
|
||||
cc = ["@oli-obk", "@RalfJung", "@JakobDegen", "@davidtwco", "@celinval", "@vakaras"]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue