mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 22:31:43 +00:00
Desugar builtin#format_args
This commit is contained in:
parent
abe8f1ece4
commit
e243a03da1
19 changed files with 783 additions and 243 deletions
|
@ -9,10 +9,7 @@ use chalk_ir::{
|
|||
};
|
||||
use hir_def::{
|
||||
data::adt::VariantData,
|
||||
hir::{
|
||||
format_args::FormatArgumentKind, Array, BinaryOp, BindingId, CaptureBy, Expr, ExprId, Pat,
|
||||
PatId, Statement, UnaryOp,
|
||||
},
|
||||
hir::{Array, BinaryOp, BindingId, CaptureBy, Expr, ExprId, Pat, PatId, Statement, UnaryOp},
|
||||
lang_item::LangItem,
|
||||
resolver::{resolver_for_expr, ResolveValueResult, ValueNs},
|
||||
DefWithBodyId, FieldId, HasModule, VariantId,
|
||||
|
@ -456,14 +453,6 @@ impl InferenceContext<'_> {
|
|||
fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) {
|
||||
match &self.body[tgt_expr] {
|
||||
Expr::OffsetOf(_) => (),
|
||||
Expr::FormatArgs(fa) => {
|
||||
self.walk_expr_without_adjust(fa.template_expr);
|
||||
fa.arguments
|
||||
.arguments
|
||||
.iter()
|
||||
.filter(|it| !matches!(it.kind, FormatArgumentKind::Captured(_)))
|
||||
.for_each(|it| self.walk_expr_without_adjust(it.expr));
|
||||
}
|
||||
Expr::InlineAsm(e) => self.walk_expr_without_adjust(e.e),
|
||||
Expr::If { condition, then_branch, else_branch } => {
|
||||
self.consume_expr(*condition);
|
||||
|
|
|
@ -9,8 +9,7 @@ use chalk_ir::{cast::Cast, fold::Shift, DebruijnIndex, Mutability, TyVariableKin
|
|||
use hir_def::{
|
||||
generics::TypeOrConstParamData,
|
||||
hir::{
|
||||
format_args::FormatArgumentKind, ArithOp, Array, BinaryOp, ClosureKind, Expr, ExprId,
|
||||
LabelId, Literal, Statement, UnaryOp,
|
||||
ArithOp, Array, BinaryOp, ClosureKind, Expr, ExprId, LabelId, Literal, Statement, UnaryOp,
|
||||
},
|
||||
lang_item::{LangItem, LangItemTarget},
|
||||
path::{GenericArg, GenericArgs},
|
||||
|
@ -849,25 +848,6 @@ impl InferenceContext<'_> {
|
|||
self.infer_expr_no_expect(it.e);
|
||||
self.result.standard_types.unit.clone()
|
||||
}
|
||||
Expr::FormatArgs(fa) => {
|
||||
fa.arguments
|
||||
.arguments
|
||||
.iter()
|
||||
.filter(|it| !matches!(it.kind, FormatArgumentKind::Captured(_)))
|
||||
.for_each(|it| _ = self.infer_expr_no_expect(it.expr));
|
||||
|
||||
match self
|
||||
.resolve_lang_item(LangItem::FormatArguments)
|
||||
.and_then(|it| it.as_struct())
|
||||
{
|
||||
Some(s) => {
|
||||
// NOTE: This struct has a lifetime parameter, but we don't currently emit
|
||||
// those to chalk
|
||||
TyKind::Adt(AdtId(s.into()), Substitution::empty(Interner)).intern(Interner)
|
||||
}
|
||||
None => self.err_ty(),
|
||||
}
|
||||
}
|
||||
};
|
||||
// use a new type variable if we got unknown here
|
||||
let ty = self.insert_type_vars_shallow(ty);
|
||||
|
|
|
@ -3,10 +3,7 @@
|
|||
|
||||
use chalk_ir::Mutability;
|
||||
use hir_def::{
|
||||
hir::{
|
||||
format_args::FormatArgumentKind, Array, BinaryOp, BindingAnnotation, Expr, ExprId, PatId,
|
||||
Statement, UnaryOp,
|
||||
},
|
||||
hir::{Array, BinaryOp, BindingAnnotation, Expr, ExprId, PatId, Statement, UnaryOp},
|
||||
lang_item::LangItem,
|
||||
};
|
||||
use hir_expand::name;
|
||||
|
@ -40,13 +37,6 @@ impl InferenceContext<'_> {
|
|||
Expr::Missing => (),
|
||||
Expr::InlineAsm(e) => self.infer_mut_expr_without_adjust(e.e, Mutability::Not),
|
||||
Expr::OffsetOf(_) => (),
|
||||
Expr::FormatArgs(fa) => {
|
||||
fa.arguments
|
||||
.arguments
|
||||
.iter()
|
||||
.filter(|it| !matches!(it.kind, FormatArgumentKind::Captured(_)))
|
||||
.for_each(|arg| self.infer_mut_expr_without_adjust(arg.expr, Mutability::Not));
|
||||
}
|
||||
&Expr::If { condition, then_branch, else_branch } => {
|
||||
self.infer_mut_expr(condition, Mutability::Not);
|
||||
self.infer_mut_expr(then_branch, Mutability::Not);
|
||||
|
|
|
@ -178,13 +178,30 @@ impl InferenceContext<'_> {
|
|||
remaining_index: usize,
|
||||
id: ExprOrPatId,
|
||||
) -> Option<(ValueNs, Substitution)> {
|
||||
assert!(remaining_index < path.segments().len());
|
||||
// there may be more intermediate segments between the resolved one and
|
||||
// the end. Only the last segment needs to be resolved to a value; from
|
||||
// the segments before that, we need to get either a type or a trait ref.
|
||||
|
||||
let resolved_segment = path.segments().get(remaining_index - 1).unwrap();
|
||||
let remaining_segments = path.segments().skip(remaining_index);
|
||||
let _d;
|
||||
let (resolved_segment, remaining_segments) = match path {
|
||||
Path::Normal { .. } => {
|
||||
assert!(remaining_index < path.segments().len());
|
||||
(
|
||||
path.segments().get(remaining_index - 1).unwrap(),
|
||||
path.segments().skip(remaining_index),
|
||||
)
|
||||
}
|
||||
Path::LangItem(_, seg) => (
|
||||
PathSegment {
|
||||
name: {
|
||||
_d = hir_expand::name::known::Unknown;
|
||||
&_d
|
||||
},
|
||||
args_and_bindings: None,
|
||||
},
|
||||
path.segments(),
|
||||
),
|
||||
};
|
||||
let is_before_last = remaining_segments.len() == 1;
|
||||
|
||||
match (def, is_before_last) {
|
||||
|
|
|
@ -376,9 +376,6 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
Expr::InlineAsm(_) => {
|
||||
not_supported!("builtin#asm")
|
||||
}
|
||||
Expr::FormatArgs(_) => {
|
||||
not_supported!("builtin#format_args")
|
||||
}
|
||||
Expr::Missing => {
|
||||
if let DefWithBodyId::FunctionId(f) = self.owner {
|
||||
let assoc = f.lookup(self.db.upcast());
|
||||
|
|
|
@ -3615,22 +3615,15 @@ fn main() {
|
|||
|
||||
#[test]
|
||||
fn builtin_format_args() {
|
||||
check_infer(
|
||||
check(
|
||||
r#"
|
||||
#[lang = "format_arguments"]
|
||||
pub struct Arguments<'a>;
|
||||
//- minicore: fmt
|
||||
fn main() {
|
||||
let are = "are";
|
||||
builtin#format_args("hello {} friends, we {are} {0}{last}", "fancy", last = "!");
|
||||
let count = 10;
|
||||
builtin#format_args("hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!");
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type: Arguments<'_>
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
65..175 '{ ...!"); }': ()
|
||||
75..78 'are': &str
|
||||
81..86 '"are"': &str
|
||||
92..172 'builti...= "!")': Arguments<'_>
|
||||
152..159 '"fancy"': &str
|
||||
168..171 '"!"': &str
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue