Highlight unsafe trait refs as unsafe only in impl blocks and definitions

This commit is contained in:
Lukas Wirth 2021-06-15 21:44:07 +02:00
parent 7f482afada
commit 29054e02fb
13 changed files with 60 additions and 19 deletions

View file

@ -48,7 +48,13 @@ pub(super) fn element(
match name_kind {
Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(),
Some(NameClass::Definition(def)) => {
highlight_def(db, krate, def) | HlMod::Definition
let mut h = highlight_def(db, krate, def) | HlMod::Definition;
if let Definition::ModuleDef(hir::ModuleDef::Trait(trait_)) = &def {
if trait_.is_unsafe(db) {
h |= HlMod::Unsafe;
}
}
h
}
Some(NameClass::ConstReference(def)) => highlight_def(db, krate, def),
Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
@ -87,20 +93,34 @@ pub(super) fn element(
let mut h = highlight_def(db, krate, def);
if let Definition::Local(local) = &def {
if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) {
match def {
Definition::Local(local)
if is_consumed_lvalue(
name_ref.syntax().clone().into(),
&local,
db,
) =>
{
h |= HlMod::Consuming;
}
}
if let Some(parent) = name_ref.syntax().parent() {
if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) {
if let Definition::Field(field) = def {
if let hir::VariantDef::Union(_) = field.parent_def(db) {
h |= HlMod::Unsafe;
Definition::ModuleDef(hir::ModuleDef::Trait(trait_))
if trait_.is_unsafe(db) =>
{
if ast::Impl::for_trait_name_ref(&name_ref).is_some() {
h |= HlMod::Unsafe;
}
}
Definition::Field(field) => {
if let Some(parent) = name_ref.syntax().parent() {
if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) {
if let hir::VariantDef::Union(_) = field.parent_def(db)
{
h |= HlMod::Unsafe;
}
}
}
}
_ => (),
}
h
@ -354,15 +374,7 @@ fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition)
h
}
hir::ModuleDef::Trait(trait_) => {
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Trait));
if trait_.is_unsafe(db) {
h |= HlMod::Unsafe;
}
h
}
hir::ModuleDef::Trait(_) => Highlight::new(HlTag::Symbol(SymbolKind::Trait)),
hir::ModuleDef::TypeAlias(type_) => {
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias));

View file

@ -67,6 +67,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }

View file

@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }

View file

@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }

View file

@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }

View file

@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }

View file

@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }

View file

@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }
@ -61,6 +62,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="field declaration">a</span><span class="colon">:</span> <span class="builtin_type">u16</span><span class="comma">,</span>
<span class="brace">}</span>
<span class="keyword unsafe">unsafe</span> <span class="keyword">trait</span> <span class="trait declaration unsafe">UnsafeTrait</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword unsafe">unsafe</span> <span class="keyword">impl</span> <span class="trait unsafe">UnsafeTrait</span> <span class="keyword">for</span> <span class="struct">Packed</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">fn</span> <span class="function declaration">require_unsafe_trait</span><span class="angle">&lt;</span><span class="type_param declaration">T</span><span class="colon">:</span> <span class="trait">UnsafeTrait</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="type_param">T</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="brace">{</span>
<span class="keyword">fn</span> <span class="function associated declaration trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="brace">}</span>

View file

@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }

View file

@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }

View file

@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }

View file

@ -527,6 +527,11 @@ struct Packed {
a: u16,
}
unsafe trait UnsafeTrait {}
unsafe impl UnsafeTrait for Packed {}
fn require_unsafe_trait<T: UnsafeTrait>(_: T) {}
trait DoTheAutoref {
fn calls_autoref(&self);
}

View file

@ -325,6 +325,15 @@ impl ast::Impl {
let second = types.next();
(first, second)
}
pub fn for_trait_name_ref(name_ref: &ast::NameRef) -> Option<ast::Impl> {
let this = name_ref.syntax().ancestors().find_map(ast::Impl::cast)?;
if this.trait_()?.syntax().text_range().start() == name_ref.syntax().text_range().start() {
Some(this)
} else {
None
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]