Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bbe9d27

Browse files
committed
Auto merge of #95702 - Dylan-DPC:rollup-793rz6v, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - #88025 (ScmCredentials netbsd implementation.) - #95473 (track individual proc-macro expansions in the self-profiler) - #95547 (caution against ptr-to-int transmutes) - #95585 (Explain why `&T` is cloned when `T` is not `Clone`) - #95591 (Use revisions to track NLL test output (part 1)) - #95663 (diagnostics: give a special note for unsafe fn / Fn/FnOnce/FnMut) - #95673 (:arrow_up: rust-analyzer) - #95681 (resolve: Fix resolution of empty paths passed from rustdoc) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 306ba83 + 728f263 commit bbe9d27

File tree

132 files changed

+877
-369
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+877
-369
lines changed

‎compiler/rustc_expand/src/base.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,12 @@ impl<'a> ExtCtxt<'a> {
10471047
self.current_expansion.id.expn_data().call_site
10481048
}
10491049

1050+
/// Returns the current expansion kind's description.
1051+
pub(crate) fn expansion_descr(&self) -> String {
1052+
let expn_data = self.current_expansion.id.expn_data();
1053+
expn_data.kind.descr()
1054+
}
1055+
10501056
/// Equivalent of `Span::def_site` from the proc macro API,
10511057
/// except that the location is taken from the span passed as an argument.
10521058
pub fn with_def_site_ctxt(&self, span: Span) -> Span {

‎compiler/rustc_expand/src/proc_macro.rs‎

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ impl base::ProcMacro for BangProcMacro {
2424
span: Span,
2525
input: TokenStream,
2626
) -> Result<TokenStream, ErrorGuaranteed> {
27+
let _timer =
28+
ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr());
2729
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
2830
let server = proc_macro_server::Rustc::new(ecx);
2931
self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace).map_err(|e| {
@@ -48,6 +50,8 @@ impl base::AttrProcMacro for AttrProcMacro {
4850
annotation: TokenStream,
4951
annotated: TokenStream,
5052
) -> Result<TokenStream, ErrorGuaranteed> {
53+
let _timer =
54+
ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr());
5155
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
5256
let server = proc_macro_server::Rustc::new(ecx);
5357
self.client
@@ -97,17 +101,21 @@ impl MultiItemModifier for ProcMacroDerive {
97101
nt_to_tokenstream(&item, &ecx.sess.parse_sess, CanSynthesizeMissingTokens::No)
98102
};
99103

100-
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
101-
let server = proc_macro_server::Rustc::new(ecx);
102-
let stream = match self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace) {
103-
Ok(stream) => stream,
104-
Err(e) => {
105-
let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
106-
if let Some(s) = e.as_str() {
107-
err.help(&format!("message: {}", s));
104+
let stream = {
105+
let _timer =
106+
ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr());
107+
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
108+
let server = proc_macro_server::Rustc::new(ecx);
109+
match self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace) {
110+
Ok(stream) => stream,
111+
Err(e) => {
112+
let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
113+
if let Some(s) = e.as_str() {
114+
err.help(&format!("message: {}", s));
115+
}
116+
err.emit();
117+
return ExpandResult::Ready(vec![]);
108118
}
109-
err.emit();
110-
return ExpandResult::Ready(vec![]);
111119
}
112120
};
113121

‎compiler/rustc_resolve/src/lib.rs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3298,7 +3298,9 @@ impl<'a> Resolver<'a> {
32983298
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
32993299
Some(path_res.base_res())
33003300
}
3301-
PathResult::NonModule(..) | PathResult::Failed { .. } => None,
3301+
PathResult::Module(ModuleOrUniformRoot::ExternPrelude)
3302+
| PathResult::NonModule(..)
3303+
| PathResult::Failed { .. } => None,
33023304
PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
33033305
}
33043306
}

‎compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
208208
flags.push((sym::_Self, Some("&[]".to_owned())));
209209
}
210210

211+
if self_ty.is_fn() {
212+
let fn_sig = self_ty.fn_sig(self.tcx);
213+
let shortname = match fn_sig.unsafety() {
214+
hir::Unsafety::Normal => "fn",
215+
hir::Unsafety::Unsafe => "unsafe fn",
216+
};
217+
flags.push((sym::_Self, Some(shortname.to_owned())));
218+
}
219+
211220
if let ty::Array(aty, len) = self_ty.kind() {
212221
flags.push((sym::_Self, Some("[]".to_owned())));
213222
flags.push((sym::_Self, Some(format!("[{}]", aty))));

‎compiler/rustc_typeck/src/check/demand.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4040
self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty);
4141
self.suggest_missing_parentheses(err, expr);
4242
self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected);
43+
self.note_type_is_not_clone(err, expected, expr_ty, expr);
4344
self.note_need_for_fn_pointer(err, expected, expr_ty);
4445
self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
4546
self.report_closure_inferred_return_type(err, expected);
@@ -630,7 +631,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
630631
Applicability::MachineApplicable,
631632
true,
632633
));
633-
634634
}
635635
}
636636
_ => {}

‎compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs‎

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ use super::FnCtxt;
22
use crate::astconv::AstConv;
33

44
use rustc_ast::util::parser::ExprPrecedence;
5-
use rustc_span::{self, Span};
6-
75
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
86
use rustc_hir as hir;
97
use rustc_hir::def::{CtorOf, DefKind};
@@ -13,12 +11,14 @@ use rustc_hir::{
1311
WherePredicate,
1412
};
1513
use rustc_infer::infer::{self, TyCtxtInferExt};
16-
14+
use rustc_infer::traits;
1715
use rustc_middle::lint::in_external_macro;
18-
use rustc_middle::ty::{self, Binder, Ty};
16+
use rustc_middle::ty::subst::GenericArgKind;
17+
use rustc_middle::ty::{self, Binder, ToPredicate, Ty};
1918
use rustc_span::symbol::{kw, sym};
19+
use rustc_span::Span;
20+
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
2021

21-
use rustc_middle::ty::subst::GenericArgKind;
2222
use std::iter;
2323

2424
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -846,4 +846,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
846846
let node = self.tcx.hir().get(id);
847847
matches!(node, Node::Stmt(Stmt { kind: StmtKind::Local(..), .. }))
848848
}
849+
850+
/// Suggest that `&T` was cloned instead of `T` because `T` does not implement `Clone`,
851+
/// which is a side-effect of autoref.
852+
pub(crate) fn note_type_is_not_clone(
853+
&self,
854+
diag: &mut Diagnostic,
855+
expected_ty: Ty<'tcx>,
856+
found_ty: Ty<'tcx>,
857+
expr: &hir::Expr<'_>,
858+
) {
859+
let hir::ExprKind::MethodCall(segment, &[ref callee_expr], _) = expr.kind else { return; };
860+
let Some(clone_trait_did) = self.tcx.lang_items().clone_trait() else { return; };
861+
let ty::Ref(_, pointee_ty, _) = found_ty.kind() else { return };
862+
let results = self.typeck_results.borrow();
863+
// First, look for a `Clone::clone` call
864+
if segment.ident.name == sym::clone
865+
&& results.type_dependent_def_id(expr.hir_id).map_or(
866+
false,
867+
|did| {
868+
self.tcx.associated_item(did).container
869+
== ty::AssocItemContainer::TraitContainer(clone_trait_did)
870+
},
871+
)
872+
// If that clone call hasn't already dereferenced the self type (i.e. don't give this
873+
// diagnostic in cases where we have `(&&T).clone()` and we expect `T`).
874+
&& !results.expr_adjustments(callee_expr).iter().any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(..)))
875+
// Check that we're in fact trying to clone into the expected type
876+
&& self.can_coerce(*pointee_ty, expected_ty)
877+
// And the expected type doesn't implement `Clone`
878+
&& !self.predicate_must_hold_considering_regions(&traits::Obligation {
879+
cause: traits::ObligationCause::dummy(),
880+
param_env: self.param_env,
881+
recursion_depth: 0,
882+
predicate: ty::Binder::dummy(ty::TraitRef {
883+
def_id: clone_trait_did,
884+
substs: self.tcx.mk_substs([expected_ty.into()].iter()),
885+
})
886+
.without_const()
887+
.to_predicate(self.tcx),
888+
})
889+
{
890+
diag.span_note(
891+
callee_expr.span,
892+
&format!(
893+
"`{expected_ty}` does not implement `Clone`, so `{found_ty}` was cloned instead"
894+
),
895+
);
896+
}
897+
}
849898
}

‎library/core/src/intrinsics.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,16 @@ extern "rust-intrinsic" {
991991
/// let ptr_num_cast = ptr as *const i32 as usize;
992992
/// ```
993993
///
994+
/// Note that using `transmute` to turn a pointer to a `usize` is (as noted above) [undefined
995+
/// behavior][ub] in `const` contexts. Also outside of consts, this operation might not behave
996+
/// as expected -- this is touching on many unspecified aspects of the Rust memory model.
997+
/// Depending on what the code is doing, the following alternatives are preferrable to
998+
/// pointer-to-integer transmutation:
999+
/// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a
1000+
/// type for that buffer, it can use [`MaybeUninit`][mem::MaybeUninit].
1001+
/// - If the code actually wants to work on the address the pointer points to, it can use `as`
1002+
/// casts or [`ptr.addr()`][pointer::addr].
1003+
///
9941004
/// Turning a `*mut T` into an `&mut T`:
9951005
///
9961006
/// ```

‎library/core/src/ops/function.rs‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@
6060
Args = "()",
6161
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
6262
),
63+
on(
64+
_Self = "unsafe fn",
65+
note = "unsafe function cannot be called generically without an unsafe block",
66+
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
67+
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
68+
),
6369
message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
6470
label = "expected an `Fn<{Args}>` closure, found `{Self}`"
6571
)]
@@ -141,6 +147,12 @@ pub trait Fn<Args>: FnMut<Args> {
141147
Args = "()",
142148
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
143149
),
150+
on(
151+
_Self = "unsafe fn",
152+
note = "unsafe function cannot be called generically without an unsafe block",
153+
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
154+
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
155+
),
144156
message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
145157
label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
146158
)]
@@ -214,6 +226,12 @@ pub trait FnMut<Args>: FnOnce<Args> {
214226
Args = "()",
215227
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
216228
),
229+
on(
230+
_Self = "unsafe fn",
231+
note = "unsafe function cannot be called generically without an unsafe block",
232+
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
233+
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
234+
),
217235
message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
218236
label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
219237
)]

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /