Skip to content

Commit

Permalink
Auto merge of rust-lang#122571 - matthiaskrgr:rollup-36wwovk, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang#122254 (Detect calls to .clone() on T: !Clone types on borrowck errors)
 - rust-lang#122495 (Visually mark 👻hidden👻 items with document-hidden-items)
 - rust-lang#122543 (Add `#![rustc_never_type_mode = "..."]` crate-level attribute to allow experimenting)
 - rust-lang#122560 (Safe Transmute: Use 'not yet supported', not 'unspecified' in errors)
 - rust-lang#122562 (Mention labelled blocks in `break` docs)
 - rust-lang#122563 (CI: cache PR CI Docker builds)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 15, 2024
2 parents 1ca424c + 948e031 commit c67326b
Show file tree
Hide file tree
Showing 56 changed files with 711 additions and 362 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_borrowck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ borrowck_borrow_due_to_use_closure =
borrowck_borrow_due_to_use_coroutine =
borrow occurs due to use in coroutine
borrowck_calling_operator_moves =
calling this operator moves the value
borrowck_calling_operator_moves_lhs =
calling this operator moves the left-hand side
Expand Down
113 changes: 106 additions & 7 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
use rustc_hir::{CoroutineDesugaring, PatField};
use rustc_hir::{CoroutineKind, CoroutineSource, LangItem};
use rustc_infer::traits::ObligationCause;
use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::{
Expand All @@ -21,16 +20,21 @@ use rustc_middle::mir::{
PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
VarBindingForm,
};
use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty, TyCtxt};
use rustc_middle::ty::{
self, suggest_constraining_type_params, PredicateKind, ToPredicate, Ty, TyCtxt,
TypeSuperVisitable, TypeVisitor,
};
use rustc_middle::util::CallKind;
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
use rustc_span::def_id::DefId;
use rustc_span::def_id::LocalDefId;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
use rustc_trait_selection::traits::error_reporting::FindExprBySpan;
use rustc_trait_selection::traits::ObligationCtxt;
use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
use std::iter;

use crate::borrow_set::TwoPhaseActivation;
Expand Down Expand Up @@ -283,7 +287,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// something that already has `Fn`-like bounds (or is a closure), so we can't
// restrict anyways.
} else {
self.suggest_adding_copy_bounds(&mut err, ty, span);
let copy_did = self.infcx.tcx.require_lang_item(LangItem::Copy, Some(span));
self.suggest_adding_bounds(&mut err, ty, copy_did, span);
}

if needs_note {
Expand Down Expand Up @@ -774,7 +779,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}

fn suggest_adding_copy_bounds(&self, err: &mut Diag<'_>, ty: Ty<'tcx>, span: Span) {
fn suggest_adding_bounds(&self, err: &mut Diag<'_>, ty: Ty<'tcx>, def_id: DefId, span: Span) {
let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id());

Expand All @@ -787,10 +792,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
};
// Try to find predicates on *generic params* that would allow copying `ty`
let ocx = ObligationCtxt::new(self.infcx);
let copy_did = tcx.require_lang_item(LangItem::Copy, Some(span));
let cause = ObligationCause::misc(span, self.mir_def_id());

ocx.register_bound(cause, self.param_env, ty, copy_did);
ocx.register_bound(cause, self.param_env, ty, def_id);
let errors = ocx.select_all_or_error();

// Only emit suggestion if all required predicates are on generic
Expand Down Expand Up @@ -876,6 +880,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Some(borrow_span),
None,
);
self.suggest_copy_for_type_in_cloned_ref(&mut err, place);
self.buffer_error(err);
}

Expand Down Expand Up @@ -1214,10 +1219,104 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);

self.suggest_using_local_if_applicable(&mut err, location, issued_borrow, explanation);
self.suggest_copy_for_type_in_cloned_ref(&mut err, place);

err
}

fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'tcx>, place: Place<'tcx>) {
let tcx = self.infcx.tcx;
let hir = tcx.hir();
let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return };
struct FindUselessClone<'hir> {
pub clones: Vec<&'hir hir::Expr<'hir>>,
}
impl<'hir> FindUselessClone<'hir> {
pub fn new() -> Self {
Self { clones: vec![] }
}
}

impl<'v> Visitor<'v> for FindUselessClone<'v> {
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
// FIXME: use `lookup_method_for_diagnostic`?
if let hir::ExprKind::MethodCall(segment, _rcvr, args, _span) = ex.kind
&& segment.ident.name == sym::clone
&& args.len() == 0
{
self.clones.push(ex);
}
hir::intravisit::walk_expr(self, ex);
}
}
let mut expr_finder = FindUselessClone::new();

let body = hir.body(body_id).value;
expr_finder.visit_expr(body);

pub struct Holds<'tcx> {
ty: Ty<'tcx>,
holds: bool,
}

impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Holds<'tcx> {
type Result = std::ops::ControlFlow<()>;

fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
if t == self.ty {
self.holds = true;
}
t.super_visit_with(self)
}
}

let mut types_to_constrain = FxIndexSet::default();

let local_ty = self.body.local_decls[place.local].ty;
let typeck_results = tcx.typeck(self.mir_def_id());
let clone = tcx.require_lang_item(LangItem::Clone, Some(body.span));
for expr in expr_finder.clones {
if let hir::ExprKind::MethodCall(_, rcvr, _, span) = expr.kind
&& let Some(rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id)
&& let Some(ty) = typeck_results.node_type_opt(expr.hir_id)
&& rcvr_ty == ty
&& let ty::Ref(_, inner, _) = rcvr_ty.kind()
&& let inner = inner.peel_refs()
&& let mut v = (Holds { ty: inner, holds: false })
&& let _ = v.visit_ty(local_ty)
&& v.holds
&& let None = self.infcx.type_implements_trait_shallow(clone, inner, self.param_env)
{
err.span_label(
span,
format!(
"this call doesn't do anything, the result is still `{rcvr_ty}` \
because `{inner}` doesn't implement `Clone`",
),
);
types_to_constrain.insert(inner);
}
}
for ty in types_to_constrain {
self.suggest_adding_bounds(err, ty, clone, body.span);
if let ty::Adt(..) = ty.kind() {
// The type doesn't implement Clone.
let trait_ref = ty::Binder::dummy(ty::TraitRef::new(self.infcx.tcx, clone, [ty]));
let obligation = Obligation::new(
self.infcx.tcx,
ObligationCause::dummy(),
self.param_env,
trait_ref,
);
self.infcx.err_ctxt().suggest_derive(
&obligation,
err,
trait_ref.to_predicate(self.infcx.tcx),
);
}
}
}

#[instrument(level = "debug", skip(self, err))]
fn suggest_using_local_if_applicable(
&self,
Expand Down
23 changes: 15 additions & 8 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
err.subdiagnostic(self.dcx(), CaptureReasonNote::FnOnceMoveInCall { var_span });
}
CallKind::Operator { self_arg, .. } => {
CallKind::Operator { self_arg, trait_id, .. } => {
let self_arg = self_arg.unwrap();
err.subdiagnostic(
self.dcx(),
Expand All @@ -1062,9 +1062,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
},
);
if self.fn_self_span_reported.insert(fn_span) {
let lang = self.infcx.tcx.lang_items();
err.subdiagnostic(
self.dcx(),
CaptureReasonNote::LhsMoveByOperator { span: self_arg.span },
if [lang.not_trait(), lang.deref_trait(), lang.neg_trait()]
.contains(&Some(trait_id))
{
CaptureReasonNote::UnOpMoveByOperator { span: self_arg.span }
} else {
CaptureReasonNote::LhsMoveByOperator { span: self_arg.span }
},
);
}
}
Expand Down Expand Up @@ -1226,20 +1233,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
{
let msg = match &errors[..] {
[] => "you can `clone` the value and consume it, but this \
might not be your desired behavior"
might not be your desired behavior"
.to_string(),
[error] => {
format!(
"you could `clone` the value and consume it, if \
the `{}` trait bound could be satisfied",
"you could `clone` the value and consume it, if the \
`{}` trait bound could be satisfied",
error.obligation.predicate,
)
}
[errors @ .., last] => {
format!(
"you could `clone` the value and consume it, if \
the following trait bounds could be satisfied: {} \
and `{}`",
"you could `clone` the value and consume it, if the \
following trait bounds could be satisfied: \
{} and `{}`",
errors
.iter()
.map(|e| format!("`{}`", e.obligation.predicate))
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_borrowck/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,11 @@ pub(crate) enum CaptureReasonNote {
#[primary_span]
var_span: Span,
},
#[note(borrowck_calling_operator_moves)]
UnOpMoveByOperator {
#[primary_span]
span: Span,
},
#[note(borrowck_calling_operator_moves_lhs)]
LhsMoveByOperator {
#[primary_span]
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,13 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
"`may_dangle` has unstable semantics and may be removed in the future",
),

rustc_attr!(
rustc_never_type_mode, Normal, template!(NameValueStr: "fallback_to_unit|fallback_to_niko|fallback_to_never|no_fallback"), ErrorFollowing,
@only_local: true,
"`rustc_never_type_fallback` is used to experiment with never type fallback and work on \
never type stabilization, and will never be stable"
),

// ==========================================================================
// Internal attributes: Runtime related:
// ==========================================================================
Expand Down
Loading

0 comments on commit c67326b

Please sign in to comment.