mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Add support for lengths in array repeats, if they are literals
Now we will get the type of `[0u8; 4]`.
This commit is contained in:
parent
73023c0299
commit
e666589e63
4 changed files with 22 additions and 11 deletions
|
@ -1006,16 +1006,17 @@ impl From<ast::BinOp> for BinaryOp {
|
||||||
impl From<ast::LiteralKind> for Literal {
|
impl From<ast::LiteralKind> for Literal {
|
||||||
fn from(ast_lit_kind: ast::LiteralKind) -> Self {
|
fn from(ast_lit_kind: ast::LiteralKind) -> Self {
|
||||||
match ast_lit_kind {
|
match ast_lit_kind {
|
||||||
|
// FIXME: these should have actual values filled in, but unsure on perf impact
|
||||||
LiteralKind::IntNumber(lit) => {
|
LiteralKind::IntNumber(lit) => {
|
||||||
if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
|
if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
|
||||||
return Literal::Float(Default::default(), builtin);
|
return Literal::Float(Default::default(), builtin);
|
||||||
} else if let builtin @ Some(_) =
|
} else if let builtin @ Some(_) =
|
||||||
lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it))
|
lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it))
|
||||||
{
|
{
|
||||||
Literal::Int(Default::default(), builtin)
|
Literal::Int(lit.value().unwrap_or(0) as i128, builtin)
|
||||||
} else {
|
} else {
|
||||||
let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it));
|
let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it));
|
||||||
Literal::Uint(Default::default(), builtin)
|
Literal::Uint(lit.value().unwrap_or(0), builtin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LiteralKind::FloatNumber(lit) => {
|
LiteralKind::FloatNumber(lit) => {
|
||||||
|
|
|
@ -43,8 +43,8 @@ pub enum Literal {
|
||||||
ByteString(Vec<u8>),
|
ByteString(Vec<u8>),
|
||||||
Char(char),
|
Char(char),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
Int(u64, Option<BuiltinInt>),
|
Int(i128, Option<BuiltinInt>),
|
||||||
Uint(u64, Option<BuiltinUint>),
|
Uint(u128, Option<BuiltinUint>),
|
||||||
Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq
|
Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
//! Type inference for expressions.
|
//! Type inference for expressions.
|
||||||
|
|
||||||
use std::iter::{repeat, repeat_with};
|
use std::{
|
||||||
|
convert::TryInto,
|
||||||
|
iter::{repeat, repeat_with},
|
||||||
|
};
|
||||||
use std::{mem, sync::Arc};
|
use std::{mem, sync::Arc};
|
||||||
|
|
||||||
use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind};
|
use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
|
builtin_type::BuiltinUint,
|
||||||
expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
|
expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
|
||||||
path::{GenericArg, GenericArgs},
|
path::{GenericArg, GenericArgs},
|
||||||
resolver::resolver_for_expr,
|
resolver::resolver_for_expr,
|
||||||
|
@ -724,7 +728,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
for expr in items.iter() {
|
for expr in items.iter() {
|
||||||
self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
|
self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
|
||||||
}
|
}
|
||||||
Some(items.len())
|
Some(items.len() as u64)
|
||||||
}
|
}
|
||||||
Array::Repeat { initializer, repeat } => {
|
Array::Repeat { initializer, repeat } => {
|
||||||
self.infer_expr_coerce(
|
self.infer_expr_coerce(
|
||||||
|
@ -737,9 +741,15 @@ impl<'a> InferenceContext<'a> {
|
||||||
TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
|
TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
// FIXME: we don't know the length here because hir Exprs don't actually
|
|
||||||
// get the value out of the AST, even though it is there.
|
let repeat_expr = &self.body.exprs[*repeat];
|
||||||
None
|
match repeat_expr {
|
||||||
|
Expr::Literal(Literal::Uint(v, None))
|
||||||
|
| Expr::Literal(Literal::Uint(v, Some(BuiltinUint::Usize))) => {
|
||||||
|
(*v).try_into().ok()
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -747,7 +757,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
ty: TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
|
ty: TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
|
||||||
value: ConstValue::Concrete(chalk_ir::ConcreteConst {
|
value: ConstValue::Concrete(chalk_ir::ConcreteConst {
|
||||||
interned: len
|
interned: len
|
||||||
.map(|len| ConstScalar::Usize(len as u64))
|
.map(|len| ConstScalar::Usize(len))
|
||||||
.unwrap_or(ConstScalar::Unknown),
|
.unwrap_or(ConstScalar::Unknown),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
|
@ -93,7 +93,7 @@ fn coerce_places() {
|
||||||
340..345 '[arr]': [&[u8]; 1]
|
340..345 '[arr]': [&[u8]; 1]
|
||||||
341..344 'arr': &[u8; 1]
|
341..344 'arr': &[u8; 1]
|
||||||
355..356 'f': [&[u8]; 2]
|
355..356 'f': [&[u8]; 2]
|
||||||
370..378 '[arr; 2]': [&[u8]; _]
|
370..378 '[arr; 2]': [&[u8]; 2]
|
||||||
371..374 'arr': &[u8; 1]
|
371..374 'arr': &[u8; 1]
|
||||||
376..377 '2': usize
|
376..377 '2': usize
|
||||||
388..389 'g': (&[u8], &[u8])
|
388..389 'g': (&[u8], &[u8])
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue