Skip to content

Commit 86cccc7

Browse files
committed
Auto merge of rust-lang#16048 - Veykril:concat-bytes-fix, r=Veykril
fix: Fix concat_bytes! expansion emitting an identifier Fixes rust-lang/rust-analyzer#16046 (note that this has always been broken)
2 parents 6bbb2ac + 71337f6 commit 86cccc7

File tree

12 files changed

+107
-49
lines changed

12 files changed

+107
-49
lines changed

crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -468,12 +468,12 @@ macro_rules! concat_bytes {}
468468
469469
fn main() { concat_bytes!(b'A', b"BC", [68, b'E', 70]); }
470470
"##,
471-
expect![[r##"
471+
expect![[r#"
472472
#[rustc_builtin_macro]
473473
macro_rules! concat_bytes {}
474474
475475
fn main() { [b'A', 66, 67, 68, b'E', 70]; }
476-
"##]],
476+
"#]],
477477
);
478478
}
479479

crates/hir-def/src/macro_expansion_tests/mbe/regression.rs

+26
Original file line numberDiff line numberDiff line change
@@ -1004,3 +1004,29 @@ fn main() {
10041004
"##]],
10051005
);
10061006
}
1007+
1008+
#[test]
1009+
fn eager_concat_bytes_panic() {
1010+
check(
1011+
r#"
1012+
#[rustc_builtin_macro]
1013+
#[macro_export]
1014+
macro_rules! concat_bytes {}
1015+
1016+
fn main() {
1017+
let x = concat_bytes!(2);
1018+
}
1019+
1020+
"#,
1021+
expect![[r#"
1022+
#[rustc_builtin_macro]
1023+
#[macro_export]
1024+
macro_rules! concat_bytes {}
1025+
1026+
fn main() {
1027+
let x = /* error: unexpected token in input */[];
1028+
}
1029+
1030+
"#]],
1031+
);
1032+
}

crates/hir-expand/src/builtin_fn_macro.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use base_db::{
66
};
77
use cfg::CfgExpr;
88
use either::Either;
9+
use itertools::Itertools;
910
use mbe::{parse_exprs_with_sep, parse_to_token_tree};
1011
use syntax::{
1112
ast::{self, AstToken},
@@ -491,8 +492,25 @@ fn concat_bytes_expand(
491492
}
492493
}
493494
}
494-
let ident = tt::Ident { text: bytes.join(", ").into(), span };
495-
ExpandResult { value: quote!(span =>[#ident]), err }
495+
let value = tt::Subtree {
496+
delimiter: tt::Delimiter { open: span, close: span, kind: tt::DelimiterKind::Bracket },
497+
token_trees: {
498+
Itertools::intersperse_with(
499+
bytes.into_iter().map(|it| {
500+
tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { text: it.into(), span }))
501+
}),
502+
|| {
503+
tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
504+
char: ',',
505+
spacing: tt::Spacing::Alone,
506+
span,
507+
}))
508+
},
509+
)
510+
.collect()
511+
},
512+
};
513+
ExpandResult { value, err }
496514
}
497515

498516
fn concat_bytes_expand_subtree(

crates/hir-ty/src/consteval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub fn intern_const_ref(
137137
ty: Ty,
138138
krate: CrateId,
139139
) -> Const {
140-
let layout = db.layout_of_ty(ty.clone(), Arc::new(TraitEnvironment::empty(krate)));
140+
let layout = db.layout_of_ty(ty.clone(), TraitEnvironment::empty(krate));
141141
let bytes = match value {
142142
LiteralConstRef::Int(i) => {
143143
// FIXME: We should handle failure of layout better.

crates/hir-ty/src/display.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,8 @@ fn render_const_scalar(
448448
) -> Result<(), HirDisplayError> {
449449
// FIXME: We need to get krate from the final callers of the hir display
450450
// infrastructure and have it here as a field on `f`.
451-
let trait_env = Arc::new(TraitEnvironment::empty(
452-
*f.db.crate_graph().crates_in_topological_order().last().unwrap(),
453-
));
451+
let trait_env =
452+
TraitEnvironment::empty(*f.db.crate_graph().crates_in_topological_order().last().unwrap());
454453
match ty.kind(Interner) {
455454
TyKind::Scalar(s) => match s {
456455
Scalar::Bool => write!(f, "{}", if b[0] == 0 { false } else { true }),

crates/hir-ty/src/infer/expr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use hir_def::{
1818
use hir_expand::name::{name, Name};
1919
use stdx::always;
2020
use syntax::ast::RangeOp;
21-
use triomphe::Arc;
2221

2322
use crate::{
2423
autoderef::{builtin_deref, deref_by_trait, Autoderef},
@@ -40,7 +39,8 @@ use crate::{
4039
traits::FnTrait,
4140
utils::{generics, Generics},
4241
Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, FnPointer, FnSig, FnSubst,
43-
Interner, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
42+
Interner, Rawness, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt,
43+
TyKind,
4444
};
4545

4646
use super::{
@@ -1291,7 +1291,7 @@ impl InferenceContext<'_> {
12911291
let g = self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr);
12921292
let prev_env = block_id.map(|block_id| {
12931293
let prev_env = self.table.trait_env.clone();
1294-
Arc::make_mut(&mut self.table.trait_env).block = Some(block_id);
1294+
TraitEnvironment::with_block(&mut self.table.trait_env, block_id);
12951295
prev_env
12961296
});
12971297

crates/hir-ty/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ pub type TyKind = chalk_ir::TyKind<Interner>;
122122
pub type TypeFlags = chalk_ir::TypeFlags;
123123
pub type DynTy = chalk_ir::DynTy<Interner>;
124124
pub type FnPointer = chalk_ir::FnPointer<Interner>;
125-
// pub type FnSubst = chalk_ir::FnSubst<Interner>;
125+
// pub type FnSubst = chalk_ir::FnSubst<Interner>; // a re-export so we don't lose the tuple constructor
126126
pub use chalk_ir::FnSubst;
127127
pub type ProjectionTy = chalk_ir::ProjectionTy<Interner>;
128128
pub type AliasTy = chalk_ir::AliasTy<Interner>;

crates/hir-ty/src/lower.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -1468,7 +1468,7 @@ pub(crate) fn trait_environment_for_body_query(
14681468
) -> Arc<TraitEnvironment> {
14691469
let Some(def) = def.as_generic_def_id() else {
14701470
let krate = def.module(db.upcast()).krate();
1471-
return Arc::new(TraitEnvironment::empty(krate));
1471+
return TraitEnvironment::empty(krate);
14721472
};
14731473
db.trait_environment(def)
14741474
}
@@ -1528,12 +1528,7 @@ pub(crate) fn trait_environment_query(
15281528

15291529
let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
15301530

1531-
Arc::new(TraitEnvironment {
1532-
krate,
1533-
block: None,
1534-
traits_from_clauses: traits_in_scope.into_boxed_slice(),
1535-
env,
1536-
})
1531+
TraitEnvironment::new(krate, None, traits_in_scope.into_boxed_slice(), env)
15371532
}
15381533

15391534
/// Resolve the where clause(s) of an item with generics.

crates/hir-ty/src/mir.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ pub use monomorphization::{
4040
use rustc_hash::FxHashMap;
4141
use smallvec::{smallvec, SmallVec};
4242
use stdx::{impl_from, never};
43-
use triomphe::Arc;
4443

4544
use super::consteval::{intern_const_scalar, try_const_usize};
4645

@@ -147,7 +146,7 @@ impl<V, T> ProjectionElem<V, T> {
147146
base = normalize(
148147
db,
149148
// FIXME: we should get this from caller
150-
Arc::new(TraitEnvironment::empty(krate)),
149+
TraitEnvironment::empty(krate),
151150
base,
152151
);
153152
}

crates/hir-ty/src/traits.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,32 @@ pub struct TraitEnvironment {
4848
pub krate: CrateId,
4949
pub block: Option<BlockId>,
5050
// FIXME make this a BTreeMap
51-
pub(crate) traits_from_clauses: Box<[(Ty, TraitId)]>,
51+
traits_from_clauses: Box<[(Ty, TraitId)]>,
5252
pub env: chalk_ir::Environment<Interner>,
5353
}
5454

5555
impl TraitEnvironment {
56-
pub fn empty(krate: CrateId) -> Self {
57-
TraitEnvironment {
56+
pub fn empty(krate: CrateId) -> Arc<Self> {
57+
Arc::new(TraitEnvironment {
5858
krate,
5959
block: None,
6060
traits_from_clauses: Box::default(),
6161
env: chalk_ir::Environment::new(Interner),
62-
}
62+
})
63+
}
64+
65+
pub fn new(
66+
krate: CrateId,
67+
block: Option<BlockId>,
68+
traits_from_clauses: Box<[(Ty, TraitId)]>,
69+
env: chalk_ir::Environment<Interner>,
70+
) -> Arc<Self> {
71+
Arc::new(TraitEnvironment { krate, block, traits_from_clauses, env })
72+
}
73+
74+
// pub fn with_block(self: &mut Arc<Self>, block: BlockId) {
75+
pub fn with_block(this: &mut Arc<Self>, block: BlockId) {
76+
Arc::make_mut(this).block = Some(block);
6377
}
6478

6579
pub fn traits_in_scope_from_clauses(&self, ty: Ty) -> impl Iterator<Item = TraitId> + '_ {

crates/hir/src/lib.rs

+18-21
Original file line numberDiff line numberDiff line change
@@ -3564,10 +3564,9 @@ impl TraitRef {
35643564
resolver: &Resolver,
35653565
trait_ref: hir_ty::TraitRef,
35663566
) -> TraitRef {
3567-
let env = resolver.generic_def().map_or_else(
3568-
|| Arc::new(TraitEnvironment::empty(resolver.krate())),
3569-
|d| db.trait_environment(d),
3570-
);
3567+
let env = resolver
3568+
.generic_def()
3569+
.map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d));
35713570
TraitRef { env, trait_ref }
35723571
}
35733572

@@ -3707,15 +3706,14 @@ impl Type {
37073706
resolver: &Resolver,
37083707
ty: Ty,
37093708
) -> Type {
3710-
let environment = resolver.generic_def().map_or_else(
3711-
|| Arc::new(TraitEnvironment::empty(resolver.krate())),
3712-
|d| db.trait_environment(d),
3713-
);
3709+
let environment = resolver
3710+
.generic_def()
3711+
.map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d));
37143712
Type { env: environment, ty }
37153713
}
37163714

37173715
pub(crate) fn new_for_crate(krate: CrateId, ty: Ty) -> Type {
3718-
Type { env: Arc::new(TraitEnvironment::empty(krate)), ty }
3716+
Type { env: TraitEnvironment::empty(krate), ty }
37193717
}
37203718

37213719
pub fn reference(inner: &Type, m: Mutability) -> Type {
@@ -3731,10 +3729,9 @@ impl Type {
37313729

37323730
fn new(db: &dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty) -> Type {
37333731
let resolver = lexical_env.resolver(db.upcast());
3734-
let environment = resolver.generic_def().map_or_else(
3735-
|| Arc::new(TraitEnvironment::empty(resolver.krate())),
3736-
|d| db.trait_environment(d),
3737-
);
3732+
let environment = resolver
3733+
.generic_def()
3734+
.map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d));
37383735
Type { env: environment, ty }
37393736
}
37403737

@@ -4304,10 +4301,10 @@ impl Type {
43044301
let canonical = hir_ty::replace_errors_with_variables(&self.ty);
43054302

43064303
let krate = scope.krate();
4307-
let environment = scope.resolver().generic_def().map_or_else(
4308-
|| Arc::new(TraitEnvironment::empty(krate.id)),
4309-
|d| db.trait_environment(d),
4310-
);
4304+
let environment = scope
4305+
.resolver()
4306+
.generic_def()
4307+
.map_or_else(|| TraitEnvironment::empty(krate.id), |d| db.trait_environment(d));
43114308

43124309
method_resolution::iterate_method_candidates_dyn(
43134310
&canonical,
@@ -4361,10 +4358,10 @@ impl Type {
43614358
let canonical = hir_ty::replace_errors_with_variables(&self.ty);
43624359

43634360
let krate = scope.krate();
4364-
let environment = scope.resolver().generic_def().map_or_else(
4365-
|| Arc::new(TraitEnvironment::empty(krate.id)),
4366-
|d| db.trait_environment(d),
4367-
);
4361+
let environment = scope
4362+
.resolver()
4363+
.generic_def()
4364+
.map_or_else(|| TraitEnvironment::empty(krate.id), |d| db.trait_environment(d));
43684365

43694366
method_resolution::iterate_path_candidates(
43704367
&canonical,

crates/mbe/src/token_map.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::hash::Hash;
44

5-
use stdx::itertools::Itertools;
5+
use stdx::{always, itertools::Itertools};
66
use syntax::{TextRange, TextSize};
77
use tt::Span;
88

@@ -21,13 +21,23 @@ impl<S: Span> SpanMap<S> {
2121
/// Finalizes the [`SpanMap`], shrinking its backing storage and validating that the offsets are
2222
/// in order.
2323
pub fn finish(&mut self) {
24-
assert!(self.spans.iter().tuple_windows().all(|(a, b)| a.0 < b.0));
24+
always!(
25+
self.spans.iter().tuple_windows().all(|(a, b)| a.0 < b.0),
26+
"spans are not in order"
27+
);
2528
self.spans.shrink_to_fit();
2629
}
2730

2831
/// Pushes a new span onto the [`SpanMap`].
2932
pub fn push(&mut self, offset: TextSize, span: S) {
30-
debug_assert!(self.spans.last().map_or(true, |&(last_offset, _)| last_offset < offset));
33+
if cfg!(debug_assertions) {
34+
if let Some(&(last_offset, _)) = self.spans.last() {
35+
assert!(
36+
last_offset < offset,
37+
"last_offset({last_offset:?}) must be smaller than offset({offset:?})"
38+
);
39+
}
40+
}
3141
self.spans.push((offset, span));
3242
}
3343

0 commit comments

Comments
 (0)