Skip to content

Commit d07bd22

Browse files
authored
Merge branch 'rust-lang:master' into precise-capturing
2 parents a1ebcca + 329adb5 commit d07bd22

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1623
-453
lines changed

crates/hir-def/src/body.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ pub mod scope;
66
#[cfg(test)]
77
mod tests;
88

9-
use std::ops::Index;
9+
use std::ops::{Deref, Index};
1010

1111
use base_db::CrateId;
1212
use cfg::{CfgExpr, CfgOptions};
1313
use hir_expand::{name::Name, InFile};
1414
use la_arena::{Arena, ArenaMap};
1515
use rustc_hash::FxHashMap;
16+
use smallvec::SmallVec;
1617
use span::MacroFileId;
1718
use syntax::{ast, AstPtr, SyntaxNodePtr};
1819
use triomphe::Arc;
@@ -91,6 +92,7 @@ pub struct BodySourceMap {
9192
label_map_back: ArenaMap<LabelId, LabelSource>,
9293

9394
self_param: Option<InFile<AstPtr<ast::SelfParam>>>,
95+
binding_definitions: FxHashMap<BindingId, SmallVec<[PatId; 4]>>,
9496

9597
/// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
9698
/// Instead, we use id of expression (`92`) to identify the field.
@@ -377,6 +379,10 @@ impl BodySourceMap {
377379
self.label_map_back[label]
378380
}
379381

382+
pub fn patterns_for_binding(&self, binding: BindingId) -> &[PatId] {
383+
self.binding_definitions.get(&binding).map_or(&[], Deref::deref)
384+
}
385+
380386
pub fn node_label(&self, node: InFile<&ast::Label>) -> Option<LabelId> {
381387
let src = node.map(AstPtr::new);
382388
self.label_map.get(&src).cloned()
@@ -428,6 +434,7 @@ impl BodySourceMap {
428434
expansions,
429435
format_args_template_map,
430436
diagnostics,
437+
binding_definitions,
431438
} = self;
432439
format_args_template_map.shrink_to_fit();
433440
expr_map.shrink_to_fit();
@@ -440,5 +447,6 @@ impl BodySourceMap {
440447
pat_field_map_back.shrink_to_fit();
441448
expansions.shrink_to_fit();
442449
diagnostics.shrink_to_fit();
450+
binding_definitions.shrink_to_fit();
443451
}
444452
}

crates/hir-def/src/body/lower.rs

+43-14
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
use std::mem;
55

66
use base_db::CrateId;
7+
use either::Either;
78
use hir_expand::{
89
name::{AsName, Name},
910
ExpandError, InFile,
1011
};
1112
use intern::{sym, Interned, Symbol};
1213
use rustc_hash::FxHashMap;
13-
use smallvec::SmallVec;
1414
use span::AstIdMap;
1515
use stdx::never;
1616
use syntax::{
@@ -1436,15 +1436,14 @@ impl ExprCollector<'_> {
14361436
args: AstChildren<ast::Pat>,
14371437
has_leading_comma: bool,
14381438
binding_list: &mut BindingList,
1439-
) -> (Box<[PatId]>, Option<usize>) {
1439+
) -> (Box<[PatId]>, Option<u32>) {
1440+
let args: Vec<_> = args.map(|p| self.collect_pat_possibly_rest(p, binding_list)).collect();
14401441
// Find the location of the `..`, if there is one. Note that we do not
14411442
// consider the possibility of there being multiple `..` here.
1442-
let ellipsis = args.clone().position(|p| matches!(p, ast::Pat::RestPat(_)));
1443+
let ellipsis = args.iter().position(|p| p.is_right()).map(|it| it as u32);
1444+
14431445
// We want to skip the `..` pattern here, since we account for it above.
1444-
let mut args: Vec<_> = args
1445-
.filter(|p| !matches!(p, ast::Pat::RestPat(_)))
1446-
.map(|p| self.collect_pat(p, binding_list))
1447-
.collect();
1446+
let mut args: Vec<_> = args.into_iter().filter_map(Either::left).collect();
14481447
// if there is a leading comma, the user is most likely to type out a leading pattern
14491448
// so we insert a missing pattern at the beginning for IDE features
14501449
if has_leading_comma {
@@ -1454,6 +1453,41 @@ impl ExprCollector<'_> {
14541453
(args.into_boxed_slice(), ellipsis)
14551454
}
14561455

1456+
// `collect_pat` rejects `ast::Pat::RestPat`, but it should be handled in some cases that
1457+
// it is the macro expansion result of an arg sub-pattern in a slice or tuple pattern.
1458+
fn collect_pat_possibly_rest(
1459+
&mut self,
1460+
pat: ast::Pat,
1461+
binding_list: &mut BindingList,
1462+
) -> Either<PatId, ()> {
1463+
match &pat {
1464+
ast::Pat::RestPat(_) => Either::Right(()),
1465+
ast::Pat::MacroPat(mac) => match mac.macro_call() {
1466+
Some(call) => {
1467+
let macro_ptr = AstPtr::new(&call);
1468+
let src = self.expander.in_file(AstPtr::new(&pat));
1469+
let pat =
1470+
self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| {
1471+
if let Some(expanded_pat) = expanded_pat {
1472+
this.collect_pat_possibly_rest(expanded_pat, binding_list)
1473+
} else {
1474+
Either::Left(this.missing_pat())
1475+
}
1476+
});
1477+
if let Some(pat) = pat.left() {
1478+
self.source_map.pat_map.insert(src, pat);
1479+
}
1480+
pat
1481+
}
1482+
None => {
1483+
let ptr = AstPtr::new(&pat);
1484+
Either::Left(self.alloc_pat(Pat::Missing, ptr))
1485+
}
1486+
},
1487+
_ => Either::Left(self.collect_pat(pat, binding_list)),
1488+
}
1489+
}
1490+
14571491
// endregion: patterns
14581492

14591493
/// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when
@@ -1478,7 +1512,7 @@ impl ExprCollector<'_> {
14781512
}
14791513

14801514
fn add_definition_to_binding(&mut self, binding_id: BindingId, pat_id: PatId) {
1481-
self.body.bindings[binding_id].definitions.push(pat_id);
1515+
self.source_map.binding_definitions.entry(binding_id).or_default().push(pat_id);
14821516
}
14831517

14841518
// region: labels
@@ -2024,12 +2058,7 @@ impl ExprCollector<'_> {
20242058
}
20252059

20262060
fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId {
2027-
let binding = self.body.bindings.alloc(Binding {
2028-
name,
2029-
mode,
2030-
definitions: SmallVec::new(),
2031-
problems: None,
2032-
});
2061+
let binding = self.body.bindings.alloc(Binding { name, mode, problems: None });
20332062
if let Some(owner) = self.current_binding_owner {
20342063
self.body.binding_owners.insert(binding, owner);
20352064
}

crates/hir-def/src/body/pretty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ impl Printer<'_> {
517517
if i != 0 {
518518
w!(self, ", ");
519519
}
520-
if *ellipsis == Some(i) {
520+
if *ellipsis == Some(i as u32) {
521521
w!(self, ".., ");
522522
}
523523
self.print_pat(*pat);
@@ -595,7 +595,7 @@ impl Printer<'_> {
595595
if i != 0 {
596596
w!(self, ", ");
597597
}
598-
if *ellipsis == Some(i) {
598+
if *ellipsis == Some(i as u32) {
599599
w!(self, ", ..");
600600
}
601601
self.print_pat(*arg);

crates/hir-def/src/body/scope.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ fn foo() {
484484
let function = find_function(&db, file_id.file_id());
485485

486486
let scopes = db.expr_scopes(function.into());
487-
let (body, source_map) = db.body_with_source_map(function.into());
487+
let (_, source_map) = db.body_with_source_map(function.into());
488488

489489
let expr_scope = {
490490
let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap();
@@ -495,7 +495,7 @@ fn foo() {
495495

496496
let resolved = scopes.resolve_name_in_scope(expr_scope, &name_ref.as_name()).unwrap();
497497
let pat_src = source_map
498-
.pat_syntax(*body.bindings[resolved.binding()].definitions.first().unwrap())
498+
.pat_syntax(*source_map.binding_definitions[&resolved.binding()].first().unwrap())
499499
.unwrap();
500500

501501
let local_name = pat_src.value.syntax_node_ptr().to_node(file.syntax());

crates/hir-def/src/db.rs

+1
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
177177
// endregion:data
178178

179179
#[salsa::invoke(Body::body_with_source_map_query)]
180+
#[salsa::lru]
180181
fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
181182

182183
#[salsa::invoke(Body::body_query)]

crates/hir-def/src/hir.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use hir_expand::name::Name;
2121
use intern::{Interned, Symbol};
2222
use la_arena::{Idx, RawIdx};
2323
use rustc_apfloat::ieee::{Half as f16, Quad as f128};
24-
use smallvec::SmallVec;
2524
use syntax::ast;
2625

2726
use crate::{
@@ -525,7 +524,6 @@ pub enum BindingProblems {
525524
pub struct Binding {
526525
pub name: Name,
527526
pub mode: BindingAnnotation,
528-
pub definitions: SmallVec<[PatId; 1]>,
529527
pub problems: Option<BindingProblems>,
530528
}
531529

@@ -540,15 +538,15 @@ pub struct RecordFieldPat {
540538
pub enum Pat {
541539
Missing,
542540
Wild,
543-
Tuple { args: Box<[PatId]>, ellipsis: Option<usize> },
541+
Tuple { args: Box<[PatId]>, ellipsis: Option<u32> },
544542
Or(Box<[PatId]>),
545543
Record { path: Option<Box<Path>>, args: Box<[RecordFieldPat]>, ellipsis: bool },
546544
Range { start: Option<Box<LiteralOrConst>>, end: Option<Box<LiteralOrConst>> },
547545
Slice { prefix: Box<[PatId]>, slice: Option<PatId>, suffix: Box<[PatId]> },
548546
Path(Box<Path>),
549547
Lit(ExprId),
550548
Bind { id: BindingId, subpat: Option<PatId> },
551-
TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<usize> },
549+
TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<u32> },
552550
Ref { pat: PatId, mutability: Mutability },
553551
Box { inner: PatId },
554552
ConstBlock(ExprId),

crates/hir-def/src/nameres/collector.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use hir_expand::{
1616
name::{AsName, Name},
1717
proc_macro::CustomProcMacroExpander,
1818
ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
19+
MacroFileIdExt,
1920
};
2021
use intern::{sym, Interned};
2122
use itertools::{izip, Itertools};
@@ -1397,7 +1398,12 @@ impl DefCollector<'_> {
13971398
// Then, fetch and process the item tree. This will reuse the expansion result from above.
13981399
let item_tree = self.db.file_item_tree(file_id);
13991400

1400-
let mod_dir = self.mod_dirs[&module_id].clone();
1401+
let mod_dir = if macro_call_id.as_macro_file().is_include_macro(self.db.upcast()) {
1402+
ModDir::root()
1403+
} else {
1404+
self.mod_dirs[&module_id].clone()
1405+
};
1406+
14011407
ModCollector {
14021408
def_collector: &mut *self,
14031409
macro_depth: depth,

crates/hir-def/src/nameres/tests/macros.rs

+64
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,70 @@ pub mod ip_address {
13551355
);
13561356
}
13571357

1358+
#[test]
1359+
fn include_many_mods() {
1360+
check(
1361+
r#"
1362+
//- /lib.rs
1363+
#[rustc_builtin_macro]
1364+
macro_rules! include { () => {} }
1365+
1366+
mod nested {
1367+
include!("out_dir/includes.rs");
1368+
1369+
mod different_company {
1370+
include!("out_dir/different_company/mod.rs");
1371+
}
1372+
1373+
mod util;
1374+
}
1375+
1376+
//- /nested/util.rs
1377+
pub struct Helper {}
1378+
//- /out_dir/includes.rs
1379+
pub mod company_name {
1380+
pub mod network {
1381+
pub mod v1;
1382+
}
1383+
}
1384+
//- /out_dir/company_name/network/v1.rs
1385+
pub struct IpAddress {}
1386+
//- /out_dir/different_company/mod.rs
1387+
pub mod network;
1388+
//- /out_dir/different_company/network.rs
1389+
pub struct Url {}
1390+
1391+
"#,
1392+
expect![[r#"
1393+
crate
1394+
nested: t
1395+
1396+
crate::nested
1397+
company_name: t
1398+
different_company: t
1399+
util: t
1400+
1401+
crate::nested::company_name
1402+
network: t
1403+
1404+
crate::nested::company_name::network
1405+
v1: t
1406+
1407+
crate::nested::company_name::network::v1
1408+
IpAddress: t
1409+
1410+
crate::nested::different_company
1411+
network: t
1412+
1413+
crate::nested::different_company::network
1414+
Url: t
1415+
1416+
crate::nested::util
1417+
Helper: t
1418+
"#]],
1419+
);
1420+
}
1421+
13581422
#[test]
13591423
fn macro_use_imports_all_macro_types() {
13601424
let db = TestDB::with_files(

crates/hir-expand/src/db.rs

-14
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ pub trait ExpandDatabase: SourceDatabase {
6262
/// file or a macro expansion.
6363
#[salsa::transparent]
6464
fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode;
65-
#[salsa::transparent]
66-
fn parse_or_expand_with_err(&self, file_id: HirFileId) -> ExpandResult<Parse<SyntaxNode>>;
6765
/// Implementation for the macro case.
6866
#[salsa::lru]
6967
fn parse_macro_expansion(
@@ -328,18 +326,6 @@ fn parse_or_expand(db: &dyn ExpandDatabase, file_id: HirFileId) -> SyntaxNode {
328326
}
329327
}
330328

331-
fn parse_or_expand_with_err(
332-
db: &dyn ExpandDatabase,
333-
file_id: HirFileId,
334-
) -> ExpandResult<Parse<SyntaxNode>> {
335-
match file_id.repr() {
336-
HirFileIdRepr::FileId(file_id) => ExpandResult::ok(db.parse(file_id).to_syntax()),
337-
HirFileIdRepr::MacroFile(macro_file) => {
338-
db.parse_macro_expansion(macro_file).map(|(it, _)| it)
339-
}
340-
}
341-
}
342-
343329
// FIXME: We should verify that the parsed node is one of the many macro node variants we expect
344330
// instead of having it be untyped
345331
fn parse_macro_expansion(

crates/hir-ty/src/diagnostics/match_check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,15 @@ impl<'a> PatCtxt<'a> {
206206
&mut self,
207207
pats: &[PatId],
208208
expected_len: usize,
209-
ellipsis: Option<usize>,
209+
ellipsis: Option<u32>,
210210
) -> Vec<FieldPat> {
211211
if pats.len() > expected_len {
212212
self.errors.push(PatternError::ExtraFields);
213213
return Vec::new();
214214
}
215215

216216
pats.iter()
217-
.enumerate_and_adjust(expected_len, ellipsis)
217+
.enumerate_and_adjust(expected_len, ellipsis.map(|it| it as usize))
218218
.map(|(i, &subpattern)| FieldPat {
219219
field: LocalFieldId::from_raw((i as u32).into()),
220220
pattern: self.lower_pattern(subpattern),

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ impl InferenceContext<'_> {
889889
match &self.body[pat] {
890890
Pat::Missing | Pat::Wild => (),
891891
Pat::Tuple { args, ellipsis } => {
892-
let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
892+
let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
893893
let field_count = match self.result[pat].kind(Interner) {
894894
TyKind::Tuple(_, s) => s.len(Interner),
895895
_ => return,
@@ -964,7 +964,7 @@ impl InferenceContext<'_> {
964964
}
965965
VariantId::StructId(s) => {
966966
let vd = &*self.db.struct_data(s).variant_data;
967-
let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
967+
let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
968968
let fields = vd.fields().iter();
969969
let it =
970970
al.iter().zip(fields.clone()).chain(ar.iter().rev().zip(fields.rev()));

0 commit comments

Comments
 (0)