Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #95702

Merged
merged 22 commits into from
Apr 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2d74528
caution against ptr-to-int transmutes
RalfJung Apr 1, 2022
dd85a76
refine wording and describe alternatives
RalfJung Apr 2, 2022
23e6314
ScmCredentials netbsd implementation.
devnexen Aug 14, 2021
bec8dbd
diagnostics: give a special note for unsafe fn / Fn/FnOnce/FnMut
notriddle Apr 5, 2022
dcf7ce8
Fix bogus tidy errors
notriddle Apr 5, 2022
505573e
:arrow_up: rust-analyzer
lnicola Apr 5, 2022
9ac8d2f
track proc-macro expansions in the self-profiler
lqd Mar 30, 2022
7faaf8f
resolve: Fix resolution of empty paths passed from rustdoc
petrochenkov Apr 5, 2022
72e3e0e
Move some tests with compare-mode=nll output to revisions
jackh726 Apr 1, 2022
1c1d01e
More nll revisions
jackh726 Apr 2, 2022
a2946ae
underscore-lifetime nll revisions
jackh726 Apr 2, 2022
f881bf7
unboxed-closures and type-alias-impl-trait nll revisions
jackh726 Apr 2, 2022
d12689c
Explain why `&T` is cloned when `T` is not `Clone`
compiler-errors Apr 2, 2022
6d18fbb
diagnostics: tweak error message to give more rationale to unsafe Fn
notriddle Apr 5, 2022
d2e1e6d
Rollup merge of #88025 - devnexen:netbsd_scm_creds, r=Amanieu
Dylan-DPC Apr 5, 2022
c5e7e95
Rollup merge of #95473 - lqd:macro-expansion, r=petrochenkov
Dylan-DPC Apr 5, 2022
e597d06
Rollup merge of #95547 - RalfJung:ptr-int-transmutes, r=scottmcm
Dylan-DPC Apr 5, 2022
42ab448
Rollup merge of #95585 - compiler-errors:ref-clone, r=estebank
Dylan-DPC Apr 5, 2022
cbf54fa
Rollup merge of #95591 - jackh726:nll-revisions-1, r=oli-obk
Dylan-DPC Apr 5, 2022
1e555ba
Rollup merge of #95663 - notriddle:notriddle/unsafe-fn-closure, r=com…
Dylan-DPC Apr 5, 2022
eda2f81
Rollup merge of #95673 - lnicola:rust-analyzer-2022-04-05, r=lnicola
Dylan-DPC Apr 5, 2022
728f263
Rollup merge of #95681 - petrochenkov:doclinkregr2, r=Dylan-DPC
Dylan-DPC Apr 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,12 @@ impl<'a> ExtCtxt<'a> {
self.current_expansion.id.expn_data().call_site
}

/// Returns the current expansion kind's description.
pub(crate) fn expansion_descr(&self) -> String {
let expn_data = self.current_expansion.id.expn_data();
expn_data.kind.descr()
}

/// Equivalent of `Span::def_site` from the proc macro API,
/// except that the location is taken from the span passed as an argument.
pub fn with_def_site_ctxt(&self, span: Span) -> Span {
Expand Down
28 changes: 18 additions & 10 deletions compiler/rustc_expand/src/proc_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ impl base::ProcMacro for BangProcMacro {
span: Span,
input: TokenStream,
) -> Result<TokenStream, ErrorGuaranteed> {
let _timer =
ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr());
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
let server = proc_macro_server::Rustc::new(ecx);
self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace).map_err(|e| {
Expand All @@ -48,6 +50,8 @@ impl base::AttrProcMacro for AttrProcMacro {
annotation: TokenStream,
annotated: TokenStream,
) -> Result<TokenStream, ErrorGuaranteed> {
let _timer =
ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr());
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
let server = proc_macro_server::Rustc::new(ecx);
self.client
Expand Down Expand Up @@ -97,17 +101,21 @@ impl MultiItemModifier for ProcMacroDerive {
nt_to_tokenstream(&item, &ecx.sess.parse_sess, CanSynthesizeMissingTokens::No)
};

let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
let server = proc_macro_server::Rustc::new(ecx);
let stream = match self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace) {
Ok(stream) => stream,
Err(e) => {
let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
if let Some(s) = e.as_str() {
err.help(&format!("message: {}", s));
let stream = {
let _timer =
ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr());
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
let server = proc_macro_server::Rustc::new(ecx);
match self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace) {
Ok(stream) => stream,
Err(e) => {
let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
if let Some(s) = e.as_str() {
err.help(&format!("message: {}", s));
}
err.emit();
return ExpandResult::Ready(vec![]);
}
err.emit();
return ExpandResult::Ready(vec![]);
}
};

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3298,7 +3298,9 @@ impl<'a> Resolver<'a> {
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
Some(path_res.base_res())
}
PathResult::NonModule(..) | PathResult::Failed { .. } => None,
PathResult::Module(ModuleOrUniformRoot::ExternPrelude)
| PathResult::NonModule(..)
| PathResult::Failed { .. } => None,
PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
flags.push((sym::_Self, Some("&[]".to_owned())));
}

if self_ty.is_fn() {
let fn_sig = self_ty.fn_sig(self.tcx);
let shortname = match fn_sig.unsafety() {
hir::Unsafety::Normal => "fn",
hir::Unsafety::Unsafe => "unsafe fn",
};
flags.push((sym::_Self, Some(shortname.to_owned())));
}

if let ty::Array(aty, len) = self_ty.kind() {
flags.push((sym::_Self, Some("[]".to_owned())));
flags.push((sym::_Self, Some(format!("[{}]", aty))));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty);
self.suggest_missing_parentheses(err, expr);
self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected);
self.note_type_is_not_clone(err, expected, expr_ty, expr);
self.note_need_for_fn_pointer(err, expected, expr_ty);
self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
self.report_closure_inferred_return_type(err, expected);
Expand Down Expand Up @@ -630,7 +631,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Applicability::MachineApplicable,
true,
));

}
}
_ => {}
Expand Down
59 changes: 54 additions & 5 deletions compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ use super::FnCtxt;
use crate::astconv::AstConv;

use rustc_ast::util::parser::ExprPrecedence;
use rustc_span::{self, Span};

use rustc_errors::{Applicability, Diagnostic, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind};
Expand All @@ -13,12 +11,14 @@ use rustc_hir::{
WherePredicate,
};
use rustc_infer::infer::{self, TyCtxtInferExt};

use rustc_infer::traits;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Binder, Ty};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, Binder, ToPredicate, Ty};
use rustc_span::symbol::{kw, sym};
use rustc_span::Span;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;

use rustc_middle::ty::subst::GenericArgKind;
use std::iter;

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Expand Down Expand Up @@ -846,4 +846,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let node = self.tcx.hir().get(id);
matches!(node, Node::Stmt(Stmt { kind: StmtKind::Local(..), .. }))
}

/// Suggest that `&T` was cloned instead of `T` because `T` does not implement `Clone`,
/// which is a side-effect of autoref.
pub(crate) fn note_type_is_not_clone(
&self,
diag: &mut Diagnostic,
expected_ty: Ty<'tcx>,
found_ty: Ty<'tcx>,
expr: &hir::Expr<'_>,
) {
let hir::ExprKind::MethodCall(segment, &[ref callee_expr], _) = expr.kind else { return; };
let Some(clone_trait_did) = self.tcx.lang_items().clone_trait() else { return; };
let ty::Ref(_, pointee_ty, _) = found_ty.kind() else { return };
let results = self.typeck_results.borrow();
// First, look for a `Clone::clone` call
if segment.ident.name == sym::clone
&& results.type_dependent_def_id(expr.hir_id).map_or(
false,
|did| {
self.tcx.associated_item(did).container
== ty::AssocItemContainer::TraitContainer(clone_trait_did)
},
)
// If that clone call hasn't already dereferenced the self type (i.e. don't give this
// diagnostic in cases where we have `(&&T).clone()` and we expect `T`).
&& !results.expr_adjustments(callee_expr).iter().any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(..)))
// Check that we're in fact trying to clone into the expected type
&& self.can_coerce(*pointee_ty, expected_ty)
// And the expected type doesn't implement `Clone`
&& !self.predicate_must_hold_considering_regions(&traits::Obligation {
cause: traits::ObligationCause::dummy(),
param_env: self.param_env,
recursion_depth: 0,
predicate: ty::Binder::dummy(ty::TraitRef {
def_id: clone_trait_did,
substs: self.tcx.mk_substs([expected_ty.into()].iter()),
})
.without_const()
.to_predicate(self.tcx),
})
{
diag.span_note(
callee_expr.span,
&format!(
"`{expected_ty}` does not implement `Clone`, so `{found_ty}` was cloned instead"
),
);
}
}
}
10 changes: 10 additions & 0 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,16 @@ extern "rust-intrinsic" {
/// let ptr_num_cast = ptr as *const i32 as usize;
/// ```
///
/// Note that using `transmute` to turn a pointer to a `usize` is (as noted above) [undefined
/// behavior][ub] in `const` contexts. Also outside of consts, this operation might not behave
/// as expected -- this is touching on many unspecified aspects of the Rust memory model.
/// Depending on what the code is doing, the following alternatives are preferrable to
/// pointer-to-integer transmutation:
/// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a
/// type for that buffer, it can use [`MaybeUninit`][mem::MaybeUninit].
/// - If the code actually wants to work on the address the pointer points to, it can use `as`
/// casts or [`ptr.addr()`][pointer::addr].
///
/// Turning a `*mut T` into an `&mut T`:
///
/// ```
Expand Down
18 changes: 18 additions & 0 deletions library/core/src/ops/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
),
on(
_Self = "unsafe fn",
note = "unsafe function cannot be called generically without an unsafe block",
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
),
message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
label = "expected an `Fn<{Args}>` closure, found `{Self}`"
)]
Expand Down Expand Up @@ -141,6 +147,12 @@ pub trait Fn<Args>: FnMut<Args> {
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
),
on(
_Self = "unsafe fn",
note = "unsafe function cannot be called generically without an unsafe block",
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
),
message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
)]
Expand Down Expand Up @@ -214,6 +226,12 @@ pub trait FnMut<Args>: FnOnce<Args> {
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
),
on(
_Self = "unsafe fn",
note = "unsafe function cannot be called generically without an unsafe block",
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
),
message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
)]
Expand Down
Loading