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_syntax/src/ast/tokens.rs | 37 |
8 files changed, 57 insertions, 119 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_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() { |