Skip to content

Commit 522abf6

Browse files
committed
Auto merge of rust-lang#99267 - Dylan-DPC:rollup-d8l7y1o, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - rust-lang#99113 (Simplify [a]rc code a little) - rust-lang#99131 (Add label for generic arg (+ APIT) and RPIT callables in `label_fn_like`) - rust-lang#99237 (removed unused CSS and unused HTML IDs) - rust-lang#99239 (Add myself to the set of people notified when MIR changes.) - rust-lang#99241 (Remove comment referring to constness.rs) - rust-lang#99257 (Add regression test for rust-lang#89436) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents b90a0ed + 7976cd6 commit 522abf6

File tree

17 files changed

+358
-163
lines changed

17 files changed

+358
-163
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

-2
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
132132
Some(p) => p,
133133
};
134134

135-
// Keep the patterns in this match ordered the same as the list in
136-
// `src/librustc_middle/ty/constness.rs`
137135
match intrinsic_name {
138136
sym::caller_location => {
139137
let span = self.find_closest_untracked_caller_location();

compiler/rustc_middle/src/ty/closure.rs

+8
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ impl<'tcx> ClosureKind {
128128
None
129129
}
130130
}
131+
132+
pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId {
133+
match self {
134+
ClosureKind::Fn => tcx.lang_items().fn_once_trait().unwrap(),
135+
ClosureKind::FnMut => tcx.lang_items().fn_mut_trait().unwrap(),
136+
ClosureKind::FnOnce => tcx.lang_items().fn_trait().unwrap(),
137+
}
138+
}
131139
}
132140

133141
/// A composite describing a `Place` that is captured by a closure.

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

+179-84
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,18 @@ use rustc_hir::def_id::DefId;
2121
use rustc_hir::{ExprKind, Node, QPath};
2222
use rustc_index::vec::IndexVec;
2323
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
24+
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
2425
use rustc_infer::infer::InferOk;
2526
use rustc_infer::infer::TypeTrace;
2627
use rustc_middle::ty::adjustment::AllowTwoPhase;
2728
use rustc_middle::ty::visit::TypeVisitable;
28-
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
29+
use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty};
2930
use rustc_session::Session;
3031
use rustc_span::symbol::Ident;
3132
use rustc_span::{self, Span};
32-
use rustc_trait_selection::traits::{self, ObligationCauseCode, StatementAsExpression};
33+
use rustc_trait_selection::traits::{
34+
self, ObligationCauseCode, SelectionContext, StatementAsExpression,
35+
};
3336

3437
use std::iter;
3538
use std::slice;
@@ -89,7 +92,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8992
args_no_rcvr,
9093
false,
9194
tuple_arguments,
92-
None,
95+
method.ok().map(|method| method.def_id),
9396
);
9497
return self.tcx.ty_error();
9598
}
@@ -393,41 +396,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
393396
}
394397

395398
if !call_appears_satisfied {
396-
// Next, let's construct the error
397-
let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
398-
hir::ExprKind::Call(
399-
hir::Expr {
400-
span,
401-
kind:
402-
hir::ExprKind::Path(hir::QPath::Resolved(
403-
_,
404-
hir::Path { res: Res::Def(DefKind::Ctor(of, _), _), .. },
405-
)),
406-
..
407-
},
408-
_,
409-
) => (call_span, *span, Some(of)),
410-
hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None),
411-
hir::ExprKind::MethodCall(path_segment, _, span) => {
412-
let ident_span = path_segment.ident.span;
413-
let ident_span = if let Some(args) = path_segment.args {
414-
ident_span.with_hi(args.span_ext.hi())
415-
} else {
416-
ident_span
417-
};
418-
(
419-
*span, ident_span, None, // methods are never ctors
420-
)
421-
}
422-
k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
423-
};
424-
let args_span = error_span.trim_start(full_call_span).unwrap_or(error_span);
425-
let call_name = match ctor_of {
426-
Some(CtorOf::Struct) => "struct",
427-
Some(CtorOf::Variant) => "enum variant",
428-
None => "function",
429-
};
430-
431399
let compatibility_diagonal = IndexVec::from_raw(compatibility_diagonal);
432400
let provided_args = IndexVec::from_iter(provided_args.iter().take(if c_variadic {
433401
minimum_input_count
@@ -451,13 +419,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
451419
compatibility_diagonal,
452420
formal_and_expected_inputs,
453421
provided_args,
454-
full_call_span,
455-
error_span,
456-
args_span,
457-
call_name,
458422
c_variadic,
459423
err_code,
460424
fn_def_id,
425+
call_span,
426+
call_expr,
461427
);
462428
}
463429
}
@@ -467,14 +433,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
467433
compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>,
468434
formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
469435
provided_args: IndexVec<ProvidedIdx, &'tcx hir::Expr<'tcx>>,
470-
full_call_span: Span,
471-
error_span: Span,
472-
args_span: Span,
473-
call_name: &str,
474436
c_variadic: bool,
475437
err_code: &str,
476438
fn_def_id: Option<DefId>,
439+
call_span: Span,
440+
call_expr: &hir::Expr<'tcx>,
477441
) {
442+
// Next, let's construct the error
443+
let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
444+
hir::ExprKind::Call(
445+
hir::Expr {
446+
span,
447+
kind:
448+
hir::ExprKind::Path(hir::QPath::Resolved(
449+
_,
450+
hir::Path { res: Res::Def(DefKind::Ctor(of, _), _), .. },
451+
)),
452+
..
453+
},
454+
_,
455+
) => (call_span, *span, Some(of)),
456+
hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None),
457+
hir::ExprKind::MethodCall(path_segment, _, span) => {
458+
let ident_span = path_segment.ident.span;
459+
let ident_span = if let Some(args) = path_segment.args {
460+
ident_span.with_hi(args.span_ext.hi())
461+
} else {
462+
ident_span
463+
};
464+
(
465+
*span, ident_span, None, // methods are never ctors
466+
)
467+
}
468+
k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
469+
};
470+
let args_span = error_span.trim_start(full_call_span).unwrap_or(error_span);
471+
let call_name = match ctor_of {
472+
Some(CtorOf::Struct) => "struct",
473+
Some(CtorOf::Variant) => "enum variant",
474+
None => "function",
475+
};
476+
478477
// Don't print if it has error types or is just plain `_`
479478
fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
480479
tys.into_iter().any(|ty| ty.references_error() || ty.is_ty_var())
@@ -495,6 +494,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
495494
(self.resolve_vars_if_possible(ty), expr.span)
496495
})
497496
.collect();
497+
let callee_expr = match &call_expr.peel_blocks().kind {
498+
hir::ExprKind::Call(callee, _) => Some(*callee),
499+
hir::ExprKind::MethodCall(_, callee, _) => {
500+
if let Some((DefKind::AssocFn, def_id)) =
501+
self.typeck_results.borrow().type_dependent_def(call_expr.hir_id)
502+
&& let Some(assoc) = tcx.opt_associated_item(def_id)
503+
&& assoc.fn_has_self_parameter
504+
{
505+
Some(&callee[0])
506+
} else {
507+
None
508+
}
509+
}
510+
_ => None,
511+
};
512+
let callee_ty = callee_expr
513+
.and_then(|callee_expr| self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr));
498514

499515
// A "softer" version of the `demand_compatible`, which checks types without persisting them,
500516
// and treats error types differently
@@ -631,7 +647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
631647
Applicability::MachineApplicable,
632648
);
633649
};
634-
label_fn_like(tcx, &mut err, fn_def_id);
650+
self.label_fn_like(&mut err, fn_def_id, callee_ty);
635651
err.emit();
636652
return;
637653
}
@@ -721,7 +737,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
721737
format!("arguments to this {} are incorrect", call_name),
722738
);
723739
// Call out where the function is defined
724-
label_fn_like(tcx, &mut err, fn_def_id);
740+
self.label_fn_like(&mut err, fn_def_id, callee_ty);
725741
err.emit();
726742
return;
727743
}
@@ -1003,7 +1019,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10031019
}
10041020

10051021
// Call out where the function is defined
1006-
label_fn_like(tcx, &mut err, fn_def_id);
1022+
self.label_fn_like(&mut err, fn_def_id, callee_ty);
10071023

10081024
// And add a suggestion block for all of the parameters
10091025
let suggestion_text = match suggestion_text {
@@ -1795,47 +1811,126 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17951811
}
17961812
}
17971813
}
1798-
}
17991814

1800-
fn label_fn_like<'tcx>(
1801-
tcx: TyCtxt<'tcx>,
1802-
err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>,
1803-
def_id: Option<DefId>,
1804-
) {
1805-
let Some(def_id) = def_id else {
1806-
return;
1807-
};
1808-
1809-
if let Some(def_span) = tcx.def_ident_span(def_id) {
1810-
let mut spans: MultiSpan = def_span.into();
1811-
1812-
let params = tcx
1813-
.hir()
1814-
.get_if_local(def_id)
1815-
.and_then(|node| node.body_id())
1816-
.into_iter()
1817-
.flat_map(|id| tcx.hir().body(id).params);
1818-
1819-
for param in params {
1820-
spans.push_span_label(param.span, "");
1815+
fn label_fn_like(
1816+
&self,
1817+
err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>,
1818+
callable_def_id: Option<DefId>,
1819+
callee_ty: Option<Ty<'tcx>>,
1820+
) {
1821+
let Some(mut def_id) = callable_def_id else {
1822+
return;
1823+
};
1824+
1825+
if let Some(assoc_item) = self.tcx.opt_associated_item(def_id)
1826+
// Possibly points at either impl or trait item, so try to get it
1827+
// to point to trait item, then get the parent.
1828+
// This parent might be an impl in the case of an inherent function,
1829+
// but the next check will fail.
1830+
&& let maybe_trait_item_def_id = assoc_item.trait_item_def_id.unwrap_or(def_id)
1831+
&& let maybe_trait_def_id = self.tcx.parent(maybe_trait_item_def_id)
1832+
// Just an easy way to check "trait_def_id == Fn/FnMut/FnOnce"
1833+
&& let Some(call_kind) = ty::ClosureKind::from_def_id(self.tcx, maybe_trait_def_id)
1834+
&& let Some(callee_ty) = callee_ty
1835+
{
1836+
let callee_ty = callee_ty.peel_refs();
1837+
match *callee_ty.kind() {
1838+
ty::Param(param) => {
1839+
let param =
1840+
self.tcx.generics_of(self.body_id.owner).type_param(&param, self.tcx);
1841+
if param.kind.is_synthetic() {
1842+
// if it's `impl Fn() -> ..` then just fall down to the def-id based logic
1843+
def_id = param.def_id;
1844+
} else {
1845+
// Otherwise, find the predicate that makes this generic callable,
1846+
// and point at that.
1847+
let instantiated = self
1848+
.tcx
1849+
.explicit_predicates_of(self.body_id.owner)
1850+
.instantiate_identity(self.tcx);
1851+
// FIXME(compiler-errors): This could be problematic if something has two
1852+
// fn-like predicates with different args, but callable types really never
1853+
// do that, so it's OK.
1854+
for (predicate, span) in
1855+
std::iter::zip(instantiated.predicates, instantiated.spans)
1856+
{
1857+
if let ty::PredicateKind::Trait(pred) = predicate.kind().skip_binder()
1858+
&& pred.self_ty().peel_refs() == callee_ty
1859+
&& ty::ClosureKind::from_def_id(self.tcx, pred.def_id()).is_some()
1860+
{
1861+
err.span_note(span, "callable defined here");
1862+
return;
1863+
}
1864+
}
1865+
}
1866+
}
1867+
ty::Opaque(new_def_id, _)
1868+
| ty::Closure(new_def_id, _)
1869+
| ty::FnDef(new_def_id, _) => {
1870+
def_id = new_def_id;
1871+
}
1872+
_ => {
1873+
// Look for a user-provided impl of a `Fn` trait, and point to it.
1874+
let new_def_id = self.probe(|_| {
1875+
let trait_ref = ty::TraitRef::new(
1876+
call_kind.to_def_id(self.tcx),
1877+
self.tcx.mk_substs([
1878+
ty::GenericArg::from(callee_ty),
1879+
self.next_ty_var(TypeVariableOrigin {
1880+
kind: TypeVariableOriginKind::MiscVariable,
1881+
span: rustc_span::DUMMY_SP,
1882+
})
1883+
.into(),
1884+
].into_iter()),
1885+
);
1886+
let obligation = traits::Obligation::new(
1887+
traits::ObligationCause::dummy(),
1888+
self.param_env,
1889+
ty::Binder::dummy(ty::TraitPredicate {
1890+
trait_ref,
1891+
constness: ty::BoundConstness::NotConst,
1892+
polarity: ty::ImplPolarity::Positive,
1893+
}),
1894+
);
1895+
match SelectionContext::new(&self).select(&obligation) {
1896+
Ok(Some(traits::ImplSource::UserDefined(impl_source))) => {
1897+
Some(impl_source.impl_def_id)
1898+
}
1899+
_ => None
1900+
}
1901+
});
1902+
if let Some(new_def_id) = new_def_id {
1903+
def_id = new_def_id;
1904+
} else {
1905+
return;
1906+
}
1907+
}
1908+
}
18211909
}
18221910

1823-
let def_kind = tcx.def_kind(def_id);
1824-
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
1825-
} else {
1826-
match tcx.hir().get_if_local(def_id) {
1827-
Some(hir::Node::Expr(hir::Expr {
1828-
kind: hir::ExprKind::Closure(hir::Closure { fn_decl_span, .. }),
1829-
..
1830-
})) => {
1831-
let spans: MultiSpan = (*fn_decl_span).into();
1911+
if let Some(def_span) = self.tcx.def_ident_span(def_id) && !def_span.is_dummy() {
1912+
let mut spans: MultiSpan = def_span.into();
18321913

1833-
// Note: We don't point to param spans here because they overlap
1834-
// with the closure span itself
1914+
let params = self
1915+
.tcx
1916+
.hir()
1917+
.get_if_local(def_id)
1918+
.and_then(|node| node.body_id())
1919+
.into_iter()
1920+
.flat_map(|id| self.tcx.hir().body(id).params);
18351921

1836-
err.span_note(spans, "closure defined here");
1922+
for param in params {
1923+
spans.push_span_label(param.span, "");
18371924
}
1838-
_ => {}
1925+
1926+
let def_kind = self.tcx.def_kind(def_id);
1927+
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
1928+
} else {
1929+
let def_kind = self.tcx.def_kind(def_id);
1930+
err.span_note(
1931+
self.tcx.def_span(def_id),
1932+
&format!("{} defined here", def_kind.descr(def_id)),
1933+
);
18391934
}
18401935
}
18411936
}

library/alloc/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
#![cfg_attr(test, feature(new_uninit))]
125125
#![feature(nonnull_slice_from_raw_parts)]
126126
#![feature(pattern)]
127+
#![feature(pointer_byte_offsets)]
127128
#![feature(ptr_internals)]
128129
#![feature(ptr_metadata)]
129130
#![feature(ptr_sub_ptr)]

0 commit comments

Comments
 (0)