mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Refactor FulfillmentError
to track less data
Move the information about pointing at the call argument expression in an unmet obligation span from the `FulfillmentError` to a new `ObligationCauseCode`.
This commit is contained in:
parent
284a8a9ce7
commit
8a3f712518
@ -1998,7 +1998,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
&obligation,
|
&obligation,
|
||||||
&traits::SelectionError::Unimplemented,
|
&traits::SelectionError::Unimplemented,
|
||||||
false,
|
false,
|
||||||
false,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||||||
SubregionOrigin::Subtype(box TypeTrace { ref cause, .. }) => cause,
|
SubregionOrigin::Subtype(box TypeTrace { ref cause, .. }) => cause,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let (parent, impl_def_id) = match &cause.code {
|
// If we added a "points at argument expression" obligation, we remove it here, we care
|
||||||
|
// about the original obligation only.
|
||||||
|
let code = match &cause.code {
|
||||||
|
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => &*parent_code,
|
||||||
|
_ => &cause.code,
|
||||||
|
};
|
||||||
|
let (parent, impl_def_id) = match code {
|
||||||
ObligationCauseCode::MatchImpl(parent, impl_def_id) => (parent, impl_def_id),
|
ObligationCauseCode::MatchImpl(parent, impl_def_id) => (parent, impl_def_id),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
@ -66,10 +66,6 @@ pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>;
|
|||||||
pub struct FulfillmentError<'tcx> {
|
pub struct FulfillmentError<'tcx> {
|
||||||
pub obligation: PredicateObligation<'tcx>,
|
pub obligation: PredicateObligation<'tcx>,
|
||||||
pub code: FulfillmentErrorCode<'tcx>,
|
pub code: FulfillmentErrorCode<'tcx>,
|
||||||
/// Diagnostics only: we opportunistically change the `code.span` when we encounter an
|
|
||||||
/// obligation error caused by a call argument. When this is the case, we also signal that in
|
|
||||||
/// this field to ensure accuracy of suggestions.
|
|
||||||
pub points_at_arg_span: bool,
|
|
||||||
/// Diagnostics only: the 'root' obligation which resulted in
|
/// Diagnostics only: the 'root' obligation which resulted in
|
||||||
/// the failure to process `obligation`. This is the obligation
|
/// the failure to process `obligation`. This is the obligation
|
||||||
/// that was initially passed to `register_predicate_obligation`
|
/// that was initially passed to `register_predicate_obligation`
|
||||||
@ -128,7 +124,7 @@ impl<'tcx> FulfillmentError<'tcx> {
|
|||||||
code: FulfillmentErrorCode<'tcx>,
|
code: FulfillmentErrorCode<'tcx>,
|
||||||
root_obligation: PredicateObligation<'tcx>,
|
root_obligation: PredicateObligation<'tcx>,
|
||||||
) -> FulfillmentError<'tcx> {
|
) -> FulfillmentError<'tcx> {
|
||||||
FulfillmentError { obligation, code, points_at_arg_span: false, root_obligation }
|
FulfillmentError { obligation, code, root_obligation }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,6 +253,15 @@ pub enum ObligationCauseCode<'tcx> {
|
|||||||
|
|
||||||
DerivedObligation(DerivedObligationCause<'tcx>),
|
DerivedObligation(DerivedObligationCause<'tcx>),
|
||||||
|
|
||||||
|
FunctionArgumentObligation {
|
||||||
|
/// The node of the relevant argument in the function call.
|
||||||
|
arg_hir_id: hir::HirId,
|
||||||
|
/// The node of the function call.
|
||||||
|
call_hir_id: hir::HirId,
|
||||||
|
/// The obligation introduced by this argument.
|
||||||
|
parent_code: Lrc<ObligationCauseCode<'tcx>>,
|
||||||
|
},
|
||||||
|
|
||||||
/// Error derived when matching traits/impls; see ObligationCause for more details
|
/// Error derived when matching traits/impls; see ObligationCause for more details
|
||||||
CompareImplConstObligation,
|
CompareImplConstObligation,
|
||||||
|
|
||||||
@ -368,11 +377,12 @@ impl ObligationCauseCode<'_> {
|
|||||||
// Return the base obligation, ignoring derived obligations.
|
// Return the base obligation, ignoring derived obligations.
|
||||||
pub fn peel_derives(&self) -> &Self {
|
pub fn peel_derives(&self) -> &Self {
|
||||||
let mut base_cause = self;
|
let mut base_cause = self;
|
||||||
while let BuiltinDerivedObligation(cause)
|
while let BuiltinDerivedObligation(DerivedObligationCause { parent_code, .. })
|
||||||
| ImplDerivedObligation(cause)
|
| ImplDerivedObligation(DerivedObligationCause { parent_code, .. })
|
||||||
| DerivedObligation(cause) = base_cause
|
| DerivedObligation(DerivedObligationCause { parent_code, .. })
|
||||||
|
| FunctionArgumentObligation { parent_code, .. } = base_cause
|
||||||
{
|
{
|
||||||
base_cause = &cause.parent_code;
|
base_cause = &parent_code;
|
||||||
}
|
}
|
||||||
base_cause
|
base_cause
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,6 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||||||
.map(|obligation| FulfillmentError {
|
.map(|obligation| FulfillmentError {
|
||||||
obligation: obligation.clone(),
|
obligation: obligation.clone(),
|
||||||
code: FulfillmentErrorCode::CodeAmbiguity,
|
code: FulfillmentErrorCode::CodeAmbiguity,
|
||||||
points_at_arg_span: false,
|
|
||||||
// FIXME - does Chalk have a notation of 'root obligation'?
|
// FIXME - does Chalk have a notation of 'root obligation'?
|
||||||
// This is just for diagnostics, so it's okay if this is wrong
|
// This is just for diagnostics, so it's okay if this is wrong
|
||||||
root_obligation: obligation.clone(),
|
root_obligation: obligation.clone(),
|
||||||
@ -112,7 +111,6 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||||||
code: FulfillmentErrorCode::CodeSelectionError(
|
code: FulfillmentErrorCode::CodeSelectionError(
|
||||||
SelectionError::Unimplemented,
|
SelectionError::Unimplemented,
|
||||||
),
|
),
|
||||||
points_at_arg_span: false,
|
|
||||||
// FIXME - does Chalk have a notation of 'root obligation'?
|
// FIXME - does Chalk have a notation of 'root obligation'?
|
||||||
// This is just for diagnostics, so it's okay if this is wrong
|
// This is just for diagnostics, so it's okay if this is wrong
|
||||||
root_obligation: obligation,
|
root_obligation: obligation,
|
||||||
@ -129,7 +127,6 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||||||
code: FulfillmentErrorCode::CodeSelectionError(
|
code: FulfillmentErrorCode::CodeSelectionError(
|
||||||
SelectionError::Unimplemented,
|
SelectionError::Unimplemented,
|
||||||
),
|
),
|
||||||
points_at_arg_span: false,
|
|
||||||
// FIXME - does Chalk have a notation of 'root obligation'?
|
// FIXME - does Chalk have a notation of 'root obligation'?
|
||||||
// This is just for diagnostics, so it's okay if this is wrong
|
// This is just for diagnostics, so it's okay if this is wrong
|
||||||
root_obligation: obligation,
|
root_obligation: obligation,
|
||||||
|
@ -66,7 +66,6 @@ pub trait InferCtxtExt<'tcx> {
|
|||||||
root_obligation: &PredicateObligation<'tcx>,
|
root_obligation: &PredicateObligation<'tcx>,
|
||||||
error: &SelectionError<'tcx>,
|
error: &SelectionError<'tcx>,
|
||||||
fallback_has_occurred: bool,
|
fallback_has_occurred: bool,
|
||||||
points_at_arg: bool,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Given some node representing a fn-like thing in the HIR map,
|
/// Given some node representing a fn-like thing in the HIR map,
|
||||||
@ -237,7 +236,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
root_obligation: &PredicateObligation<'tcx>,
|
root_obligation: &PredicateObligation<'tcx>,
|
||||||
error: &SelectionError<'tcx>,
|
error: &SelectionError<'tcx>,
|
||||||
fallback_has_occurred: bool,
|
fallback_has_occurred: bool,
|
||||||
points_at_arg: bool,
|
|
||||||
) {
|
) {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let mut span = obligation.cause.span;
|
let mut span = obligation.cause.span;
|
||||||
@ -387,7 +385,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
&obligation,
|
&obligation,
|
||||||
&mut err,
|
&mut err,
|
||||||
&trait_ref,
|
&trait_ref,
|
||||||
points_at_arg,
|
|
||||||
have_alt_message,
|
have_alt_message,
|
||||||
) {
|
) {
|
||||||
self.note_obligation_cause(&mut err, &obligation);
|
self.note_obligation_cause(&mut err, &obligation);
|
||||||
@ -430,8 +427,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
err.span_label(enclosing_scope_span, s.as_str());
|
err.span_label(enclosing_scope_span, s.as_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.suggest_dereferences(&obligation, &mut err, trait_ref, points_at_arg);
|
self.suggest_dereferences(&obligation, &mut err, trait_ref);
|
||||||
self.suggest_fn_call(&obligation, &mut err, trait_ref, points_at_arg);
|
self.suggest_fn_call(&obligation, &mut err, trait_ref);
|
||||||
self.suggest_remove_reference(&obligation, &mut err, trait_ref);
|
self.suggest_remove_reference(&obligation, &mut err, trait_ref);
|
||||||
self.suggest_semicolon_removal(&obligation, &mut err, span, trait_ref);
|
self.suggest_semicolon_removal(&obligation, &mut err, span, trait_ref);
|
||||||
self.note_version_mismatch(&mut err, &trait_ref);
|
self.note_version_mismatch(&mut err, &trait_ref);
|
||||||
@ -500,12 +497,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
// Changing mutability doesn't make a difference to whether we have
|
// Changing mutability doesn't make a difference to whether we have
|
||||||
// an `Unsize` impl (Fixes ICE in #71036)
|
// an `Unsize` impl (Fixes ICE in #71036)
|
||||||
if !is_unsize {
|
if !is_unsize {
|
||||||
self.suggest_change_mut(
|
self.suggest_change_mut(&obligation, &mut err, trait_ref);
|
||||||
&obligation,
|
|
||||||
&mut err,
|
|
||||||
trait_ref,
|
|
||||||
points_at_arg,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this error is due to `!: Trait` not implemented but `(): Trait` is
|
// If this error is due to `!: Trait` not implemented but `(): Trait` is
|
||||||
@ -1214,7 +1206,6 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
&error.root_obligation,
|
&error.root_obligation,
|
||||||
selection_error,
|
selection_error,
|
||||||
fallback_has_occurred,
|
fallback_has_occurred,
|
||||||
error.points_at_arg_span,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
FulfillmentErrorCode::CodeProjectionError(ref e) => {
|
FulfillmentErrorCode::CodeProjectionError(ref e) => {
|
||||||
|
@ -54,7 +54,6 @@ pub trait InferCtxtExt<'tcx> {
|
|||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
err: &mut DiagnosticBuilder<'tcx>,
|
err: &mut DiagnosticBuilder<'tcx>,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
points_at_arg: bool,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
fn get_closure_name(
|
fn get_closure_name(
|
||||||
@ -69,7 +68,6 @@ pub trait InferCtxtExt<'tcx> {
|
|||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
err: &mut DiagnosticBuilder<'_>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||||
points_at_arg: bool,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
fn suggest_add_reference_to_arg(
|
fn suggest_add_reference_to_arg(
|
||||||
@ -77,7 +75,6 @@ pub trait InferCtxtExt<'tcx> {
|
|||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
err: &mut DiagnosticBuilder<'_>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||||
points_at_arg: bool,
|
|
||||||
has_custom_message: bool,
|
has_custom_message: bool,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
|
||||||
@ -93,7 +90,6 @@ pub trait InferCtxtExt<'tcx> {
|
|||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
err: &mut DiagnosticBuilder<'_>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||||
points_at_arg: bool,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
fn suggest_semicolon_removal(
|
fn suggest_semicolon_removal(
|
||||||
@ -490,16 +486,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
err: &mut DiagnosticBuilder<'tcx>,
|
err: &mut DiagnosticBuilder<'tcx>,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
points_at_arg: bool,
|
|
||||||
) {
|
) {
|
||||||
// It only make sense when suggesting dereferences for arguments
|
// It only make sense when suggesting dereferences for arguments
|
||||||
if !points_at_arg {
|
let code = if let ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } =
|
||||||
|
&obligation.cause.code
|
||||||
|
{
|
||||||
|
std::rc::Rc::clone(parent_code)
|
||||||
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
};
|
||||||
let param_env = obligation.param_env;
|
let param_env = obligation.param_env;
|
||||||
let body_id = obligation.cause.body_id;
|
let body_id = obligation.cause.body_id;
|
||||||
let span = obligation.cause.span;
|
let span = obligation.cause.span;
|
||||||
let real_trait_ref = match &obligation.cause.code {
|
let real_trait_ref = match &*code {
|
||||||
ObligationCauseCode::ImplDerivedObligation(cause)
|
ObligationCauseCode::ImplDerivedObligation(cause)
|
||||||
| ObligationCauseCode::DerivedObligation(cause)
|
| ObligationCauseCode::DerivedObligation(cause)
|
||||||
| ObligationCauseCode::BuiltinDerivedObligation(cause) => cause.parent_trait_ref,
|
| ObligationCauseCode::BuiltinDerivedObligation(cause) => cause.parent_trait_ref,
|
||||||
@ -584,7 +583,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
err: &mut DiagnosticBuilder<'_>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||||
points_at_arg: bool,
|
|
||||||
) {
|
) {
|
||||||
let self_ty = match trait_ref.self_ty().no_bound_vars() {
|
let self_ty = match trait_ref.self_ty().no_bound_vars() {
|
||||||
None => return,
|
None => return,
|
||||||
@ -656,11 +654,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
if points_at_arg {
|
if matches!(obligation.cause.code, ObligationCauseCode::FunctionArgumentObligation { .. }) {
|
||||||
// When the obligation error has been ensured to have been caused by
|
// When the obligation error has been ensured to have been caused by
|
||||||
// an argument, the `obligation.cause.span` points at the expression
|
// an argument, the `obligation.cause.span` points at the expression
|
||||||
// of the argument, so we can provide a suggestion. This is signaled
|
// of the argument, so we can provide a suggestion. Otherwise, we give
|
||||||
// by `points_at_arg`. Otherwise, we give a more general note.
|
// a more general note.
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
obligation.cause.span.shrink_to_hi(),
|
obligation.cause.span.shrink_to_hi(),
|
||||||
&msg,
|
&msg,
|
||||||
@ -677,7 +675,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
err: &mut DiagnosticBuilder<'_>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||||
points_at_arg: bool,
|
|
||||||
has_custom_message: bool,
|
has_custom_message: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let span = obligation.cause.span;
|
let span = obligation.cause.span;
|
||||||
@ -686,9 +683,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter))
|
ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter))
|
||||||
);
|
);
|
||||||
|
|
||||||
if !points_at_arg && !points_at_for_iter {
|
let code =
|
||||||
return false;
|
if let (ObligationCauseCode::FunctionArgumentObligation { parent_code, .. }, false) =
|
||||||
}
|
(&obligation.cause.code, points_at_for_iter)
|
||||||
|
{
|
||||||
|
std::rc::Rc::clone(parent_code)
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
// List of traits for which it would be nonsensical to suggest borrowing.
|
// List of traits for which it would be nonsensical to suggest borrowing.
|
||||||
// For instance, immutable references are always Copy, so suggesting to
|
// For instance, immutable references are always Copy, so suggesting to
|
||||||
@ -787,7 +789,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
if let ObligationCauseCode::ImplDerivedObligation(obligation) = &obligation.cause.code {
|
if let ObligationCauseCode::ImplDerivedObligation(obligation) = &*code {
|
||||||
let expected_trait_ref = obligation.parent_trait_ref.skip_binder();
|
let expected_trait_ref = obligation.parent_trait_ref.skip_binder();
|
||||||
let new_imm_trait_ref =
|
let new_imm_trait_ref =
|
||||||
ty::TraitRef::new(obligation.parent_trait_ref.def_id(), imm_substs);
|
ty::TraitRef::new(obligation.parent_trait_ref.def_id(), imm_substs);
|
||||||
@ -799,7 +801,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
return try_borrowing(new_mut_trait_ref, expected_trait_ref, true, &[]);
|
return try_borrowing(new_mut_trait_ref, expected_trait_ref, true, &[]);
|
||||||
}
|
}
|
||||||
} else if let ObligationCauseCode::BindingObligation(_, _)
|
} else if let ObligationCauseCode::BindingObligation(_, _)
|
||||||
| ObligationCauseCode::ItemObligation(_) = &obligation.cause.code
|
| ObligationCauseCode::ItemObligation(_) = &*code
|
||||||
{
|
{
|
||||||
if try_borrowing(
|
if try_borrowing(
|
||||||
ty::TraitRef::new(trait_ref.def_id, imm_substs),
|
ty::TraitRef::new(trait_ref.def_id, imm_substs),
|
||||||
@ -891,8 +893,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
err: &mut DiagnosticBuilder<'_>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||||
points_at_arg: bool,
|
|
||||||
) {
|
) {
|
||||||
|
let points_at_arg = matches!(
|
||||||
|
obligation.cause.code,
|
||||||
|
ObligationCauseCode::FunctionArgumentObligation { .. },
|
||||||
|
);
|
||||||
|
|
||||||
let span = obligation.cause.span;
|
let span = obligation.cause.span;
|
||||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||||
let refs_number =
|
let refs_number =
|
||||||
@ -2289,6 +2295,21 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
ObligationCauseCode::FunctionArgumentObligation {
|
||||||
|
arg_hir_id: _,
|
||||||
|
call_hir_id: _,
|
||||||
|
ref parent_code,
|
||||||
|
} => {
|
||||||
|
ensure_sufficient_stack(|| {
|
||||||
|
self.note_obligation_cause_code(
|
||||||
|
err,
|
||||||
|
predicate,
|
||||||
|
&parent_code,
|
||||||
|
obligated_types,
|
||||||
|
seen_requirements,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
ObligationCauseCode::CompareImplMethodObligation {
|
ObligationCauseCode::CompareImplMethodObligation {
|
||||||
item_name,
|
item_name,
|
||||||
trait_item_def_id,
|
trait_item_def_id,
|
||||||
|
@ -707,13 +707,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
|
|
||||||
// Object safety violations or miscellaneous.
|
// Object safety violations or miscellaneous.
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
self.report_selection_error(
|
self.report_selection_error(obligation.clone(), &obligation, &err, false);
|
||||||
obligation.clone(),
|
|
||||||
&obligation,
|
|
||||||
&err,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
// Treat this like an obligation and follow through
|
// Treat this like an obligation and follow through
|
||||||
// with the unsizing - the lack of a coercion should
|
// with the unsizing - the lack of a coercion should
|
||||||
// be silent, as it causes a type mismatch later.
|
// be silent, as it causes a type mismatch later.
|
||||||
|
@ -9,6 +9,7 @@ use crate::check::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
|
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||||
@ -324,6 +325,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
self.point_at_arg_instead_of_call_if_possible(
|
self.point_at_arg_instead_of_call_if_possible(
|
||||||
errors,
|
errors,
|
||||||
&final_arg_types[..],
|
&final_arg_types[..],
|
||||||
|
expr,
|
||||||
sp,
|
sp,
|
||||||
&args,
|
&args,
|
||||||
);
|
);
|
||||||
@ -391,7 +393,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
) {
|
) {
|
||||||
for error in errors {
|
for error in errors {
|
||||||
error.obligation.cause.make_mut().span = arg.span;
|
error.obligation.cause.make_mut().span = arg.span;
|
||||||
error.points_at_arg_span = true;
|
let code = error.obligation.cause.code.clone();
|
||||||
|
error.obligation.cause.make_mut().code =
|
||||||
|
ObligationCauseCode::FunctionArgumentObligation {
|
||||||
|
arg_hir_id: arg.hir_id,
|
||||||
|
call_hir_id: expr.hir_id,
|
||||||
|
parent_code: Lrc::new(code),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -937,6 +945,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
|
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
|
||||||
final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
|
final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
|
||||||
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
call_sp: Span,
|
call_sp: Span,
|
||||||
args: &'tcx [hir::Expr<'tcx>],
|
args: &'tcx [hir::Expr<'tcx>],
|
||||||
) {
|
) {
|
||||||
@ -986,7 +995,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// We make sure that only *one* argument matches the obligation failure
|
// We make sure that only *one* argument matches the obligation failure
|
||||||
// and we assign the obligation's span to its expression's.
|
// and we assign the obligation's span to its expression's.
|
||||||
error.obligation.cause.make_mut().span = args[ref_in].span;
|
error.obligation.cause.make_mut().span = args[ref_in].span;
|
||||||
error.points_at_arg_span = true;
|
let code = error.obligation.cause.code.clone();
|
||||||
|
error.obligation.cause.make_mut().code =
|
||||||
|
ObligationCauseCode::FunctionArgumentObligation {
|
||||||
|
arg_hir_id: args[ref_in].hir_id,
|
||||||
|
call_hir_id: expr.hir_id,
|
||||||
|
parent_code: Lrc::new(code),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ error[E0277]: `dummy1c::TestType` cannot be sent between threads safely
|
|||||||
LL | is_send((8, TestType));
|
LL | is_send((8, TestType));
|
||||||
| ^^^^^^^^^^^^^ `dummy1c::TestType` cannot be sent between threads safely
|
| ^^^^^^^^^^^^^ `dummy1c::TestType` cannot be sent between threads safely
|
||||||
|
|
|
|
||||||
= help: within `({integer}, dummy1c::TestType)`, the trait `Send` is not implemented for `dummy1c::TestType`
|
= help: the trait `Send` is not implemented for `dummy1c::TestType`
|
||||||
= note: required because it appears within the type `({integer}, dummy1c::TestType)`
|
= note: required because it appears within the type `({integer}, dummy1c::TestType)`
|
||||||
note: required by a bound in `is_send`
|
note: required by a bound in `is_send`
|
||||||
--> $DIR/negated-auto-traits-error.rs:16:15
|
--> $DIR/negated-auto-traits-error.rs:16:15
|
||||||
@ -75,7 +75,7 @@ error[E0277]: `dummy3::TestType` cannot be sent between threads safely
|
|||||||
LL | is_send(Box::new(Outer2(TestType)));
|
LL | is_send(Box::new(Outer2(TestType)));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `dummy3::TestType` cannot be sent between threads safely
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `dummy3::TestType` cannot be sent between threads safely
|
||||||
|
|
|
|
||||||
= help: within `Outer2<dummy3::TestType>`, the trait `Send` is not implemented for `dummy3::TestType`
|
= help: the trait `Send` is not implemented for `dummy3::TestType`
|
||||||
note: required because it appears within the type `Outer2<dummy3::TestType>`
|
note: required because it appears within the type `Outer2<dummy3::TestType>`
|
||||||
--> $DIR/negated-auto-traits-error.rs:12:8
|
--> $DIR/negated-auto-traits-error.rs:12:8
|
||||||
|
|
|
|
||||||
|
@ -14,7 +14,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation
|
|||||||
LL | udrop::<A<[u8]>>(A { 0: *foo() });
|
LL | udrop::<A<[u8]>>(A { 0: *foo() });
|
||||||
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: within `A<[u8]>`, the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
note: required because it appears within the type `A<[u8]>`
|
note: required because it appears within the type `A<[u8]>`
|
||||||
--> $DIR/unsized-exprs.rs:3:8
|
--> $DIR/unsized-exprs.rs:3:8
|
||||||
|
|
|
|
||||||
|
Loading…
Reference in New Issue
Block a user