mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Add HighlightTag::Operator, use it for unsafe deref. Move unsafe validation to its own file
This commit is contained in:
parent
6c1682396c
commit
f678e0d837
@ -25,9 +25,11 @@ use hir_expand::{
|
|||||||
use hir_ty::{
|
use hir_ty::{
|
||||||
autoderef,
|
autoderef,
|
||||||
display::{HirDisplayError, HirFormatter},
|
display::{HirDisplayError, HirFormatter},
|
||||||
expr::{ExprValidator, UnsafeValidator},
|
expr::ExprValidator,
|
||||||
method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, Substs,
|
method_resolution,
|
||||||
TraitEnvironment, Ty, TyDefId, TypeCtor,
|
method_resolution, ApplicationTy, Canonical, InEnvironment, Substs, TraitEnvironment, Ty,
|
||||||
|
TyDefId, TypeCtor,
|
||||||
|
unsafe_validation::UnsafeValidator,
|
||||||
};
|
};
|
||||||
use ra_db::{CrateId, CrateName, Edition, FileId};
|
use ra_db::{CrateId, CrateName, Edition, FileId};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
|
@ -9,9 +9,7 @@ use rustc_hash::FxHashSet;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
diagnostics::{
|
diagnostics::{MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields},
|
||||||
MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields, MissingUnsafe,
|
|
||||||
},
|
|
||||||
lower::CallableDef,
|
lower::CallableDef,
|
||||||
utils::variant_data,
|
utils::variant_data,
|
||||||
ApplicationTy, InferenceResult, Ty, TypeCtor,
|
ApplicationTy, InferenceResult, Ty, TypeCtor,
|
||||||
@ -317,8 +315,8 @@ pub fn record_pattern_missing_fields(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct UnsafeExpr {
|
pub struct UnsafeExpr {
|
||||||
expr: ExprId,
|
pub expr: ExprId,
|
||||||
inside_unsafe_block: bool,
|
pub inside_unsafe_block: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnsafeExpr {
|
impl UnsafeExpr {
|
||||||
@ -383,43 +381,3 @@ pub fn unsafe_expressions(
|
|||||||
|
|
||||||
unsafe_exprs
|
unsafe_exprs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UnsafeValidator<'a, 'b: 'a> {
|
|
||||||
func: FunctionId,
|
|
||||||
infer: Arc<InferenceResult>,
|
|
||||||
sink: &'a mut DiagnosticSink<'b>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b> UnsafeValidator<'a, 'b> {
|
|
||||||
pub fn new(
|
|
||||||
func: FunctionId,
|
|
||||||
infer: Arc<InferenceResult>,
|
|
||||||
sink: &'a mut DiagnosticSink<'b>,
|
|
||||||
) -> UnsafeValidator<'a, 'b> {
|
|
||||||
UnsafeValidator { func, infer, sink }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn validate_body(&mut self, db: &dyn HirDatabase) {
|
|
||||||
let def = self.func.into();
|
|
||||||
let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
|
|
||||||
let func_data = db.function_data(self.func);
|
|
||||||
if func_data.is_unsafe
|
|
||||||
|| unsafe_expressions
|
|
||||||
.iter()
|
|
||||||
.filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block)
|
|
||||||
.count()
|
|
||||||
== 0
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (_, body_source) = db.body_with_source_map(def);
|
|
||||||
for unsafe_expr in unsafe_expressions {
|
|
||||||
if !unsafe_expr.inside_unsafe_block {
|
|
||||||
if let Ok(in_file) = body_source.as_ref().expr_syntax(unsafe_expr.expr) {
|
|
||||||
self.sink.push(MissingUnsafe { file: in_file.file_id, expr: in_file.value })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -37,6 +37,7 @@ pub(crate) mod utils;
|
|||||||
pub mod db;
|
pub mod db;
|
||||||
pub mod diagnostics;
|
pub mod diagnostics;
|
||||||
pub mod expr;
|
pub mod expr;
|
||||||
|
pub mod unsafe_validation;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -12,9 +12,8 @@ use rustc_hash::FxHashSet;
|
|||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase, diagnostics::Diagnostic, expr::ExprValidator,
|
||||||
diagnostics::Diagnostic,
|
unsafe_validation::UnsafeValidator,
|
||||||
expr::{ExprValidator, UnsafeValidator},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[salsa::database(
|
#[salsa::database(
|
||||||
|
63
crates/ra_hir_ty/src/unsafe_validation.rs
Normal file
63
crates/ra_hir_ty/src/unsafe_validation.rs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//! Provides validations for unsafe code. Currently checks if unsafe functions are missing
|
||||||
|
//! unsafe blocks.
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use hir_def::FunctionId;
|
||||||
|
use hir_expand::diagnostics::DiagnosticSink;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
db::HirDatabase, diagnostics::MissingUnsafe, expr::unsafe_expressions, InferenceResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub use hir_def::{
|
||||||
|
body::{
|
||||||
|
scope::{ExprScopes, ScopeEntry, ScopeId},
|
||||||
|
Body, BodySourceMap, ExprPtr, ExprSource, PatPtr, PatSource,
|
||||||
|
},
|
||||||
|
expr::{
|
||||||
|
ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp,
|
||||||
|
MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp,
|
||||||
|
},
|
||||||
|
LocalFieldId, VariantId,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct UnsafeValidator<'a, 'b: 'a> {
|
||||||
|
func: FunctionId,
|
||||||
|
infer: Arc<InferenceResult>,
|
||||||
|
sink: &'a mut DiagnosticSink<'b>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b> UnsafeValidator<'a, 'b> {
|
||||||
|
pub fn new(
|
||||||
|
func: FunctionId,
|
||||||
|
infer: Arc<InferenceResult>,
|
||||||
|
sink: &'a mut DiagnosticSink<'b>,
|
||||||
|
) -> UnsafeValidator<'a, 'b> {
|
||||||
|
UnsafeValidator { func, infer, sink }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn validate_body(&mut self, db: &dyn HirDatabase) {
|
||||||
|
let def = self.func.into();
|
||||||
|
let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
|
||||||
|
let func_data = db.function_data(self.func);
|
||||||
|
if func_data.is_unsafe
|
||||||
|
|| unsafe_expressions
|
||||||
|
.iter()
|
||||||
|
.filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block)
|
||||||
|
.count()
|
||||||
|
== 0
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (_, body_source) = db.body_with_source_map(def);
|
||||||
|
for unsafe_expr in unsafe_expressions {
|
||||||
|
if !unsafe_expr.inside_unsafe_block {
|
||||||
|
if let Ok(in_file) = body_source.as_ref().expr_syntax(unsafe_expr.expr) {
|
||||||
|
self.sink.push(MissingUnsafe { file: in_file.file_id, expr: in_file.value })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||||||
.string_literal { color: #CC9393; }
|
.string_literal { color: #CC9393; }
|
||||||
.field { color: #94BFF3; }
|
.field { color: #94BFF3; }
|
||||||
.function { color: #93E0E3; }
|
.function { color: #93E0E3; }
|
||||||
.function.unsafe { color: #BC8383; }
|
.function.unsafe { color: #E28C14; }
|
||||||
.operator.unsafe { color: #BC8383; }
|
.operator.unsafe { color: #BC8383; }
|
||||||
.parameter { color: #94BFF3; }
|
.parameter { color: #94BFF3; }
|
||||||
.text { color: #DCDCCC; }
|
.text { color: #DCDCCC; }
|
||||||
|
@ -12,7 +12,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||||||
.string_literal { color: #CC9393; }
|
.string_literal { color: #CC9393; }
|
||||||
.field { color: #94BFF3; }
|
.field { color: #94BFF3; }
|
||||||
.function { color: #93E0E3; }
|
.function { color: #93E0E3; }
|
||||||
.function.unsafe { color: #BC8383; }
|
.function.unsafe { color: #E28C14; }
|
||||||
.operator.unsafe { color: #BC8383; }
|
.operator.unsafe { color: #BC8383; }
|
||||||
.parameter { color: #94BFF3; }
|
.parameter { color: #94BFF3; }
|
||||||
.text { color: #DCDCCC; }
|
.text { color: #DCDCCC; }
|
||||||
|
@ -12,7 +12,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||||||
.string_literal { color: #CC9393; }
|
.string_literal { color: #CC9393; }
|
||||||
.field { color: #94BFF3; }
|
.field { color: #94BFF3; }
|
||||||
.function { color: #93E0E3; }
|
.function { color: #93E0E3; }
|
||||||
.function.unsafe { color: #BC8383; }
|
.function.unsafe { color: #E28C14; }
|
||||||
.operator.unsafe { color: #BC8383; }
|
.operator.unsafe { color: #BC8383; }
|
||||||
.parameter { color: #94BFF3; }
|
.parameter { color: #94BFF3; }
|
||||||
.text { color: #DCDCCC; }
|
.text { color: #DCDCCC; }
|
||||||
@ -47,7 +47,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||||||
<span class="keyword unsafe">unsafe</span> {
|
<span class="keyword unsafe">unsafe</span> {
|
||||||
<span class="function unsafe">unsafe_fn</span>();
|
<span class="function unsafe">unsafe_fn</span>();
|
||||||
<span class="struct">HasUnsafeFn</span>.<span class="function unsafe">unsafe_method</span>();
|
<span class="struct">HasUnsafeFn</span>.<span class="function unsafe">unsafe_method</span>();
|
||||||
<span class="keyword">let</span> <span class="variable declaration">y</span> = <span class="operator unsafe">*</span>(<span class="variable">x</span>);
|
<span class="keyword">let</span> <span class="variable declaration">y</span> = <span class="function unsafe">*</span><span class="variable">x</span>;
|
||||||
<span class="keyword">let</span> <span class="variable declaration">z</span> = -<span class="variable">x</span>;
|
<span class="keyword">let</span> <span class="variable declaration">z</span> = -<span class="variable">x</span>;
|
||||||
}
|
}
|
||||||
}</code></pre>
|
}</code></pre>
|
@ -12,7 +12,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||||||
.string_literal { color: #CC9393; }
|
.string_literal { color: #CC9393; }
|
||||||
.field { color: #94BFF3; }
|
.field { color: #94BFF3; }
|
||||||
.function { color: #93E0E3; }
|
.function { color: #93E0E3; }
|
||||||
.function.unsafe { color: #BC8383; }
|
.function.unsafe { color: #E28C14; }
|
||||||
.operator.unsafe { color: #BC8383; }
|
.operator.unsafe { color: #BC8383; }
|
||||||
.parameter { color: #94BFF3; }
|
.parameter { color: #94BFF3; }
|
||||||
.text { color: #DCDCCC; }
|
.text { color: #DCDCCC; }
|
||||||
|
@ -12,7 +12,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||||||
.string_literal { color: #CC9393; }
|
.string_literal { color: #CC9393; }
|
||||||
.field { color: #94BFF3; }
|
.field { color: #94BFF3; }
|
||||||
.function { color: #93E0E3; }
|
.function { color: #93E0E3; }
|
||||||
.function.unsafe { color: #BC8383; }
|
.function.unsafe { color: #E28C14; }
|
||||||
.operator.unsafe { color: #BC8383; }
|
.operator.unsafe { color: #BC8383; }
|
||||||
.parameter { color: #94BFF3; }
|
.parameter { color: #94BFF3; }
|
||||||
.text { color: #DCDCCC; }
|
.text { color: #DCDCCC; }
|
||||||
|
@ -71,7 +71,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||||||
.string_literal { color: #CC9393; }
|
.string_literal { color: #CC9393; }
|
||||||
.field { color: #94BFF3; }
|
.field { color: #94BFF3; }
|
||||||
.function { color: #93E0E3; }
|
.function { color: #93E0E3; }
|
||||||
.function.unsafe { color: #BC8383; }
|
.function.unsafe { color: #E28C14; }
|
||||||
.operator.unsafe { color: #BC8383; }
|
.operator.unsafe { color: #BC8383; }
|
||||||
.parameter { color: #94BFF3; }
|
.parameter { color: #94BFF3; }
|
||||||
.text { color: #DCDCCC; }
|
.text { color: #DCDCCC; }
|
||||||
|
Loading…
Reference in New Issue
Block a user