diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/primitive.rs | 54 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/mapping.rs | 24 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/highlight_strings.html | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/tests.rs | 59 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/tokens.rs | 37 |
9 files changed, 84 insertions, 151 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index 2e16e5120..f965eb2b5 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs | |||
@@ -39,8 +39,7 @@ use ra_syntax::SmolStr; | |||
39 | use super::{ | 39 | use super::{ |
40 | primitive::{FloatTy, IntTy}, | 40 | primitive::{FloatTy, IntTy}, |
41 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | 41 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, |
42 | ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, | 42 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, |
43 | TypeWalk, Uncertain, | ||
44 | }; | 43 | }; |
45 | use crate::{ | 44 | use crate::{ |
46 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, | 45 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, |
@@ -312,12 +311,6 @@ impl<'a> InferenceContext<'a> { | |||
312 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | 311 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { |
313 | match ty { | 312 | match ty { |
314 | Ty::Unknown => self.table.new_type_var(), | 313 | Ty::Unknown => self.table.new_type_var(), |
315 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(Uncertain::Unknown), .. }) => { | ||
316 | self.table.new_integer_var() | ||
317 | } | ||
318 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(Uncertain::Unknown), .. }) => { | ||
319 | self.table.new_float_var() | ||
320 | } | ||
321 | _ => ty, | 314 | _ => ty, |
322 | } | 315 | } |
323 | } | 316 | } |
@@ -664,8 +657,8 @@ impl InferTy { | |||
664 | fn fallback_value(self) -> Ty { | 657 | fn fallback_value(self) -> Ty { |
665 | match self { | 658 | match self { |
666 | InferTy::TypeVar(..) => Ty::Unknown, | 659 | InferTy::TypeVar(..) => Ty::Unknown, |
667 | InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(Uncertain::Known(IntTy::i32()))), | 660 | InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(IntTy::i32())), |
668 | InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(Uncertain::Known(FloatTy::f64()))), | 661 | InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(FloatTy::f64())), |
669 | InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), | 662 | InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), |
670 | } | 663 | } |
671 | } | 664 | } |
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 4a98e2deb..9fd310f69 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -18,7 +18,7 @@ use crate::{ | |||
18 | traits::InEnvironment, | 18 | traits::InEnvironment, |
19 | utils::{generics, variant_data, Generics}, | 19 | utils::{generics, variant_data, Generics}, |
20 | ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Rawness, Substs, | 20 | ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Rawness, Substs, |
21 | TraitRef, Ty, TypeCtor, Uncertain, | 21 | TraitRef, Ty, TypeCtor, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | use super::{ | 24 | use super::{ |
@@ -426,15 +426,7 @@ impl<'a> InferenceContext<'a> { | |||
426 | match &inner_ty { | 426 | match &inner_ty { |
427 | // Fast path for builtins | 427 | // Fast path for builtins |
428 | Ty::Apply(ApplicationTy { | 428 | Ty::Apply(ApplicationTy { |
429 | ctor: | 429 | ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), |
430 | TypeCtor::Int(Uncertain::Known(IntTy { | ||
431 | signedness: Signedness::Signed, | ||
432 | .. | ||
433 | })), | ||
434 | .. | ||
435 | }) | ||
436 | | Ty::Apply(ApplicationTy { | ||
437 | ctor: TypeCtor::Int(Uncertain::Unknown), | ||
438 | .. | 430 | .. |
439 | }) | 431 | }) |
440 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) | 432 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) |
@@ -577,9 +569,7 @@ impl<'a> InferenceContext<'a> { | |||
577 | ); | 569 | ); |
578 | self.infer_expr( | 570 | self.infer_expr( |
579 | *repeat, | 571 | *repeat, |
580 | &Expectation::has_type(Ty::simple(TypeCtor::Int(Uncertain::Known( | 572 | &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), |
581 | IntTy::usize(), | ||
582 | )))), | ||
583 | ); | 573 | ); |
584 | } | 574 | } |
585 | } | 575 | } |
@@ -592,13 +582,19 @@ impl<'a> InferenceContext<'a> { | |||
592 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) | 582 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) |
593 | } | 583 | } |
594 | Literal::ByteString(..) => { | 584 | Literal::ByteString(..) => { |
595 | let byte_type = Ty::simple(TypeCtor::Int(Uncertain::Known(IntTy::u8()))); | 585 | let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); |
596 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); | 586 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); |
597 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) | 587 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) |
598 | } | 588 | } |
599 | Literal::Char(..) => Ty::simple(TypeCtor::Char), | 589 | Literal::Char(..) => Ty::simple(TypeCtor::Char), |
600 | Literal::Int(_v, ty) => Ty::simple(TypeCtor::Int((*ty).into())), | 590 | Literal::Int(_v, ty) => match ty { |
601 | Literal::Float(_v, ty) => Ty::simple(TypeCtor::Float((*ty).into())), | 591 | Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), |
592 | None => self.table.new_integer_var(), | ||
593 | }, | ||
594 | Literal::Float(_v, ty) => match ty { | ||
595 | Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), | ||
596 | None => self.table.new_float_var(), | ||
597 | }, | ||
602 | }, | 598 | }, |
603 | }; | 599 | }; |
604 | // use a new type variable if we got Ty::Unknown here | 600 | // use a new type variable if we got Ty::Unknown here |
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 135976fcd..2b9372b4b 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -58,7 +58,7 @@ use ra_db::{impl_intern_key, salsa, CrateId}; | |||
58 | 58 | ||
59 | use crate::{ | 59 | use crate::{ |
60 | db::HirDatabase, | 60 | db::HirDatabase, |
61 | primitive::{FloatTy, IntTy, Uncertain}, | 61 | primitive::{FloatTy, IntTy}, |
62 | utils::{generics, make_mut_slice, Generics}, | 62 | utils::{generics, make_mut_slice, Generics}, |
63 | }; | 63 | }; |
64 | use display::HirDisplay; | 64 | use display::HirDisplay; |
@@ -87,10 +87,10 @@ pub enum TypeCtor { | |||
87 | Char, | 87 | Char, |
88 | 88 | ||
89 | /// A primitive integer type. For example, `i32`. | 89 | /// A primitive integer type. For example, `i32`. |
90 | Int(Uncertain<IntTy>), | 90 | Int(IntTy), |
91 | 91 | ||
92 | /// A primitive floating-point type. For example, `f64`. | 92 | /// A primitive floating-point type. For example, `f64`. |
93 | Float(Uncertain<FloatTy>), | 93 | Float(FloatTy), |
94 | 94 | ||
95 | /// Structures, enumerations and unions. | 95 | /// Structures, enumerations and unions. |
96 | Adt(AdtId), | 96 | Adt(AdtId), |
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index e19628fdf..e83b39456 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs | |||
@@ -16,12 +16,8 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
16 | 16 | ||
17 | use super::Substs; | 17 | use super::Substs; |
18 | use crate::{ | 18 | use crate::{ |
19 | autoderef, | 19 | autoderef, db::HirDatabase, primitive::FloatBitness, utils::all_super_traits, ApplicationTy, |
20 | db::HirDatabase, | 20 | Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, |
21 | primitive::{FloatBitness, Uncertain}, | ||
22 | utils::all_super_traits, | ||
23 | ApplicationTy, Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty, | ||
24 | TypeCtor, TypeWalk, | ||
25 | }; | 21 | }; |
26 | 22 | ||
27 | /// This is used as a key for indexing impls. | 23 | /// This is used as a key for indexing impls. |
@@ -147,12 +143,12 @@ impl Ty { | |||
147 | } | 143 | } |
148 | TypeCtor::Bool => lang_item_crate!("bool"), | 144 | TypeCtor::Bool => lang_item_crate!("bool"), |
149 | TypeCtor::Char => lang_item_crate!("char"), | 145 | TypeCtor::Char => lang_item_crate!("char"), |
150 | TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { | 146 | TypeCtor::Float(f) => match f.bitness { |
151 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) | 147 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) |
152 | FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), | 148 | FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), |
153 | FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), | 149 | FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), |
154 | }, | 150 | }, |
155 | TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()), | 151 | TypeCtor::Int(i) => lang_item_crate!(i.ty_to_string()), |
156 | TypeCtor::Str => lang_item_crate!("str_alloc", "str"), | 152 | TypeCtor::Str => lang_item_crate!("str_alloc", "str"), |
157 | TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), | 153 | TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), |
158 | TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), | 154 | TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), |
diff --git a/crates/ra_hir_ty/src/primitive.rs b/crates/ra_hir_ty/src/primitive.rs index 02a8179d9..37966b709 100644 --- a/crates/ra_hir_ty/src/primitive.rs +++ b/crates/ra_hir_ty/src/primitive.rs | |||
@@ -7,42 +7,6 @@ use std::fmt; | |||
7 | 7 | ||
8 | pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; | 8 | pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; |
9 | 9 | ||
10 | #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] | ||
11 | pub enum Uncertain<T> { | ||
12 | Unknown, | ||
13 | Known(T), | ||
14 | } | ||
15 | |||
16 | impl From<IntTy> for Uncertain<IntTy> { | ||
17 | fn from(ty: IntTy) -> Self { | ||
18 | Uncertain::Known(ty) | ||
19 | } | ||
20 | } | ||
21 | |||
22 | impl fmt::Display for Uncertain<IntTy> { | ||
23 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
24 | match *self { | ||
25 | Uncertain::Unknown => write!(f, "{{integer}}"), | ||
26 | Uncertain::Known(ty) => write!(f, "{}", ty), | ||
27 | } | ||
28 | } | ||
29 | } | ||
30 | |||
31 | impl From<FloatTy> for Uncertain<FloatTy> { | ||
32 | fn from(ty: FloatTy) -> Self { | ||
33 | Uncertain::Known(ty) | ||
34 | } | ||
35 | } | ||
36 | |||
37 | impl fmt::Display for Uncertain<FloatTy> { | ||
38 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
39 | match *self { | ||
40 | Uncertain::Unknown => write!(f, "{{float}}"), | ||
41 | Uncertain::Known(ty) => write!(f, "{}", ty), | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | #[derive(Copy, Clone, Eq, PartialEq, Hash)] | 10 | #[derive(Copy, Clone, Eq, PartialEq, Hash)] |
47 | pub struct IntTy { | 11 | pub struct IntTy { |
48 | pub signedness: Signedness, | 12 | pub signedness: Signedness, |
@@ -173,21 +137,3 @@ impl From<BuiltinFloat> for FloatTy { | |||
173 | FloatTy { bitness: t.bitness } | 137 | FloatTy { bitness: t.bitness } |
174 | } | 138 | } |
175 | } | 139 | } |
176 | |||
177 | impl From<Option<BuiltinInt>> for Uncertain<IntTy> { | ||
178 | fn from(t: Option<BuiltinInt>) -> Self { | ||
179 | match t { | ||
180 | None => Uncertain::Unknown, | ||
181 | Some(t) => Uncertain::Known(t.into()), | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | |||
186 | impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> { | ||
187 | fn from(t: Option<BuiltinFloat>) -> Self { | ||
188 | match t { | ||
189 | None => Uncertain::Unknown, | ||
190 | Some(t) => Uncertain::Known(t.into()), | ||
191 | } | ||
192 | } | ||
193 | } | ||
diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index 28a5fbe3e..18e5c9c16 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs | |||
@@ -14,7 +14,7 @@ use ra_db::salsa::InternKey; | |||
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | db::HirDatabase, | 16 | db::HirDatabase, |
17 | primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, | 17 | primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, |
18 | traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, | 18 | traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, |
19 | ApplicationTy, CallableDef, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, | 19 | ApplicationTy, CallableDef, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, |
20 | ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, | 20 | ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, |
@@ -249,11 +249,11 @@ impl ToChalk for TypeCtor { | |||
249 | 249 | ||
250 | TypeCtor::Bool => TypeName::Scalar(Scalar::Bool), | 250 | TypeCtor::Bool => TypeName::Scalar(Scalar::Bool), |
251 | TypeCtor::Char => TypeName::Scalar(Scalar::Char), | 251 | TypeCtor::Char => TypeName::Scalar(Scalar::Char), |
252 | TypeCtor::Int(Uncertain::Known(int_ty)) => TypeName::Scalar(int_ty_to_chalk(int_ty)), | 252 | TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)), |
253 | TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 })) => { | 253 | TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => { |
254 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) | 254 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) |
255 | } | 255 | } |
256 | TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 })) => { | 256 | TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => { |
257 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) | 257 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) |
258 | } | 258 | } |
259 | 259 | ||
@@ -268,9 +268,7 @@ impl ToChalk for TypeCtor { | |||
268 | } | 268 | } |
269 | TypeCtor::Never => TypeName::Never, | 269 | TypeCtor::Never => TypeName::Never, |
270 | 270 | ||
271 | TypeCtor::Int(Uncertain::Unknown) | 271 | TypeCtor::Adt(_) |
272 | | TypeCtor::Float(Uncertain::Unknown) | ||
273 | | TypeCtor::Adt(_) | ||
274 | | TypeCtor::Array | 272 | | TypeCtor::Array |
275 | | TypeCtor::FnPtr { .. } | 273 | | TypeCtor::FnPtr { .. } |
276 | | TypeCtor::Closure { .. } => { | 274 | | TypeCtor::Closure { .. } => { |
@@ -291,19 +289,19 @@ impl ToChalk for TypeCtor { | |||
291 | 289 | ||
292 | TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool, | 290 | TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool, |
293 | TypeName::Scalar(Scalar::Char) => TypeCtor::Char, | 291 | TypeName::Scalar(Scalar::Char) => TypeCtor::Char, |
294 | TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(Uncertain::Known(IntTy { | 292 | TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(IntTy { |
295 | signedness: Signedness::Signed, | 293 | signedness: Signedness::Signed, |
296 | bitness: bitness_from_chalk_int(int_ty), | 294 | bitness: bitness_from_chalk_int(int_ty), |
297 | })), | 295 | }), |
298 | TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(Uncertain::Known(IntTy { | 296 | TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(IntTy { |
299 | signedness: Signedness::Unsigned, | 297 | signedness: Signedness::Unsigned, |
300 | bitness: bitness_from_chalk_uint(uint_ty), | 298 | bitness: bitness_from_chalk_uint(uint_ty), |
301 | })), | 299 | }), |
302 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => { | 300 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => { |
303 | TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 })) | 301 | TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) |
304 | } | 302 | } |
305 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => { | 303 | TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => { |
306 | TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 })) | 304 | TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) |
307 | } | 305 | } |
308 | TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 }, | 306 | TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 }, |
309 | TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)), | 307 | TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)), |
diff --git a/crates/ra_ide/src/snapshots/highlight_strings.html b/crates/ra_ide/src/snapshots/highlight_strings.html index e97192b61..6a5cf0e74 100644 --- a/crates/ra_ide/src/snapshots/highlight_strings.html +++ b/crates/ra_ide/src/snapshots/highlight_strings.html | |||
@@ -63,7 +63,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
63 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">^</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="string_literal">"x"</span>); | 63 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">^</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="string_literal">"x"</span>); |
64 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">></span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="string_literal">"x"</span>); | 64 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">></span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="string_literal">"x"</span>); |
65 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">+</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="numeric_literal">5</span>); | 65 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">+</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="numeric_literal">5</span>); |
66 | <span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="variable">x</span><span class="string_literal">}!"</span>, <span class="numeric_literal">27</span>); | 66 | <span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="numeric_literal">27</span>); |
67 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="numeric_literal">5</span>); | 67 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="numeric_literal">5</span>); |
68 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, -<span class="numeric_literal">5</span>); | 68 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, -<span class="numeric_literal">5</span>); |
69 | <span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="numeric_literal">0</span><span class="numeric_literal">10</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="numeric_literal">27</span>); | 69 | <span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="numeric_literal">0</span><span class="numeric_literal">10</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="numeric_literal">27</span>); |
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs index 36a1aa419..5e42c5b55 100644 --- a/crates/ra_ide/src/syntax_highlighting/tests.rs +++ b/crates/ra_ide/src/syntax_highlighting/tests.rs | |||
@@ -7,9 +7,21 @@ use crate::{ | |||
7 | FileRange, TextRange, | 7 | FileRange, TextRange, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | /// Highlights the code given by the `ra_fixture` argument, renders the | ||
11 | /// result as HTML, and compares it with the HTML file given as `snapshot`. | ||
12 | /// Note that the `snapshot` file is overwritten by the rendered HTML. | ||
13 | fn check_highlighting(ra_fixture: &str, snapshot: &str, rainbow: bool) { | ||
14 | let (analysis, file_id) = single_file(ra_fixture); | ||
15 | let dst_file = project_dir().join(snapshot); | ||
16 | let actual_html = &analysis.highlight_as_html(file_id, rainbow).unwrap(); | ||
17 | let expected_html = &read_text(&dst_file); | ||
18 | fs::write(dst_file, &actual_html).unwrap(); | ||
19 | assert_eq_text!(expected_html, actual_html); | ||
20 | } | ||
21 | |||
10 | #[test] | 22 | #[test] |
11 | fn test_highlighting() { | 23 | fn test_highlighting() { |
12 | let (analysis, file_id) = single_file( | 24 | check_highlighting( |
13 | r#" | 25 | r#" |
14 | #[derive(Clone, Debug)] | 26 | #[derive(Clone, Debug)] |
15 | struct Foo { | 27 | struct Foo { |
@@ -84,17 +96,14 @@ impl<T> Option<T> { | |||
84 | } | 96 | } |
85 | "# | 97 | "# |
86 | .trim(), | 98 | .trim(), |
99 | "crates/ra_ide/src/snapshots/highlighting.html", | ||
100 | false, | ||
87 | ); | 101 | ); |
88 | let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlighting.html"); | ||
89 | let actual_html = &analysis.highlight_as_html(file_id, false).unwrap(); | ||
90 | let expected_html = &read_text(&dst_file); | ||
91 | fs::write(dst_file, &actual_html).unwrap(); | ||
92 | assert_eq_text!(expected_html, actual_html); | ||
93 | } | 102 | } |
94 | 103 | ||
95 | #[test] | 104 | #[test] |
96 | fn test_rainbow_highlighting() { | 105 | fn test_rainbow_highlighting() { |
97 | let (analysis, file_id) = single_file( | 106 | check_highlighting( |
98 | r#" | 107 | r#" |
99 | fn main() { | 108 | fn main() { |
100 | let hello = "hello"; | 109 | let hello = "hello"; |
@@ -110,12 +119,9 @@ fn bar() { | |||
110 | } | 119 | } |
111 | "# | 120 | "# |
112 | .trim(), | 121 | .trim(), |
122 | "crates/ra_ide/src/snapshots/rainbow_highlighting.html", | ||
123 | true, | ||
113 | ); | 124 | ); |
114 | let dst_file = project_dir().join("crates/ra_ide/src/snapshots/rainbow_highlighting.html"); | ||
115 | let actual_html = &analysis.highlight_as_html(file_id, true).unwrap(); | ||
116 | let expected_html = &read_text(&dst_file); | ||
117 | fs::write(dst_file, &actual_html).unwrap(); | ||
118 | assert_eq_text!(expected_html, actual_html); | ||
119 | } | 125 | } |
120 | 126 | ||
121 | #[test] | 127 | #[test] |
@@ -153,7 +159,7 @@ fn test_ranges() { | |||
153 | 159 | ||
154 | #[test] | 160 | #[test] |
155 | fn test_flattening() { | 161 | fn test_flattening() { |
156 | let (analysis, file_id) = single_file( | 162 | check_highlighting( |
157 | r##" | 163 | r##" |
158 | fn fixture(ra_fixture: &str) {} | 164 | fn fixture(ra_fixture: &str) {} |
159 | 165 | ||
@@ -167,13 +173,9 @@ fn main() { | |||
167 | ); | 173 | ); |
168 | }"## | 174 | }"## |
169 | .trim(), | 175 | .trim(), |
176 | "crates/ra_ide/src/snapshots/highlight_injection.html", | ||
177 | false, | ||
170 | ); | 178 | ); |
171 | |||
172 | let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlight_injection.html"); | ||
173 | let actual_html = &analysis.highlight_as_html(file_id, false).unwrap(); | ||
174 | let expected_html = &read_text(&dst_file); | ||
175 | fs::write(dst_file, &actual_html).unwrap(); | ||
176 | assert_eq_text!(expected_html, actual_html); | ||
177 | } | 179 | } |
178 | 180 | ||
179 | #[test] | 181 | #[test] |
@@ -192,7 +194,7 @@ macro_rules! test {} | |||
192 | fn test_string_highlighting() { | 194 | fn test_string_highlighting() { |
193 | // The format string detection is based on macro-expansion, | 195 | // The format string detection is based on macro-expansion, |
194 | // thus, we have to copy the macro definition from `std` | 196 | // thus, we have to copy the macro definition from `std` |
195 | let (analysis, file_id) = single_file( | 197 | check_highlighting( |
196 | r#" | 198 | r#" |
197 | macro_rules! println { | 199 | macro_rules! println { |
198 | ($($arg:tt)*) => ({ | 200 | ($($arg:tt)*) => ({ |
@@ -250,18 +252,14 @@ fn main() { | |||
250 | println!("{ничоси}", ничоси = 92); | 252 | println!("{ничоси}", ничоси = 92); |
251 | }"# | 253 | }"# |
252 | .trim(), | 254 | .trim(), |
255 | "crates/ra_ide/src/snapshots/highlight_strings.html", | ||
256 | false, | ||
253 | ); | 257 | ); |
254 | |||
255 | let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlight_strings.html"); | ||
256 | let actual_html = &analysis.highlight_as_html(file_id, false).unwrap(); | ||
257 | let expected_html = &read_text(&dst_file); | ||
258 | fs::write(dst_file, &actual_html).unwrap(); | ||
259 | assert_eq_text!(expected_html, actual_html); | ||
260 | } | 258 | } |
261 | 259 | ||
262 | #[test] | 260 | #[test] |
263 | fn test_unsafe_highlighting() { | 261 | fn test_unsafe_highlighting() { |
264 | let (analysis, file_id) = single_file( | 262 | check_highlighting( |
265 | r#" | 263 | r#" |
266 | unsafe fn unsafe_fn() {} | 264 | unsafe fn unsafe_fn() {} |
267 | 265 | ||
@@ -282,10 +280,7 @@ fn main() { | |||
282 | } | 280 | } |
283 | "# | 281 | "# |
284 | .trim(), | 282 | .trim(), |
283 | "crates/ra_ide/src/snapshots/highlight_unsafe.html", | ||
284 | false, | ||
285 | ); | 285 | ); |
286 | let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlight_unsafe.html"); | ||
287 | let actual_html = &analysis.highlight_as_html(file_id, false).unwrap(); | ||
288 | let expected_html = &read_text(&dst_file); | ||
289 | fs::write(dst_file, &actual_html).unwrap(); | ||
290 | assert_eq_text!(expected_html, actual_html); | ||
291 | } | 286 | } |
diff --git a/crates/ra_syntax/src/ast/tokens.rs b/crates/ra_syntax/src/ast/tokens.rs index 04b0a4480..56378385a 100644 --- a/crates/ra_syntax/src/ast/tokens.rs +++ b/crates/ra_syntax/src/ast/tokens.rs | |||
@@ -335,16 +335,26 @@ pub trait HasFormatSpecifier: AstToken { | |||
335 | } | 335 | } |
336 | c if c == '_' || c.is_alphabetic() => { | 336 | c if c == '_' || c.is_alphabetic() => { |
337 | read_identifier(&mut chars, &mut callback); | 337 | read_identifier(&mut chars, &mut callback); |
338 | if chars.peek().and_then(|next| next.1.as_ref().ok()).copied() | 338 | // can be either width (indicated by dollar sign, or type in which case |
339 | != Some('$') | 339 | // the next sign has to be `}`) |
340 | { | 340 | let next = |
341 | continue; | 341 | chars.peek().and_then(|next| next.1.as_ref().ok()).copied(); |
342 | } | 342 | match next { |
343 | skip_char_and_emit( | 343 | Some('$') => skip_char_and_emit( |
344 | &mut chars, | 344 | &mut chars, |
345 | FormatSpecifier::DollarSign, | 345 | FormatSpecifier::DollarSign, |
346 | &mut callback, | 346 | &mut callback, |
347 | ); | 347 | ), |
348 | Some('}') => { | ||
349 | skip_char_and_emit( | ||
350 | &mut chars, | ||
351 | FormatSpecifier::Close, | ||
352 | &mut callback, | ||
353 | ); | ||
354 | continue; | ||
355 | } | ||
356 | _ => continue, | ||
357 | }; | ||
348 | } | 358 | } |
349 | _ => {} | 359 | _ => {} |
350 | } | 360 | } |
@@ -416,12 +426,11 @@ pub trait HasFormatSpecifier: AstToken { | |||
416 | } | 426 | } |
417 | } | 427 | } |
418 | 428 | ||
419 | let mut cloned = chars.clone().take(2); | 429 | if let Some((_, Ok('}'))) = chars.peek() { |
420 | let first = cloned.next().and_then(|next| next.1.as_ref().ok()).copied(); | 430 | skip_char_and_emit(&mut chars, FormatSpecifier::Close, &mut callback); |
421 | if first != Some('}') { | 431 | } else { |
422 | continue; | 432 | continue; |
423 | } | 433 | } |
424 | skip_char_and_emit(&mut chars, FormatSpecifier::Close, &mut callback); | ||
425 | } | 434 | } |
426 | _ => { | 435 | _ => { |
427 | while let Some((_, Ok(next_char))) = chars.peek() { | 436 | while let Some((_, Ok(next_char))) = chars.peek() { |