Assert that Instance::try_resolve is only used on body-like things
This commit is contained in:
parent
e7ad3ae331
commit
9bf9f5db9b
10 changed files with 118 additions and 99 deletions
|
@ -20,7 +20,7 @@ use rustc_middle::bug;
|
||||||
use rustc_middle::hir::nested_filter::OnlyBodies;
|
use rustc_middle::hir::nested_filter::OnlyBodies;
|
||||||
use rustc_middle::mir::tcx::PlaceTy;
|
use rustc_middle::mir::tcx::PlaceTy;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory,
|
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
|
||||||
FakeBorrowKind, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind,
|
FakeBorrowKind, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind,
|
||||||
Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
|
Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
|
||||||
TerminatorKind, VarBindingForm, VarDebugInfoContents,
|
TerminatorKind, VarBindingForm, VarDebugInfoContents,
|
||||||
|
@ -30,13 +30,13 @@ use rustc_middle::ty::{
|
||||||
self, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast,
|
self, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast,
|
||||||
suggest_constraining_type_params,
|
suggest_constraining_type_params,
|
||||||
};
|
};
|
||||||
use rustc_middle::util::CallKind;
|
|
||||||
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
|
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
|
||||||
use rustc_span::def_id::{DefId, LocalDefId};
|
use rustc_span::def_id::{DefId, LocalDefId};
|
||||||
use rustc_span::hygiene::DesugaringKind;
|
use rustc_span::hygiene::DesugaringKind;
|
||||||
use rustc_span::{BytePos, Ident, Span, Symbol, kw, sym};
|
use rustc_span::{BytePos, Ident, Span, Symbol, kw, sym};
|
||||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||||
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
|
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
|
||||||
|
use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
|
use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
|
||||||
|
@ -46,7 +46,7 @@ use super::explain_borrow::{BorrowExplanation, LaterUseKind};
|
||||||
use super::{DescribePlaceOpt, RegionName, RegionNameSource, UseSpans};
|
use super::{DescribePlaceOpt, RegionName, RegionNameSource, UseSpans};
|
||||||
use crate::borrow_set::{BorrowData, TwoPhaseActivation};
|
use crate::borrow_set::{BorrowData, TwoPhaseActivation};
|
||||||
use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
|
use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
|
||||||
use crate::diagnostics::{CapturedMessageOpt, Instance, find_all_local_uses};
|
use crate::diagnostics::{CapturedMessageOpt, call_kind, find_all_local_uses};
|
||||||
use crate::prefixes::IsPrefixOf;
|
use crate::prefixes::IsPrefixOf;
|
||||||
use crate::{InitializationRequiringAction, MirBorrowckCtxt, WriteKind, borrowck_errors};
|
use crate::{InitializationRequiringAction, MirBorrowckCtxt, WriteKind, borrowck_errors};
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let UseSpans::FnSelfUse {
|
if let UseSpans::FnSelfUse {
|
||||||
kind: CallKind::DerefCoercion { deref_target, deref_target_ty, .. },
|
kind: CallKind::DerefCoercion { deref_target_span, deref_target_ty, .. },
|
||||||
..
|
..
|
||||||
} = use_spans
|
} = use_spans
|
||||||
{
|
{
|
||||||
|
@ -315,8 +315,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
));
|
));
|
||||||
|
|
||||||
// Check first whether the source is accessible (issue #87060)
|
// Check first whether the source is accessible (issue #87060)
|
||||||
if self.infcx.tcx.sess.source_map().is_span_accessible(deref_target) {
|
if let Some(deref_target_span) = deref_target_span
|
||||||
err.span_note(deref_target, "deref defined here");
|
&& self.infcx.tcx.sess.source_map().is_span_accessible(deref_target_span)
|
||||||
|
{
|
||||||
|
err.span_note(deref_target_span, "deref defined here");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3765,38 +3767,27 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
|
|
||||||
fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diag<'_>) {
|
fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diag<'_>) {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
if let (
|
if let Some(Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. }) =
|
||||||
Some(Terminator {
|
&self.body[loan.reserve_location.block].terminator
|
||||||
kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
|
&& let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
|
||||||
..
|
|
||||||
}),
|
|
||||||
Some((method_did, method_args)),
|
|
||||||
) = (
|
|
||||||
&self.body[loan.reserve_location.block].terminator,
|
|
||||||
rustc_middle::util::find_self_call(
|
|
||||||
tcx,
|
tcx,
|
||||||
self.body,
|
self.body,
|
||||||
loan.assigned_place.local,
|
loan.assigned_place.local,
|
||||||
loan.reserve_location.block,
|
loan.reserve_location.block,
|
||||||
),
|
)
|
||||||
) {
|
&& let CallKind::DerefCoercion { deref_target_span, deref_target_ty, .. } = call_kind(
|
||||||
if tcx.is_diagnostic_item(sym::deref_method, method_did) {
|
self.infcx.tcx,
|
||||||
let deref_target =
|
self.infcx.typing_env(self.infcx.param_env),
|
||||||
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
|
method_did,
|
||||||
Instance::try_resolve(
|
method_args,
|
||||||
tcx,
|
*fn_span,
|
||||||
self.infcx.typing_env(self.infcx.param_env),
|
call_source.from_hir_call(),
|
||||||
deref_target,
|
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
|
||||||
method_args,
|
)
|
||||||
)
|
{
|
||||||
.transpose()
|
err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
|
||||||
});
|
if let Some(deref_target_span) = deref_target_span {
|
||||||
if let Some(Ok(instance)) = deref_target {
|
err.span_note(deref_target_span, "deref defined here");
|
||||||
let deref_target_ty =
|
|
||||||
instance.ty(tcx, self.infcx.typing_env(self.infcx.param_env));
|
|
||||||
err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
|
|
||||||
err.span_note(tcx.def_span(instance.def_id()), "deref defined here");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,9 @@ use rustc_middle::mir::{
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
|
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
|
||||||
use rustc_middle::util::CallKind;
|
|
||||||
use rustc_span::{DesugaringKind, Span, kw, sym};
|
use rustc_span::{DesugaringKind, Span, kw, sym};
|
||||||
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
|
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
|
||||||
|
use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
use super::{RegionName, UseSpans, find_use};
|
use super::{RegionName, UseSpans, find_use};
|
||||||
|
|
|
@ -20,13 +20,13 @@ use rustc_middle::mir::{
|
||||||
StatementKind, Terminator, TerminatorKind,
|
StatementKind, Terminator, TerminatorKind,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::print::Print;
|
use rustc_middle::ty::print::Print;
|
||||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_middle::util::{CallDesugaringKind, call_kind};
|
|
||||||
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex};
|
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex};
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
|
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
|
||||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||||
|
use rustc_trait_selection::error_reporting::traits::call_kind::{CallDesugaringKind, call_kind};
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{
|
||||||
FulfillmentErrorCode, type_known_to_meet_bound_modulo_regions,
|
FulfillmentErrorCode, type_known_to_meet_bound_modulo_regions,
|
||||||
|
@ -63,7 +63,7 @@ pub(crate) use mutability_errors::AccessKind;
|
||||||
pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder;
|
pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder;
|
||||||
pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
|
pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
|
||||||
pub(crate) use region_name::{RegionName, RegionNameSource};
|
pub(crate) use region_name::{RegionName, RegionNameSource};
|
||||||
pub(crate) use rustc_middle::util::CallKind;
|
pub(crate) use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
|
||||||
|
|
||||||
pub(super) struct DescribePlaceOpt {
|
pub(super) struct DescribePlaceOpt {
|
||||||
including_downcast: bool,
|
including_downcast: bool,
|
||||||
|
|
|
@ -14,9 +14,11 @@ use rustc_middle::ty::{
|
||||||
self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty,
|
self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty,
|
||||||
suggest_constraining_type_param,
|
suggest_constraining_type_param,
|
||||||
};
|
};
|
||||||
use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind};
|
|
||||||
use rustc_session::parse::add_feature_diagnostics;
|
use rustc_session::parse::add_feature_diagnostics;
|
||||||
use rustc_span::{BytePos, Pos, Span, Symbol, sym};
|
use rustc_span::{BytePos, Pos, Span, Symbol, sym};
|
||||||
|
use rustc_trait_selection::error_reporting::traits::call_kind::{
|
||||||
|
CallDesugaringKind, CallKind, call_kind,
|
||||||
|
};
|
||||||
use rustc_trait_selection::traits::SelectionContext;
|
use rustc_trait_selection::traits::SelectionContext;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
|
@ -324,10 +326,12 @@ fn build_error_for_const_call<'tcx>(
|
||||||
note_trait_if_possible(&mut err, self_ty, trait_id);
|
note_trait_if_possible(&mut err, self_ty, trait_id);
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
CallKind::DerefCoercion { deref_target, deref_target_ty, self_ty } => {
|
CallKind::DerefCoercion { deref_target_span, deref_target_ty, self_ty } => {
|
||||||
// Check first whether the source is accessible (issue #87060)
|
// Check first whether the source is accessible (issue #87060)
|
||||||
let target = if tcx.sess.source_map().is_span_accessible(deref_target) {
|
let target = if let Some(deref_target_span) = deref_target_span
|
||||||
Some(deref_target)
|
&& tcx.sess.source_map().is_span_accessible(deref_target_span)
|
||||||
|
{
|
||||||
|
Some(deref_target_span)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::path::PathBuf;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::Namespace;
|
use rustc_hir::def::{CtorKind, DefKind, Namespace};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId};
|
use rustc_hir::def_id::{CrateNum, DefId};
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_index::bit_set::FiniteBitSet;
|
use rustc_index::bit_set::FiniteBitSet;
|
||||||
|
@ -498,7 +498,8 @@ impl<'tcx> Instance<'tcx> {
|
||||||
|
|
||||||
/// Resolves a `(def_id, args)` pair to an (optional) instance -- most commonly,
|
/// Resolves a `(def_id, args)` pair to an (optional) instance -- most commonly,
|
||||||
/// this is used to find the precise code that will run for a trait method invocation,
|
/// this is used to find the precise code that will run for a trait method invocation,
|
||||||
/// if known.
|
/// if known. This should only be used for functions and consts. If you want to
|
||||||
|
/// resolve an associated type, use [`TyCtxt::try_normalize_erasing_regions`].
|
||||||
///
|
///
|
||||||
/// Returns `Ok(None)` if we cannot resolve `Instance` to a specific instance.
|
/// Returns `Ok(None)` if we cannot resolve `Instance` to a specific instance.
|
||||||
/// For example, in a context like this,
|
/// For example, in a context like this,
|
||||||
|
@ -527,6 +528,23 @@ impl<'tcx> Instance<'tcx> {
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
args: GenericArgsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
|
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
|
||||||
|
assert_matches!(
|
||||||
|
tcx.def_kind(def_id),
|
||||||
|
DefKind::Fn
|
||||||
|
| DefKind::AssocFn
|
||||||
|
| DefKind::Const
|
||||||
|
| DefKind::AssocConst
|
||||||
|
| DefKind::AnonConst
|
||||||
|
| DefKind::InlineConst
|
||||||
|
| DefKind::Static { .. }
|
||||||
|
| DefKind::Ctor(_, CtorKind::Fn)
|
||||||
|
| DefKind::Closure
|
||||||
|
| DefKind::SyntheticCoroutineBody,
|
||||||
|
"`Instance::try_resolve` should only be used to resolve instances of \
|
||||||
|
functions, statics, and consts; to resolve associated types, use \
|
||||||
|
`try_normalize_erasing_regions`."
|
||||||
|
);
|
||||||
|
|
||||||
// Rust code can easily create exponentially-long types using only a
|
// Rust code can easily create exponentially-long types using only a
|
||||||
// polynomial recursion depth. Even with the default recursion
|
// polynomial recursion depth. Even with the default recursion
|
||||||
// depth, you can easily get cases that take >2^60 steps to run,
|
// depth, you can easily get cases that take >2^60 steps to run,
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
pub mod bug;
|
pub mod bug;
|
||||||
pub mod call_kind;
|
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod find_self_call;
|
pub mod find_self_call;
|
||||||
|
|
||||||
pub use call_kind::{CallDesugaringKind, CallKind, call_kind};
|
|
||||||
pub use find_self_call::find_self_call;
|
pub use find_self_call::find_self_call;
|
||||||
|
|
||||||
#[derive(Default, Copy, Clone)]
|
#[derive(Default, Copy, Clone)]
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
//! as well as errors when attempting to call a non-const function in a const
|
//! as well as errors when attempting to call a non-const function in a const
|
||||||
//! context.
|
//! context.
|
||||||
|
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{LangItem, lang_items};
|
use rustc_hir::{LangItem, lang_items};
|
||||||
|
use rustc_middle::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv};
|
||||||
use rustc_span::{DesugaringKind, Ident, Span, sym};
|
use rustc_span::{DesugaringKind, Ident, Span, sym};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv};
|
use crate::traits::specialization_graph;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
pub enum CallDesugaringKind {
|
pub enum CallDesugaringKind {
|
||||||
|
@ -55,7 +57,7 @@ pub enum CallKind<'tcx> {
|
||||||
DerefCoercion {
|
DerefCoercion {
|
||||||
/// The `Span` of the `Target` associated type
|
/// The `Span` of the `Target` associated type
|
||||||
/// in the `Deref` impl we are using.
|
/// in the `Deref` impl we are using.
|
||||||
deref_target: Span,
|
deref_target_span: Option<Span>,
|
||||||
/// The type `T::Deref` we are dereferencing to
|
/// The type `T::Deref` we are dereferencing to
|
||||||
deref_target_ty: Ty<'tcx>,
|
deref_target_ty: Ty<'tcx>,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
|
@ -89,61 +91,65 @@ pub fn call_kind<'tcx>(
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_deref = !from_hir_call && tcx.is_diagnostic_item(sym::deref_method, method_did);
|
|
||||||
|
|
||||||
// Check for a 'special' use of 'self' -
|
// Check for a 'special' use of 'self' -
|
||||||
// an FnOnce call, an operator (e.g. `<<`), or a
|
// an FnOnce call, an operator (e.g. `<<`), or a
|
||||||
// deref coercion.
|
// deref coercion.
|
||||||
let kind = if let Some(trait_id) = fn_call {
|
if let Some(trait_id) = fn_call {
|
||||||
Some(CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_args.type_at(0) })
|
return CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_args.type_at(0) };
|
||||||
} else if let Some(trait_id) = operator {
|
} else if let Some(trait_id) = operator {
|
||||||
Some(CallKind::Operator { self_arg, trait_id, self_ty: method_args.type_at(0) })
|
return CallKind::Operator { self_arg, trait_id, self_ty: method_args.type_at(0) };
|
||||||
} else if is_deref {
|
} else if !from_hir_call && tcx.is_diagnostic_item(sym::deref_method, method_did) {
|
||||||
let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
|
let deref_target_def_id =
|
||||||
Instance::try_resolve(tcx, typing_env, deref_target, method_args).transpose()
|
tcx.get_diagnostic_item(sym::deref_target).expect("deref method but no deref target");
|
||||||
});
|
let deref_target_ty = tcx.normalize_erasing_regions(
|
||||||
if let Some(Ok(instance)) = deref_target {
|
typing_env,
|
||||||
let deref_target_ty = instance.ty(tcx, typing_env);
|
Ty::new_projection(tcx, deref_target_def_id, method_args),
|
||||||
Some(CallKind::DerefCoercion {
|
);
|
||||||
deref_target: tcx.def_span(instance.def_id()),
|
let deref_target_span = if let Ok(Some(instance)) =
|
||||||
deref_target_ty,
|
Instance::try_resolve(tcx, typing_env, method_did, method_args)
|
||||||
self_ty: method_args.type_at(0),
|
&& let instance_parent_def_id = tcx.parent(instance.def_id())
|
||||||
})
|
&& matches!(tcx.def_kind(instance_parent_def_id), DefKind::Impl { .. })
|
||||||
} else {
|
&& let Ok(instance) =
|
||||||
None
|
specialization_graph::assoc_def(tcx, instance_parent_def_id, deref_target_def_id)
|
||||||
}
|
&& instance.is_final()
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
kind.unwrap_or_else(|| {
|
|
||||||
// This isn't a 'special' use of `self`
|
|
||||||
debug!(?method_did, ?fn_call_span);
|
|
||||||
let desugaring = if tcx.is_lang_item(method_did, LangItem::IntoIterIntoIter)
|
|
||||||
&& fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
|
|
||||||
{
|
{
|
||||||
Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0)))
|
Some(tcx.def_span(instance.item.def_id))
|
||||||
} else if tcx.is_lang_item(method_did, LangItem::IteratorNext)
|
|
||||||
&& fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
|
|
||||||
{
|
|
||||||
Some((CallDesugaringKind::ForLoopNext, method_args.type_at(0)))
|
|
||||||
} else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) {
|
|
||||||
if tcx.is_lang_item(method_did, LangItem::TryTraitBranch) {
|
|
||||||
Some((CallDesugaringKind::QuestionBranch, method_args.type_at(0)))
|
|
||||||
} else if tcx.is_lang_item(method_did, LangItem::TryTraitFromResidual) {
|
|
||||||
Some((CallDesugaringKind::QuestionFromResidual, method_args.type_at(0)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else if tcx.is_lang_item(method_did, LangItem::TryTraitFromOutput)
|
|
||||||
&& fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock)
|
|
||||||
{
|
|
||||||
Some((CallDesugaringKind::TryBlockFromOutput, method_args.type_at(0)))
|
|
||||||
} else if fn_call_span.is_desugaring(DesugaringKind::Await) {
|
|
||||||
Some((CallDesugaringKind::Await, method_args.type_at(0)))
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
CallKind::Normal { self_arg, desugaring, method_did, method_args }
|
return CallKind::DerefCoercion {
|
||||||
})
|
deref_target_ty,
|
||||||
|
deref_target_span,
|
||||||
|
self_ty: method_args.type_at(0),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// This isn't a 'special' use of `self`
|
||||||
|
debug!(?method_did, ?fn_call_span);
|
||||||
|
let desugaring = if tcx.is_lang_item(method_did, LangItem::IntoIterIntoIter)
|
||||||
|
&& fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
|
||||||
|
{
|
||||||
|
Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0)))
|
||||||
|
} else if tcx.is_lang_item(method_did, LangItem::IteratorNext)
|
||||||
|
&& fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
|
||||||
|
{
|
||||||
|
Some((CallDesugaringKind::ForLoopNext, method_args.type_at(0)))
|
||||||
|
} else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) {
|
||||||
|
if tcx.is_lang_item(method_did, LangItem::TryTraitBranch) {
|
||||||
|
Some((CallDesugaringKind::QuestionBranch, method_args.type_at(0)))
|
||||||
|
} else if tcx.is_lang_item(method_did, LangItem::TryTraitFromResidual) {
|
||||||
|
Some((CallDesugaringKind::QuestionFromResidual, method_args.type_at(0)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else if tcx.is_lang_item(method_did, LangItem::TryTraitFromOutput)
|
||||||
|
&& fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock)
|
||||||
|
{
|
||||||
|
Some((CallDesugaringKind::TryBlockFromOutput, method_args.type_at(0)))
|
||||||
|
} else if fn_call_span.is_desugaring(DesugaringKind::Await) {
|
||||||
|
Some((CallDesugaringKind::Await, method_args.type_at(0)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
CallKind::Normal { self_arg, desugaring, method_did, method_args }
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod ambiguity;
|
pub mod ambiguity;
|
||||||
|
pub mod call_kind;
|
||||||
mod fulfillment_errors;
|
mod fulfillment_errors;
|
||||||
pub mod on_unimplemented;
|
pub mod on_unimplemented;
|
||||||
mod overflow;
|
mod overflow;
|
||||||
|
|
|
@ -11,7 +11,7 @@ impl Foo {
|
||||||
//~^ ERROR invalid generic `self` parameter type
|
//~^ ERROR invalid generic `self` parameter type
|
||||||
//~| ERROR destructor of `R` cannot be evaluated at compile-time
|
//~| ERROR destructor of `R` cannot be evaluated at compile-time
|
||||||
self.0
|
self.0
|
||||||
//~^ ERROR cannot call conditionally-const method `<R as Deref>::deref` in constant function
|
//~^ ERROR cannot perform conditionally-const deref coercion on `R` in constant functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
error[E0658]: cannot call conditionally-const method `<R as Deref>::deref` in constant functions
|
error[E0658]: cannot perform conditionally-const deref coercion on `R` in constant functions
|
||||||
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
|
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
|
||||||
|
|
|
|
||||||
LL | self.0
|
LL | self.0
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
|
= note: attempting to deref into `Foo`
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue