Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion crates/hir-expand/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ pub(crate) fn parse_with_map(
/// This resolves the [MacroCallId] to check if it is a derive macro if so get the [macro_arg] for the derive.
/// Other wise return the [macro_arg] for the macro_call_id.
///
/// This is not connected to the database so it does not cached the result. However, the inner [macro_arg] query is
/// This is not connected to the database so it does not cache the result. However, the inner [macro_arg] query is
#[allow(deprecated)] // we are macro_arg_considering_derives
fn macro_arg_considering_derives<'db>(
db: &'db dyn ExpandDatabase,
Expand Down
10 changes: 10 additions & 0 deletions crates/hir-ty/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,16 @@ pub enum InferenceDiagnostic {
found: StoredTy,
},
SolverDiagnostic(SolverDiagnostic),
ExplicitDropMethodUse {
#[type_visitable(ignore)]
kind: ExplicitDropMethodUseKind,
},
}

#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ExplicitDropMethodUseKind {
MethodCall(ExprId),
Path(ExprOrPatId),
}

/// Represents coercing a value to a different type of value.
Expand Down
10 changes: 9 additions & 1 deletion crates/hir-ty/src/infer/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_type_ir::inherent::{SliceLike, Ty as _};
use stdx::never;

use crate::{
InferenceDiagnostic, Span, ValueTyDefId,
ExplicitDropMethodUseKind, InferenceDiagnostic, Span, ValueTyDefId,
infer::{
InferenceTyLoweringVarsCtx, diagnostics::InferenceTyLoweringContext as TyLoweringContext,
},
Expand All @@ -33,6 +33,14 @@ impl<'db> InferenceContext<'_, 'db> {
) -> Option<(ValueNs, Ty<'db>)> {
let (value, self_subst) = self.resolve_value_path_inner(path, id, false)?;

if let ValueNs::FunctionId(f) = value
&& self.lang_items.Drop_drop.is_some_and(|drop_fn| drop_fn == f)
{
self.push_diagnostic(InferenceDiagnostic::ExplicitDropMethodUse {
kind: ExplicitDropMethodUseKind::Path(id),
});
}

let (value_def, generic_def, substs) =
match self.resolve_value_path(path, id, value, self_subst)? {
ValuePathResolution::GenericDef(value_def, generic_def, substs) => {
Expand Down
7 changes: 4 additions & 3 deletions crates/hir-ty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,10 @@ use crate::{

pub use autoderef::autoderef;
pub use infer::{
Adjust, Adjustment, AutoBorrow, BindingMode, ByRef, InferenceDiagnostic, InferenceResult,
InferenceTyDiagnosticSource, OverloadedDeref, PointerCast, cast::CastError, could_coerce,
could_unify, could_unify_deeply, infer_query_with_inspect,
Adjust, Adjustment, AutoBorrow, BindingMode, ByRef, ExplicitDropMethodUseKind,
InferenceDiagnostic, InferenceResult, InferenceTyDiagnosticSource, OverloadedDeref,
PointerCast, cast::CastError, could_coerce, could_unify, could_unify_deeply,
infer_query_with_inspect,
};
pub use lower::{
GenericDefaults, GenericDefaultsRef, GenericPredicates, ImplTraits, LifetimeElisionKind,
Expand Down
6 changes: 4 additions & 2 deletions crates/hir-ty/src/method_resolution/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
Adjust, Adjustment, AutoBorrow, IncorrectGenericsLenKind, InferenceDiagnostic,
LifetimeElisionKind, PointerCast, Span,
db::HirDatabase,
infer::{AllowTwoPhase, AutoBorrowMutability, InferenceContext},
infer::{AllowTwoPhase, AutoBorrowMutability, ExplicitDropMethodUseKind, InferenceContext},
lower::{
GenericPredicates,
path::{GenericArgsLowerer, TypeLikeConst, substs_from_args_and_bindings},
Expand Down Expand Up @@ -582,7 +582,9 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> {
fn check_for_illegal_method_calls(&self) {
// Disallow calls to the method `drop` defined in the `Drop` trait.
if self.ctx.lang_items.Drop_drop.is_some_and(|drop_fn| drop_fn == self.candidate) {
// FIXME: Report an error.
self.ctx.push_diagnostic(InferenceDiagnostic::ExplicitDropMethodUse {
kind: ExplicitDropMethodUseKind::MethodCall(self.call_expr),
});
}
}

Expand Down
30 changes: 28 additions & 2 deletions crates/hir/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ use hir_def::{
};
use hir_expand::{HirFileId, InFile, mod_path::ModPath, name::Name};
use hir_ty::{
CastError, InferenceDiagnostic, InferenceTyDiagnosticSource, ParamEnvAndCrate,
PathGenericsSource, PathLoweringDiagnostic, TyLoweringDiagnostic, TyLoweringDiagnosticKind,
CastError, ExplicitDropMethodUseKind, InferenceDiagnostic, InferenceTyDiagnosticSource,
ParamEnvAndCrate, PathGenericsSource, PathLoweringDiagnostic, TyLoweringDiagnostic,
TyLoweringDiagnosticKind,
db::HirDatabase,
diagnostics::{BodyValidationDiagnostic, UnsafetyReason},
display::{DisplayTarget, HirDisplay},
Expand Down Expand Up @@ -106,6 +107,7 @@ diagnostics![AnyDiagnostic<'db> ->
CastToUnsized<'db>,
ExpectedArrayOrSlicePat<'db>,
ExpectedFunction<'db>,
ExplicitDropMethodUse,
FruInDestructuringAssignment,
FunctionalRecordUpdateOnNonStruct,
GenericDefaultRefersToSelf,
Expand Down Expand Up @@ -325,6 +327,11 @@ pub struct CannotBeDereferenced<'db> {
pub found: Type<'db>,
}

#[derive(Debug)]
pub struct ExplicitDropMethodUse {
pub expr_or_path: Either<InFile<AstPtr<ast::MethodCallExpr>>, InFile<AstPtr<ast::Path>>>,
}

#[derive(Debug)]
pub struct FruInDestructuringAssignment {
pub node: InFile<AstPtr<ast::Expr>>,
Expand Down Expand Up @@ -1044,6 +1051,25 @@ impl<'db> AnyDiagnostic<'db> {
let span = span_syntax(d.span)?;
Self::solver_diagnostic(db, &d.kind, span, env)?
}
InferenceDiagnostic::ExplicitDropMethodUse { kind } => {
let expr_or_path = match kind {
ExplicitDropMethodUseKind::MethodCall(expr) => {
let expr = expr_syntax(*expr)?;
let expr = expr.with_value(expr.value.cast::<ast::MethodCallExpr>()?);
Either::Left(expr)
}
ExplicitDropMethodUseKind::Path(path_expr_id) => {
let syntax = expr_or_pat_syntax(*path_expr_id)?;
let file_id = syntax.file_id;
let syntax =
syntax.with_value(syntax.value.cast::<ast::PathExpr>()?).to_node(db);
let path = syntax.path()?;
let path = InFile::new(file_id, AstPtr::new(&path));
Either::Right(path)
}
};
ExplicitDropMethodUse { expr_or_path }.into()
}
})
}

Expand Down
Loading
Loading