diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index e2a8a9891f72f..3039b10373d8c 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -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(); diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index f5ce43f3afb69..8ead05122740e 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -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. diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index b1e391bf1c71f..ec045d3e70c96 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -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>, formal_and_expected_inputs: IndexVec, Ty<'tcx>)>, provided_args: IndexVec>, - full_call_span: Span, - error_span: Span, - args_span: Span, - call_name: &str, c_variadic: bool, err_code: &str, fn_def_id: Option, + 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>) -> 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, -) { - let Some(def_id) = 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, ""); + fn label_fn_like( + &self, + err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>, + callable_def_id: Option, + callee_ty: Option>, + ) { + let Some(mut def_id) = callable_def_id else { + return; + }; + + 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)), + ); } } } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index d68e0a9d66fde..541de5c902970 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -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)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index a248cd458df81..b89b03683baef 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -907,8 +907,7 @@ impl Rc { 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) }; + let rc_ptr = unsafe { ptr.byte_sub(offset) as *mut RcBox }; unsafe { Self::from_ptr(rc_ptr) } } @@ -2331,7 +2330,7 @@ impl Weak { 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) } + unsafe { ptr.byte_sub(offset) as *mut RcBox } }; // SAFETY: we now have recovered the original Weak pointer, so can create the Weak. @@ -2684,7 +2683,7 @@ impl Unpin for Rc {} /// /// 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(ptr: *const T) -> isize { +unsafe fn data_offset(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(ptr: *const T) -> isize { } #[inline] -fn data_offset_align(align: usize) -> isize { +fn data_offset_align(align: usize) -> usize { let layout = Layout::new::>(); - (layout.size() + layout.padding_needed_for(align)) as isize + layout.size() + layout.padding_needed_for(align) } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 24e849aab4cce..4c03cc3ed158a 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -908,8 +908,7 @@ impl Arc { 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); + let arc_ptr = ptr.byte_sub(offset) as *mut ArcInner; Self::from_ptr(arc_ptr) } @@ -1942,7 +1941,7 @@ impl Weak { 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) } + unsafe { ptr.byte_sub(offset) as *mut ArcInner } }; // SAFETY: we now have recovered the original Weak pointer, so can create the Weak. @@ -2749,7 +2748,7 @@ impl Unpin for Arc {} /// /// 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(ptr: *const T) -> isize { +unsafe fn data_offset(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(ptr: *const T) -> isize { } #[inline] -fn data_offset_align(align: usize) -> isize { +fn data_offset_align(align: usize) -> usize { let layout = Layout::new::>(); - (layout.size() + layout.padding_needed_for(align)) as isize + layout.size() + layout.padding_needed_for(align) } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 91733004e44c3..4170c73b24625 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1442,7 +1442,6 @@ static DEFAULT_ID_MAP: Lazy, usize>> = Lazy::new(|| fn init_id_map() -> FxHashMap, 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, 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); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index e8f069cdbfe0c..c6933a8254bc2 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -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"); } diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 73d18df76561b..142ce456c5213 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -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; diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 93dca51307f58..aeaca7515f962 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -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; diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 73731bc8f9ff3..54d1a7b65d665 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -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; diff --git a/src/test/ui/argument-suggestions/exotic-calls.rs b/src/test/ui/argument-suggestions/exotic-calls.rs new file mode 100644 index 0000000000000..a18e967668def --- /dev/null +++ b/src/test/ui/argument-suggestions/exotic-calls.rs @@ -0,0 +1,26 @@ +fn foo(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() {} diff --git a/src/test/ui/argument-suggestions/exotic-calls.stderr b/src/test/ui/argument-suggestions/exotic-calls.stderr new file mode 100644 index 0000000000000..ca93ecc4e381a --- /dev/null +++ b/src/test/ui/argument-suggestions/exotic-calls.stderr @@ -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: 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`. diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89436.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89436.rs new file mode 100644 index 0000000000000..f7e467b3786dc --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89436.rs @@ -0,0 +1,44 @@ +// check-pass + +#![allow(unused)] + +trait MiniYokeable<'a> { + type Output; +} + +struct MiniYoke MiniYokeable<'a>> { + pub yokeable: Y, +} + +fn map_project_broken( + source: MiniYoke, + f: impl for<'a> FnOnce( + >::Output, + core::marker::PhantomData<&'a ()>, + ) ->

>::Output, +) -> MiniYoke

+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>) -> MiniYoke<&'static str> { + map_project_broken(bar, |bar, _| bar.string_1) +} + +fn main() {} diff --git a/src/test/ui/issues/issue-16939.stderr b/src/test/ui/issues/issue-16939.stderr index 294524f0b6148..aaa3c49b3d83e 100644 --- a/src/test/ui/issues/issue-16939.stderr +++ b/src/test/ui/issues/issue-16939.stderr @@ -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: F) { + | ^^^^ help: remove the extra argument | LL | |t| f(); diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr index cb93a7ad9008d..475ea9dfaf1b4 100644 --- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr +++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr @@ -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 */); diff --git a/triagebot.toml b/triagebot.toml index 3842da566a91d..f2930b50e3ee8 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -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"]