aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Daniel Faria <[email protected]>2020-07-23 15:11:37 +0100
committerPaul Daniel Faria <[email protected]>2020-08-10 13:46:34 +0100
commita6af0272f7bf129a3063cdd7096f685fc58438e6 (patch)
tree8a7041a76beb5df60742ad16b6325938efd4b3da
parent87cb09365cf841b559e76951eedb826f2d4d3dfd (diff)
Move semantic logic into Semantics, fix missing tag for safe amp operator, using functional methods rather than clunky inline closure
-rw-r--r--crates/ra_hir/src/semantics.rs110
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs89
-rw-r--r--crates/ra_ide/test_data/highlight_doctest.html2
-rw-r--r--crates/ra_ide/test_data/highlight_injection.html2
-rw-r--r--crates/ra_ide/test_data/highlight_unsafe.html4
-rw-r--r--crates/ra_ide/test_data/highlighting.html10
6 files changed, 112 insertions, 105 deletions
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index 1072b3971..f706a186e 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -25,7 +25,8 @@ use crate::{
25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, 25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
26 source_analyzer::{resolve_hir_path, resolve_hir_path_qualifier, SourceAnalyzer}, 26 source_analyzer::{resolve_hir_path, resolve_hir_path_qualifier, SourceAnalyzer},
27 AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, 27 AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef,
28 Module, ModuleDef, Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef, 28 Module, ModuleDef, Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, TypeRef,
29 VariantDef,
29}; 30};
30use resolver::TypeNs; 31use resolver::TypeNs;
31 32
@@ -280,45 +281,84 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
280 self.imp.assert_contains_node(node) 281 self.imp.assert_contains_node(node)
281 } 282 }
282 283
283 pub fn is_unsafe_pat(&self, pat: &ast::Pat) -> bool { 284 pub fn is_unsafe_method_call(&self, method_call_expr: ast::MethodCallExpr) -> Option<()> {
284 let ty = (|| { 285 let expr = method_call_expr.expr()?;
285 let parent = match pat { 286 let field_expr =
286 ast::Pat::BindPat(bind_pat) => bind_pat.syntax().parent()?, 287 if let ast::Expr::FieldExpr(field_expr) = expr { field_expr } else { return None };
287 _ => return None, 288 let ty = self.type_of_expr(&field_expr.expr()?)?;
288 }; 289 if !ty.is_packed(self.db) {
289 290 return None;
290 // `BindPat` can live under `RecordPat` directly under `RecordFieldPat` or 291 }
291 // `RecordFieldPatList`. `RecordFieldPat` also lives under `RecordFieldPatList`,
292 // so this tries to lookup the `BindPat` anywhere along that structure to the
293 // `RecordPat` so we can get the containing type.
294 let record_pat = ast::RecordFieldPat::cast(parent.clone())
295 .and_then(|record_pat| record_pat.syntax().parent())
296 .or_else(|| Some(parent.clone()))
297 .and_then(|parent| {
298 ast::RecordFieldPatList::cast(parent)?
299 .syntax()
300 .parent()
301 .and_then(ast::RecordPat::cast)
302 });
303
304 // If this doesn't match a `RecordPat`, fallback to a `LetStmt` to see if
305 // this is initialized from a `FieldExpr`.
306 if let Some(record_pat) = record_pat {
307 self.type_of_pat(&ast::Pat::RecordPat(record_pat))
308 } else if let Some(let_stmt) = ast::LetStmt::cast(parent) {
309 let field_expr = match let_stmt.initializer()? {
310 ast::Expr::FieldExpr(field_expr) => field_expr,
311 _ => return None,
312 };
313 292
314 self.type_of_expr(&field_expr.expr()?) 293 let func = self.resolve_method_call(&method_call_expr)?;
294 if func.has_self_param(self.db) {
295 let params = func.params(self.db);
296 if matches!(params.into_iter().next(), Some(TypeRef::Reference(..))) {
297 Some(())
315 } else { 298 } else {
316 None 299 None
317 } 300 }
318 })(); 301 } else {
302 None
303 }
304 }
319 305
320 // Binding a reference to a packed type is possibly unsafe. 306 pub fn is_unsafe_ref_expr(&self, ref_expr: &ast::RefExpr) -> bool {
321 ty.map(|ty| ty.is_packed(self.db)).unwrap_or(false) 307 ref_expr
308 .expr()
309 .and_then(|expr| {
310 let field_expr = match expr {
311 ast::Expr::FieldExpr(field_expr) => field_expr,
312 _ => return None,
313 };
314 let expr = field_expr.expr()?;
315 self.type_of_expr(&expr)
316 })
317 // Binding a reference to a packed type is possibly unsafe.
318 .map(|ty| ty.is_packed(self.db))
319 .unwrap_or(false)
320
321 // FIXME This needs layout computation to be correct. It will highlight
322 // more than it should with the current implementation.
323 }
324
325 pub fn is_unsafe_bind_pat(&self, bind_pat: &ast::BindPat) -> bool {
326 bind_pat
327 .syntax()
328 .parent()
329 .and_then(|parent| {
330 // `BindPat` can live under `RecordPat` directly under `RecordFieldPat` or
331 // `RecordFieldPatList`. `RecordFieldPat` also lives under `RecordFieldPatList`,
332 // so this tries to lookup the `BindPat` anywhere along that structure to the
333 // `RecordPat` so we can get the containing type.
334 let record_pat = ast::RecordFieldPat::cast(parent.clone())
335 .and_then(|record_pat| record_pat.syntax().parent())
336 .or_else(|| Some(parent.clone()))
337 .and_then(|parent| {
338 ast::RecordFieldPatList::cast(parent)?
339 .syntax()
340 .parent()
341 .and_then(ast::RecordPat::cast)
342 });
343
344 // If this doesn't match a `RecordPat`, fallback to a `LetStmt` to see if
345 // this is initialized from a `FieldExpr`.
346 if let Some(record_pat) = record_pat {
347 self.type_of_pat(&ast::Pat::RecordPat(record_pat))
348 } else if let Some(let_stmt) = ast::LetStmt::cast(parent) {
349 let field_expr = match let_stmt.initializer()? {
350 ast::Expr::FieldExpr(field_expr) => field_expr,
351 _ => return None,
352 };
353
354 self.type_of_expr(&field_expr.expr()?)
355 } else {
356 None
357 }
358 })
359 // Binding a reference to a packed type is possibly unsafe.
360 .map(|ty| ty.is_packed(self.db))
361 .unwrap_or(false)
322 } 362 }
323} 363}
324 364
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index cf93205b6..e29f65a78 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -565,29 +565,21 @@ fn highlight_element(
565 _ => h, 565 _ => h,
566 } 566 }
567 } 567 }
568 T![&] => {
569 let ref_expr = element.parent().and_then(ast::RefExpr::cast)?;
570 let expr = ref_expr.expr()?;
571 let field_expr = match expr {
572 ast::Expr::FieldExpr(fe) => fe,
573 _ => return None,
574 };
575
576 let expr = field_expr.expr()?;
577 let ty = sema.type_of_expr(&expr)?;
578 if !ty.is_packed(db) {
579 return None;
580 }
581
582 // FIXME This needs layout computation to be correct. It will highlight
583 // more than it should with the current implementation.
584
585 HighlightTag::Operator | HighlightModifier::Unsafe
586 }
587 p if p.is_punct() => match p { 568 p if p.is_punct() => match p {
588 T![::] | T![->] | T![=>] | T![&] | T![..] | T![=] | T![@] => { 569 T![&] => {
589 HighlightTag::Operator.into() 570 let h = HighlightTag::Operator.into();
571 let is_unsafe = element
572 .parent()
573 .and_then(ast::RefExpr::cast)
574 .map(|ref_expr| sema.is_unsafe_ref_expr(&ref_expr))
575 .unwrap_or(false);
576 if is_unsafe {
577 h | HighlightModifier::Unsafe
578 } else {
579 h
580 }
590 } 581 }
582 T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] => HighlightTag::Operator.into(),
591 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { 583 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => {
592 HighlightTag::Macro.into() 584 HighlightTag::Macro.into()
593 } 585 }
@@ -668,22 +660,18 @@ fn highlight_element(
668 HighlightTag::SelfKeyword.into() 660 HighlightTag::SelfKeyword.into()
669 } 661 }
670 } 662 }
671 T![ref] => { 663 T![ref] => element
672 let modifier: Option<HighlightModifier> = (|| { 664 .parent()
673 let bind_pat = element.parent().and_then(ast::BindPat::cast)?; 665 .and_then(ast::BindPat::cast)
674 if sema.is_unsafe_pat(&ast::Pat::BindPat(bind_pat)) { 666 .and_then(|bind_pat| {
667 if sema.is_unsafe_bind_pat(&bind_pat) {
675 Some(HighlightModifier::Unsafe) 668 Some(HighlightModifier::Unsafe)
676 } else { 669 } else {
677 None 670 None
678 } 671 }
679 })(); 672 })
680 673 .map(|modifier| h | modifier)
681 if let Some(modifier) = modifier { 674 .unwrap_or(h),
682 h | modifier
683 } else {
684 h
685 }
686 }
687 _ => h, 675 _ => h,
688 } 676 }
689 } 677 }
@@ -713,31 +701,6 @@ fn is_child_of_impl(element: &SyntaxElement) -> bool {
713 } 701 }
714} 702}
715 703
716fn is_method_call_unsafe(
717 sema: &Semantics<RootDatabase>,
718 method_call_expr: ast::MethodCallExpr,
719) -> Option<()> {
720 let expr = method_call_expr.expr()?;
721 let field_expr =
722 if let ast::Expr::FieldExpr(field_expr) = expr { field_expr } else { return None };
723 let ty = sema.type_of_expr(&field_expr.expr()?)?;
724 if !ty.is_packed(sema.db) {
725 return None;
726 }
727
728 let func = sema.resolve_method_call(&method_call_expr)?;
729 if func.has_self_param(sema.db) {
730 let params = func.params(sema.db);
731 if matches!(params.into_iter().next(), Some(TypeRef::Reference(..))) {
732 Some(())
733 } else {
734 None
735 }
736 } else {
737 None
738 }
739}
740
741fn highlight_name( 704fn highlight_name(
742 sema: &Semantics<RootDatabase>, 705 sema: &Semantics<RootDatabase>,
743 db: &RootDatabase, 706 db: &RootDatabase,
@@ -767,7 +730,7 @@ fn highlight_name(
767 let is_unsafe = name_ref 730 let is_unsafe = name_ref
768 .and_then(|name_ref| name_ref.syntax().parent()) 731 .and_then(|name_ref| name_ref.syntax().parent())
769 .and_then(ast::MethodCallExpr::cast) 732 .and_then(ast::MethodCallExpr::cast)
770 .and_then(|method_call_expr| is_method_call_unsafe(sema, method_call_expr)); 733 .and_then(|method_call_expr| sema.is_unsafe_method_call(method_call_expr));
771 if is_unsafe.is_some() { 734 if is_unsafe.is_some() {
772 h |= HighlightModifier::Unsafe; 735 h |= HighlightModifier::Unsafe;
773 } 736 }
@@ -846,7 +809,7 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
846 METHOD_CALL_EXPR => { 809 METHOD_CALL_EXPR => {
847 let mut h = Highlight::new(HighlightTag::Function); 810 let mut h = Highlight::new(HighlightTag::Function);
848 let is_unsafe = ast::MethodCallExpr::cast(parent) 811 let is_unsafe = ast::MethodCallExpr::cast(parent)
849 .and_then(|method_call_expr| is_method_call_unsafe(sema, method_call_expr)); 812 .and_then(|method_call_expr| sema.is_unsafe_method_call(method_call_expr));
850 813
851 if is_unsafe.is_some() { 814 if is_unsafe.is_some() {
852 h |= HighlightModifier::Unsafe; 815 h |= HighlightModifier::Unsafe;
@@ -866,7 +829,11 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
866 }) 829 })
867 }) 830 })
868 .unwrap_or(false); 831 .unwrap_or(false);
869 if is_union { h | HighlightModifier::Unsafe } else { h.into() } 832 if is_union {
833 h | HighlightModifier::Unsafe
834 } else {
835 h.into()
836 }
870 } 837 }
871 PATH_SEGMENT => { 838 PATH_SEGMENT => {
872 let path = match parent.parent().and_then(ast::Path::cast) { 839 let path = match parent.parent().and_then(ast::Path::cast) {
diff --git a/crates/ra_ide/test_data/highlight_doctest.html b/crates/ra_ide/test_data/highlight_doctest.html
index 46c1e0a11..6322d404f 100644
--- a/crates/ra_ide/test_data/highlight_doctest.html
+++ b/crates/ra_ide/test_data/highlight_doctest.html
@@ -87,7 +87,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
87 <span class="comment documentation">/// ```sh</span> 87 <span class="comment documentation">/// ```sh</span>
88 <span class="comment documentation">/// echo 1</span> 88 <span class="comment documentation">/// echo 1</span>
89 <span class="comment documentation">/// ```</span> 89 <span class="comment documentation">/// ```</span>
90 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">(</span>&<span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="punctuation">{</span> 90 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="punctuation">{</span>
91 <span class="bool_literal">true</span> 91 <span class="bool_literal">true</span>
92 <span class="punctuation">}</span> 92 <span class="punctuation">}</span>
93<span class="punctuation">}</span> 93<span class="punctuation">}</span>
diff --git a/crates/ra_ide/test_data/highlight_injection.html b/crates/ra_ide/test_data/highlight_injection.html
index 60c394399..18addd00d 100644
--- a/crates/ra_ide/test_data/highlight_injection.html
+++ b/crates/ra_ide/test_data/highlight_injection.html
@@ -35,7 +35,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
35 35
36.unresolved_reference { color: #FC5555; text-decoration: wavy underline; } 36.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
37</style> 37</style>
38<pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="punctuation">(</span><span class="value_param declaration">ra_fixture</span><span class="punctuation">:</span> &<span class="builtin_type">str</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 38<pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="punctuation">(</span><span class="value_param declaration">ra_fixture</span><span class="punctuation">:</span> <span class="operator">&</span><span class="builtin_type">str</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
39 39
40<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> 40<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
41 <span class="function">fixture</span><span class="punctuation">(</span><span class="string_literal">r#"</span> 41 <span class="function">fixture</span><span class="punctuation">(</span><span class="string_literal">r#"</span>
diff --git a/crates/ra_ide/test_data/highlight_unsafe.html b/crates/ra_ide/test_data/highlight_unsafe.html
index 454ff6d5f..a2df2c27e 100644
--- a/crates/ra_ide/test_data/highlight_unsafe.html
+++ b/crates/ra_ide/test_data/highlight_unsafe.html
@@ -45,7 +45,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
45<span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="punctuation">;</span> 45<span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="punctuation">;</span>
46 46
47<span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="punctuation">{</span> 47<span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="punctuation">{</span>
48 <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration unsafe">unsafe_method</span><span class="punctuation">(</span>&<span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 48 <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration unsafe">unsafe_method</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
49<span class="punctuation">}</span> 49<span class="punctuation">}</span>
50 50
51<span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="punctuation">{</span> 51<span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="punctuation">{</span>
@@ -55,7 +55,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
55<span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">global_mut</span><span class="punctuation">:</span> <span class="struct">TypeForStaticMut</span> <span class="operator">=</span> <span class="struct">TypeForStaticMut</span> <span class="punctuation">{</span> <span class="field">a</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span><span class="punctuation">;</span> 55<span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">global_mut</span><span class="punctuation">:</span> <span class="struct">TypeForStaticMut</span> <span class="operator">=</span> <span class="struct">TypeForStaticMut</span> <span class="punctuation">{</span> <span class="field">a</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span><span class="punctuation">;</span>
56 56
57<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> 57<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
58 <span class="keyword">let</span> <span class="variable declaration">x</span> <span class="operator">=</span> &<span class="numeric_literal">5</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="punctuation">_</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="builtin_type">usize</span><span class="punctuation">;</span> 58 <span class="keyword">let</span> <span class="variable declaration">x</span> <span class="operator">=</span> <span class="operator">&</span><span class="numeric_literal">5</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="punctuation">_</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="builtin_type">usize</span><span class="punctuation">;</span>
59 <span class="keyword">let</span> <span class="variable declaration">u</span> <span class="operator">=</span> <span class="union">Union</span> <span class="punctuation">{</span> <span class="field">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span><span class="punctuation">;</span> 59 <span class="keyword">let</span> <span class="variable declaration">u</span> <span class="operator">=</span> <span class="union">Union</span> <span class="punctuation">{</span> <span class="field">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span><span class="punctuation">;</span>
60 <span class="keyword unsafe">unsafe</span> <span class="punctuation">{</span> 60 <span class="keyword unsafe">unsafe</span> <span class="punctuation">{</span>
61 <span class="comment">// unsafe fn and method calls</span> 61 <span class="comment">// unsafe fn and method calls</span>
diff --git a/crates/ra_ide/test_data/highlighting.html b/crates/ra_ide/test_data/highlighting.html
index 678cf9bd3..8e0160eee 100644
--- a/crates/ra_ide/test_data/highlighting.html
+++ b/crates/ra_ide/test_data/highlighting.html
@@ -45,11 +45,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
45<span class="punctuation">}</span> 45<span class="punctuation">}</span>
46 46
47<span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="punctuation">{</span> 47<span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="punctuation">{</span>
48 <span class="keyword">fn</span> <span class="function declaration">bar</span><span class="punctuation">(</span>&<span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span><span class="punctuation">;</span> 48 <span class="keyword">fn</span> <span class="function declaration">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span><span class="punctuation">;</span>
49<span class="punctuation">}</span> 49<span class="punctuation">}</span>
50 50
51<span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="punctuation">{</span> 51<span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
52 <span class="keyword">fn</span> <span class="function declaration">bar</span><span class="punctuation">(</span>&<span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> 52 <span class="keyword">fn</span> <span class="function declaration">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
53 <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span> 53 <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span>
54 <span class="punctuation">}</span> 54 <span class="punctuation">}</span>
55<span class="punctuation">}</span> 55<span class="punctuation">}</span>
@@ -59,7 +59,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
59 <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span> 59 <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span>
60 <span class="punctuation">}</span> 60 <span class="punctuation">}</span>
61 61
62 <span class="keyword">fn</span> <span class="function declaration">qux</span><span class="punctuation">(</span>&<span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> 62 <span class="keyword">fn</span> <span class="function declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>
63 <span class="self_keyword mutable">self</span><span class="punctuation">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> 63 <span class="self_keyword mutable">self</span><span class="punctuation">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span>
64 <span class="punctuation">}</span> 64 <span class="punctuation">}</span>
65<span class="punctuation">}</span> 65<span class="punctuation">}</span>
@@ -107,8 +107,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
107 <span class="macro">noop!</span><span class="punctuation">(</span><span class="macro">noop</span><span class="macro">!</span><span class="punctuation">(</span><span class="numeric_literal">1</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span> 107 <span class="macro">noop!</span><span class="punctuation">(</span><span class="macro">noop</span><span class="macro">!</span><span class="punctuation">(</span><span class="numeric_literal">1</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span>
108 108
109 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">x</span> <span class="operator">=</span> <span class="numeric_literal">42</span><span class="punctuation">;</span> 109 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">x</span> <span class="operator">=</span> <span class="numeric_literal">42</span><span class="punctuation">;</span>
110 <span class="keyword">let</span> <span class="variable declaration mutable">y</span> <span class="operator">=</span> &<span class="keyword">mut</span> <span class="variable mutable">x</span><span class="punctuation">;</span> 110 <span class="keyword">let</span> <span class="variable declaration mutable">y</span> <span class="operator">=</span> <span class="operator">&</span><span class="keyword">mut</span> <span class="variable mutable">x</span><span class="punctuation">;</span>
111 <span class="keyword">let</span> <span class="variable declaration">z</span> <span class="operator">=</span> &<span class="variable mutable">y</span><span class="punctuation">;</span> 111 <span class="keyword">let</span> <span class="variable declaration">z</span> <span class="operator">=</span> <span class="operator">&</span><span class="variable mutable">y</span><span class="punctuation">;</span>
112 112
113 <span class="keyword">let</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable declaration">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span><span class="punctuation">;</span> 113 <span class="keyword">let</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable declaration">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span><span class="punctuation">;</span>
114 114