Skip to content

Commit

Permalink
Merge branch 'rust-lang:master' into precise-capturing
Browse files Browse the repository at this point in the history
  • Loading branch information
winstxnhdw authored Jul 22, 2024
2 parents a1ebcca + 329adb5 commit d07bd22
Show file tree
Hide file tree
Showing 53 changed files with 1,623 additions and 453 deletions.
10 changes: 9 additions & 1 deletion crates/hir-def/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ pub mod scope;
#[cfg(test)]
mod tests;

use std::ops::Index;
use std::ops::{Deref, Index};

use base_db::CrateId;
use cfg::{CfgExpr, CfgOptions};
use hir_expand::{name::Name, InFile};
use la_arena::{Arena, ArenaMap};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use span::MacroFileId;
use syntax::{ast, AstPtr, SyntaxNodePtr};
use triomphe::Arc;
Expand Down Expand Up @@ -91,6 +92,7 @@ pub struct BodySourceMap {
label_map_back: ArenaMap<LabelId, LabelSource>,

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

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

pub fn patterns_for_binding(&self, binding: BindingId) -> &[PatId] {
self.binding_definitions.get(&binding).map_or(&[], Deref::deref)
}

pub fn node_label(&self, node: InFile<&ast::Label>) -> Option<LabelId> {
let src = node.map(AstPtr::new);
self.label_map.get(&src).cloned()
Expand Down Expand Up @@ -428,6 +434,7 @@ impl BodySourceMap {
expansions,
format_args_template_map,
diagnostics,
binding_definitions,
} = self;
format_args_template_map.shrink_to_fit();
expr_map.shrink_to_fit();
Expand All @@ -440,5 +447,6 @@ impl BodySourceMap {
pat_field_map_back.shrink_to_fit();
expansions.shrink_to_fit();
diagnostics.shrink_to_fit();
binding_definitions.shrink_to_fit();
}
}
57 changes: 43 additions & 14 deletions crates/hir-def/src/body/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
use std::mem;

use base_db::CrateId;
use either::Either;
use hir_expand::{
name::{AsName, Name},
ExpandError, InFile,
};
use intern::{sym, Interned, Symbol};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use span::AstIdMap;
use stdx::never;
use syntax::{
Expand Down Expand Up @@ -1436,15 +1436,14 @@ impl ExprCollector<'_> {
args: AstChildren<ast::Pat>,
has_leading_comma: bool,
binding_list: &mut BindingList,
) -> (Box<[PatId]>, Option<usize>) {
) -> (Box<[PatId]>, Option<u32>) {
let args: Vec<_> = args.map(|p| self.collect_pat_possibly_rest(p, binding_list)).collect();
// Find the location of the `..`, if there is one. Note that we do not
// consider the possibility of there being multiple `..` here.
let ellipsis = args.clone().position(|p| matches!(p, ast::Pat::RestPat(_)));
let ellipsis = args.iter().position(|p| p.is_right()).map(|it| it as u32);

// We want to skip the `..` pattern here, since we account for it above.
let mut args: Vec<_> = args
.filter(|p| !matches!(p, ast::Pat::RestPat(_)))
.map(|p| self.collect_pat(p, binding_list))
.collect();
let mut args: Vec<_> = args.into_iter().filter_map(Either::left).collect();
// if there is a leading comma, the user is most likely to type out a leading pattern
// so we insert a missing pattern at the beginning for IDE features
if has_leading_comma {
Expand All @@ -1454,6 +1453,41 @@ impl ExprCollector<'_> {
(args.into_boxed_slice(), ellipsis)
}

// `collect_pat` rejects `ast::Pat::RestPat`, but it should be handled in some cases that
// it is the macro expansion result of an arg sub-pattern in a slice or tuple pattern.
fn collect_pat_possibly_rest(
&mut self,
pat: ast::Pat,
binding_list: &mut BindingList,
) -> Either<PatId, ()> {
match &pat {
ast::Pat::RestPat(_) => Either::Right(()),
ast::Pat::MacroPat(mac) => match mac.macro_call() {
Some(call) => {
let macro_ptr = AstPtr::new(&call);
let src = self.expander.in_file(AstPtr::new(&pat));
let pat =
self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| {
if let Some(expanded_pat) = expanded_pat {
this.collect_pat_possibly_rest(expanded_pat, binding_list)
} else {
Either::Left(this.missing_pat())
}
});
if let Some(pat) = pat.left() {
self.source_map.pat_map.insert(src, pat);
}
pat
}
None => {
let ptr = AstPtr::new(&pat);
Either::Left(self.alloc_pat(Pat::Missing, ptr))
}
},
_ => Either::Left(self.collect_pat(pat, binding_list)),
}
}

// endregion: patterns

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

fn add_definition_to_binding(&mut self, binding_id: BindingId, pat_id: PatId) {
self.body.bindings[binding_id].definitions.push(pat_id);
self.source_map.binding_definitions.entry(binding_id).or_default().push(pat_id);
}

// region: labels
Expand Down Expand Up @@ -2024,12 +2058,7 @@ impl ExprCollector<'_> {
}

fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId {
let binding = self.body.bindings.alloc(Binding {
name,
mode,
definitions: SmallVec::new(),
problems: None,
});
let binding = self.body.bindings.alloc(Binding { name, mode, problems: None });
if let Some(owner) = self.current_binding_owner {
self.body.binding_owners.insert(binding, owner);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-def/src/body/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ impl Printer<'_> {
if i != 0 {
w!(self, ", ");
}
if *ellipsis == Some(i) {
if *ellipsis == Some(i as u32) {
w!(self, ".., ");
}
self.print_pat(*pat);
Expand Down Expand Up @@ -595,7 +595,7 @@ impl Printer<'_> {
if i != 0 {
w!(self, ", ");
}
if *ellipsis == Some(i) {
if *ellipsis == Some(i as u32) {
w!(self, ", ..");
}
self.print_pat(*arg);
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-def/src/body/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ fn foo() {
let function = find_function(&db, file_id.file_id());

let scopes = db.expr_scopes(function.into());
let (body, source_map) = db.body_with_source_map(function.into());
let (_, source_map) = db.body_with_source_map(function.into());

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

let resolved = scopes.resolve_name_in_scope(expr_scope, &name_ref.as_name()).unwrap();
let pat_src = source_map
.pat_syntax(*body.bindings[resolved.binding()].definitions.first().unwrap())
.pat_syntax(*source_map.binding_definitions[&resolved.binding()].first().unwrap())
.unwrap();

let local_name = pat_src.value.syntax_node_ptr().to_node(file.syntax());
Expand Down
1 change: 1 addition & 0 deletions crates/hir-def/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
// endregion:data

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

#[salsa::invoke(Body::body_query)]
Expand Down
6 changes: 2 additions & 4 deletions crates/hir-def/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use hir_expand::name::Name;
use intern::{Interned, Symbol};
use la_arena::{Idx, RawIdx};
use rustc_apfloat::ieee::{Half as f16, Quad as f128};
use smallvec::SmallVec;
use syntax::ast;

use crate::{
Expand Down Expand Up @@ -525,7 +524,6 @@ pub enum BindingProblems {
pub struct Binding {
pub name: Name,
pub mode: BindingAnnotation,
pub definitions: SmallVec<[PatId; 1]>,
pub problems: Option<BindingProblems>,
}

Expand All @@ -540,15 +538,15 @@ pub struct RecordFieldPat {
pub enum Pat {
Missing,
Wild,
Tuple { args: Box<[PatId]>, ellipsis: Option<usize> },
Tuple { args: Box<[PatId]>, ellipsis: Option<u32> },
Or(Box<[PatId]>),
Record { path: Option<Box<Path>>, args: Box<[RecordFieldPat]>, ellipsis: bool },
Range { start: Option<Box<LiteralOrConst>>, end: Option<Box<LiteralOrConst>> },
Slice { prefix: Box<[PatId]>, slice: Option<PatId>, suffix: Box<[PatId]> },
Path(Box<Path>),
Lit(ExprId),
Bind { id: BindingId, subpat: Option<PatId> },
TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<usize> },
TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<u32> },
Ref { pat: PatId, mutability: Mutability },
Box { inner: PatId },
ConstBlock(ExprId),
Expand Down
8 changes: 7 additions & 1 deletion crates/hir-def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use hir_expand::{
name::{AsName, Name},
proc_macro::CustomProcMacroExpander,
ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
MacroFileIdExt,
};
use intern::{sym, Interned};
use itertools::{izip, Itertools};
Expand Down Expand Up @@ -1397,7 +1398,12 @@ impl DefCollector<'_> {
// Then, fetch and process the item tree. This will reuse the expansion result from above.
let item_tree = self.db.file_item_tree(file_id);

let mod_dir = self.mod_dirs[&module_id].clone();
let mod_dir = if macro_call_id.as_macro_file().is_include_macro(self.db.upcast()) {
ModDir::root()
} else {
self.mod_dirs[&module_id].clone()
};

ModCollector {
def_collector: &mut *self,
macro_depth: depth,
Expand Down
64 changes: 64 additions & 0 deletions crates/hir-def/src/nameres/tests/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,70 @@ pub mod ip_address {
);
}

#[test]
fn include_many_mods() {
check(
r#"
//- /lib.rs
#[rustc_builtin_macro]
macro_rules! include { () => {} }
mod nested {
include!("out_dir/includes.rs");
mod different_company {
include!("out_dir/different_company/mod.rs");
}
mod util;
}
//- /nested/util.rs
pub struct Helper {}
//- /out_dir/includes.rs
pub mod company_name {
pub mod network {
pub mod v1;
}
}
//- /out_dir/company_name/network/v1.rs
pub struct IpAddress {}
//- /out_dir/different_company/mod.rs
pub mod network;
//- /out_dir/different_company/network.rs
pub struct Url {}
"#,
expect![[r#"
crate
nested: t
crate::nested
company_name: t
different_company: t
util: t
crate::nested::company_name
network: t
crate::nested::company_name::network
v1: t
crate::nested::company_name::network::v1
IpAddress: t
crate::nested::different_company
network: t
crate::nested::different_company::network
Url: t
crate::nested::util
Helper: t
"#]],
);
}

#[test]
fn macro_use_imports_all_macro_types() {
let db = TestDB::with_files(
Expand Down
14 changes: 0 additions & 14 deletions crates/hir-expand/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ pub trait ExpandDatabase: SourceDatabase {
/// file or a macro expansion.
#[salsa::transparent]
fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode;
#[salsa::transparent]
fn parse_or_expand_with_err(&self, file_id: HirFileId) -> ExpandResult<Parse<SyntaxNode>>;
/// Implementation for the macro case.
#[salsa::lru]
fn parse_macro_expansion(
Expand Down Expand Up @@ -328,18 +326,6 @@ fn parse_or_expand(db: &dyn ExpandDatabase, file_id: HirFileId) -> SyntaxNode {
}
}

fn parse_or_expand_with_err(
db: &dyn ExpandDatabase,
file_id: HirFileId,
) -> ExpandResult<Parse<SyntaxNode>> {
match file_id.repr() {
HirFileIdRepr::FileId(file_id) => ExpandResult::ok(db.parse(file_id).to_syntax()),
HirFileIdRepr::MacroFile(macro_file) => {
db.parse_macro_expansion(macro_file).map(|(it, _)| it)
}
}
}

// FIXME: We should verify that the parsed node is one of the many macro node variants we expect
// instead of having it be untyped
fn parse_macro_expansion(
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/diagnostics/match_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,15 @@ impl<'a> PatCtxt<'a> {
&mut self,
pats: &[PatId],
expected_len: usize,
ellipsis: Option<usize>,
ellipsis: Option<u32>,
) -> Vec<FieldPat> {
if pats.len() > expected_len {
self.errors.push(PatternError::ExtraFields);
return Vec::new();
}

pats.iter()
.enumerate_and_adjust(expected_len, ellipsis)
.enumerate_and_adjust(expected_len, ellipsis.map(|it| it as usize))
.map(|(i, &subpattern)| FieldPat {
field: LocalFieldId::from_raw((i as u32).into()),
pattern: self.lower_pattern(subpattern),
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/infer/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ impl InferenceContext<'_> {
match &self.body[pat] {
Pat::Missing | Pat::Wild => (),
Pat::Tuple { args, ellipsis } => {
let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
let field_count = match self.result[pat].kind(Interner) {
TyKind::Tuple(_, s) => s.len(Interner),
_ => return,
Expand Down Expand Up @@ -964,7 +964,7 @@ impl InferenceContext<'_> {
}
VariantId::StructId(s) => {
let vd = &*self.db.struct_data(s).variant_data;
let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
let fields = vd.fields().iter();
let it =
al.iter().zip(fields.clone()).chain(ar.iter().rev().zip(fields.rev()));
Expand Down
Loading

0 comments on commit d07bd22

Please sign in to comment.