Remove redundant code from copy-suggestions

This commit is contained in:
Maybe Waffle 2022-03-07 16:38:58 +04:00
parent ecb867ec3c
commit 74d0866c62

View File

@ -12,9 +12,7 @@
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
}; };
use rustc_middle::ty::{ use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty};
self, suggest_constraining_type_param, suggest_constraining_type_params, PredicateKind, Ty,
};
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP}; use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
@ -410,86 +408,63 @@ pub(crate) fn report_use_of_moved_or_uninitialized(
Some(ref name) => format!("`{}`", name), Some(ref name) => format!("`{}`", name),
None => "value".to_owned(), None => "value".to_owned(),
}; };
if let ty::Param(param_ty) = ty.kind() {
let tcx = self.infcx.tcx; // Try to find predicates on *generic params* that would allow copying `ty`
let generics = tcx.generics_of(self.mir_def_id()); let tcx = self.infcx.tcx;
let param = generics.type_param(&param_ty, tcx); let generics = tcx.generics_of(self.mir_def_id());
if let Some(generics) = tcx if let Some(hir_generics) = tcx
.typeck_root_def_id(self.mir_def_id().to_def_id()) .typeck_root_def_id(self.mir_def_id().to_def_id())
.as_local() .as_local()
.and_then(|def_id| tcx.hir().get_generics(def_id)) .and_then(|def_id| tcx.hir().get_generics(def_id))
{ {
suggest_constraining_type_param( let predicates: Result<Vec<_>, _> = tcx.infer_ctxt().enter(|infcx| {
tcx, let mut fulfill_cx =
generics, <dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx);
&mut err,
param.name.as_str(), let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
"Copy", let cause = ObligationCause::new(
None, span,
self.mir_hir_id(),
rustc_infer::traits::ObligationCauseCode::MiscObligation,
); );
} fulfill_cx.register_bound(
} else { &infcx,
// Try to find predicates on *generic params* that would allow copying `ty` 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);
let tcx = self.infcx.tcx; // Only emit suggestion if all required predicates are on generic
let generics = tcx.generics_of(self.mir_def_id()); errors
if let Some(hir_generics) = tcx .into_iter()
.typeck_root_def_id(self.mir_def_id().to_def_id()) .map(|err| match err.obligation.predicate.kind().skip_binder() {
.as_local() PredicateKind::Trait(predicate) => {
.and_then(|def_id| tcx.hir().get_generics(def_id)) match predicate.self_ty().kind() {
{ ty::Param(param_ty) => Ok((
let predicates: Result<Vec<_>, _> = tcx.infer_ctxt().enter(|infcx| { generics.type_param(param_ty, tcx),
let mut fulfill_cx = predicate.trait_ref.print_only_trait_path().to_string(),
<dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx); )),
_ => Err(()),
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(()),
}
} }
_ => Err(()), }
}) _ => Err(()),
.collect() })
}); .collect()
});
if let Ok(predicates) = predicates { if let Ok(predicates) = predicates {
suggest_constraining_type_params( suggest_constraining_type_params(
tcx, tcx,
hir_generics, hir_generics,
&mut err, &mut err,
predicates.iter().map(|(param, constraint)| { predicates.iter().map(|(param, constraint)| {
(param.name.as_str(), &**constraint, None) (param.name.as_str(), &**constraint, None)
}), }),
); );
}
} }
} }