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

Remove redundant code from copy-suggestions #94698

Merged
merged 1 commit into from
Mar 18, 2022
Merged
Changes from all commits
Commits
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
135 changes: 55 additions & 80 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ use rustc_middle::mir::{
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
};
use rustc_middle::ty::{
self, suggest_constraining_type_param, suggest_constraining_type_params, PredicateKind, Ty,
};
use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty};
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
use rustc_span::symbol::sym;
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
Expand Down Expand Up @@ -410,86 +408,63 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Some(ref name) => format!("`{}`", name),
None => "value".to_owned(),
};
if let ty::Param(param_ty) = ty.kind() {
let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id());
let param = generics.type_param(&param_ty, tcx);
if let Some(generics) = tcx
.typeck_root_def_id(self.mir_def_id().to_def_id())
.as_local()
.and_then(|def_id| tcx.hir().get_generics(def_id))
{
suggest_constraining_type_param(
tcx,
generics,
&mut err,
param.name.as_str(),
"Copy",
None,

// Try to find predicates on *generic params* that would allow copying `ty`
let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id());
if let Some(hir_generics) = tcx
.typeck_root_def_id(self.mir_def_id().to_def_id())
.as_local()
.and_then(|def_id| tcx.hir().get_generics(def_id))
{
let predicates: Result<Vec<_>, _> = tcx.infer_ctxt().enter(|infcx| {
let mut fulfill_cx =
<dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx);

let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
let cause = ObligationCause::new(
span,
self.mir_hir_id(),
rustc_infer::traits::ObligationCauseCode::MiscObligation,
);
}
} else {
// Try to find predicates on *generic params* that would allow copying `ty`

let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id());
if let Some(hir_generics) = tcx
.typeck_root_def_id(self.mir_def_id().to_def_id())
.as_local()
.and_then(|def_id| tcx.hir().get_generics(def_id))
{
let predicates: Result<Vec<_>, _> = tcx.infer_ctxt().enter(|infcx| {
let mut fulfill_cx =
<dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx);

let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
let cause = ObligationCause::new(
span,
self.mir_hir_id(),
rustc_infer::traits::ObligationCauseCode::MiscObligation,
);
fulfill_cx.register_bound(
&infcx,
self.param_env,
// Erase any region vids from the type, which may not be resolved
infcx.tcx.erase_regions(ty),
copy_did,
cause,
);
// Select all, including ambiguous predicates
let errors = fulfill_cx.select_all_or_error(&infcx);

// Only emit suggestion if all required predicates are on generic
errors
.into_iter()
.map(|err| match err.obligation.predicate.kind().skip_binder() {
PredicateKind::Trait(predicate) => {
match predicate.self_ty().kind() {
ty::Param(param_ty) => Ok((
generics.type_param(param_ty, tcx),
predicate
.trait_ref
.print_only_trait_path()
.to_string(),
)),
_ => Err(()),
}
fulfill_cx.register_bound(
&infcx,
self.param_env,
// Erase any region vids from the type, which may not be resolved
infcx.tcx.erase_regions(ty),
copy_did,
cause,
);
// Select all, including ambiguous predicates
let errors = fulfill_cx.select_all_or_error(&infcx);

// Only emit suggestion if all required predicates are on generic
errors
.into_iter()
.map(|err| match err.obligation.predicate.kind().skip_binder() {
PredicateKind::Trait(predicate) => {
match predicate.self_ty().kind() {
ty::Param(param_ty) => Ok((
generics.type_param(param_ty, tcx),
predicate.trait_ref.print_only_trait_path().to_string(),
)),
_ => Err(()),
}
_ => Err(()),
})
.collect()
});
}
_ => Err(()),
})
.collect()
});

if let Ok(predicates) = predicates {
suggest_constraining_type_params(
tcx,
hir_generics,
&mut err,
predicates.iter().map(|(param, constraint)| {
(param.name.as_str(), &**constraint, None)
}),
);
}
if let Ok(predicates) = predicates {
suggest_constraining_type_params(
tcx,
hir_generics,
&mut err,
predicates.iter().map(|(param, constraint)| {
(param.name.as_str(), &**constraint, None)
}),
);
}
}

Expand Down