Merge commit '37f84c101b' into sync-from-ra

This commit is contained in:
Laurențiu Nicola 2023-07-17 16:49:15 +03:00
parent 6502421771
commit 4704881b64
311 changed files with 13700 additions and 9110 deletions

View file

@ -47,7 +47,7 @@ use hir_def::{
lang_item::LangItemTarget,
layout::{self, ReprOptions, TargetDataLayout},
macro_id_to_def_id,
nameres::{self, diagnostics::DefDiagnostic, ModuleOrigin},
nameres::{self, diagnostics::DefDiagnostic},
per_ns::PerNs,
resolver::{HasResolver, Resolver},
src::HasSource as _,
@ -62,7 +62,6 @@ use hir_ty::{
all_super_traits, autoderef,
consteval::{try_const_usize, unknown_const_as_generic, ConstEvalError, ConstExt},
diagnostics::BodyValidationDiagnostic,
display::HexifiedConst,
layout::{Layout as TyLayout, RustcEnumVariantIdx, TagEncoding},
method_resolution::{self, TyFingerprint},
mir::{self, interpret_mir},
@ -89,11 +88,11 @@ use crate::db::{DefDatabase, HirDatabase};
pub use crate::{
attrs::{HasAttrs, Namespace},
diagnostics::{
AnyDiagnostic, BreakOutsideOfLoop, ExpectedFunction, InactiveCode, IncoherentImpl,
IncorrectCase, InvalidDeriveTarget, MacroDefError, MacroError, MacroExpansionParseError,
MalformedDerive, MismatchedArgCount, MissingFields, MissingMatchArms, MissingUnsafe,
MovedOutOfRef, NeedMut, NoSuchField, PrivateAssocItem, PrivateField,
ReplaceFilterMapNextWithFindMap, TypeMismatch, TypedHole, UndeclaredLabel,
AnyDiagnostic, BreakOutsideOfLoop, CaseType, ExpectedFunction, InactiveCode,
IncoherentImpl, IncorrectCase, InvalidDeriveTarget, MacroDefError, MacroError,
MacroExpansionParseError, MalformedDerive, MismatchedArgCount, MissingFields,
MissingMatchArms, MissingUnsafe, MovedOutOfRef, NeedMut, NoSuchField, PrivateAssocItem,
PrivateField, ReplaceFilterMapNextWithFindMap, TypeMismatch, TypedHole, UndeclaredLabel,
UnimplementedBuiltinMacro, UnreachableLabel, UnresolvedExternCrate, UnresolvedField,
UnresolvedImport, UnresolvedMacroCall, UnresolvedMethodCall, UnresolvedModule,
UnresolvedProcMacro, UnusedMut,
@ -505,15 +504,10 @@ impl Module {
/// Finds nearest non-block ancestor `Module` (`self` included).
pub fn nearest_non_block_module(self, db: &dyn HirDatabase) -> Module {
let mut id = self.id;
loop {
let def_map = id.def_map(db.upcast());
let origin = def_map[id.local_id].origin;
if matches!(origin, ModuleOrigin::BlockExpr { .. }) {
id = id.containing_module(db.upcast()).expect("block without parent module")
} else {
return Module { id };
}
while id.is_block_module() {
id = id.containing_module(db.upcast()).expect("block without parent module");
}
Module { id }
}
pub fn path_to_root(self, db: &dyn HirDatabase) -> Vec<Module> {
@ -619,15 +613,21 @@ impl Module {
let inherent_impls = db.inherent_impls_in_crate(self.id.krate());
for impl_def in self.impl_defs(db) {
let loc = impl_def.id.lookup(db.upcast());
let tree = loc.id.item_tree(db.upcast());
let node = &tree[loc.id.value];
let file_id = loc.id.file_id();
if file_id.is_builtin_derive(db.upcast()) {
// these expansion come from us, diagnosing them is a waste of resources
// FIXME: Once we diagnose the inputs to builtin derives, we should at least extract those diagnostics somehow
continue;
}
for diag in db.impl_data_with_diagnostics(impl_def.id).1.iter() {
emit_def_diagnostic(db, acc, diag);
}
if inherent_impls.invalid_impls().contains(&impl_def.id) {
let loc = impl_def.id.lookup(db.upcast());
let tree = loc.id.item_tree(db.upcast());
let node = &tree[loc.id.value];
let file_id = loc.id.file_id();
let ast_id_map = db.ast_id_map(file_id);
acc.push(IncoherentImpl { impl_: ast_id_map.get(node.ast_id()), file_id }.into())
@ -698,16 +698,18 @@ impl Module {
fn emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, m: Macro) {
let id = macro_id_to_def_id(db.upcast(), m.id);
if let Err(e) = db.macro_def(id) {
let Some(ast) = id.ast_id().left() else {
never!("MacroDefError for proc-macro: {:?}", e);
if let hir_expand::db::TokenExpander::DeclarativeMacro(expander) = db.macro_expander(id) {
if let Some(e) = expander.mac.err() {
let Some(ast) = id.ast_id().left() else {
never!("declarative expander for non decl-macro: {:?}", e);
return;
};
emit_def_diagnostic_(
db,
acc,
&DefDiagnosticKind::MacroDefError { ast, message: e.to_string() },
);
emit_def_diagnostic_(
db,
acc,
&DefDiagnosticKind::MacroDefError { ast, message: e.to_string() },
);
}
}
}
@ -753,7 +755,7 @@ fn emit_def_diagnostic_(
let item = ast.to_node(db.upcast());
acc.push(
InactiveCode {
node: ast.with_value(AstPtr::new(&item).into()),
node: ast.with_value(SyntaxNodePtr::new(&item).into()),
cfg: cfg.clone(),
opts: opts.clone(),
}
@ -1234,7 +1236,7 @@ impl Adt {
pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
let subst = db.generic_defaults(self.into());
subst.iter().any(|ty| match ty.skip_binders().data(Interner) {
GenericArgData::Ty(x) => x.is_unknown(),
GenericArgData::Ty(it) => it.is_unknown(),
_ => false,
})
}
@ -1635,11 +1637,11 @@ impl DefWithBody {
for moof in &borrowck_result.moved_out_of_ref {
let span: InFile<SyntaxNodePtr> = match moof.span {
mir::MirSpan::ExprId(e) => match source_map.expr_syntax(e) {
Ok(s) => s.map(|x| x.into()),
Ok(s) => s.map(|it| it.into()),
Err(_) => continue,
},
mir::MirSpan::PatId(p) => match source_map.pat_syntax(p) {
Ok(s) => s.map(|x| match x {
Ok(s) => s.map(|it| match it {
Either::Left(e) => e.into(),
Either::Right(e) => e.into(),
}),
@ -1661,6 +1663,14 @@ impl DefWithBody {
let Some(&local) = mir_body.binding_locals.get(binding_id) else {
continue;
};
if body[binding_id]
.definitions
.iter()
.any(|&pat| source_map.pat_syntax(pat).is_err())
{
// Skip synthetic bindings
continue;
}
let need_mut = &mol[local];
let local = Local { parent: self.into(), binding_id };
match (need_mut, local.is_mut(db)) {
@ -1670,11 +1680,11 @@ impl DefWithBody {
for span in spans {
let span: InFile<SyntaxNodePtr> = match span {
mir::MirSpan::ExprId(e) => match source_map.expr_syntax(*e) {
Ok(s) => s.map(|x| x.into()),
Ok(s) => s.map(|it| it.into()),
Err(_) => continue,
},
mir::MirSpan::PatId(p) => match source_map.pat_syntax(*p) {
Ok(s) => s.map(|x| match x {
Ok(s) => s.map(|it| match it {
Either::Left(e) => e.into(),
Either::Right(e) => e.into(),
}),
@ -1687,7 +1697,7 @@ impl DefWithBody {
}
(mir::MutabilityReason::Not, true) => {
if !infer.mutated_bindings_in_closure.contains(&binding_id) {
let should_ignore = matches!(body[binding_id].name.as_str(), Some(x) if x.starts_with("_"));
let should_ignore = matches!(body[binding_id].name.as_str(), Some(it) if it.starts_with("_"));
if !should_ignore {
acc.push(UnusedMut { local }.into())
}
@ -1919,6 +1929,21 @@ impl Function {
db.function_data(self.id).has_async_kw()
}
/// Does this function have `#[test]` attribute?
pub fn is_test(self, db: &dyn HirDatabase) -> bool {
db.function_data(self.id).attrs.is_test()
}
/// Does this function have the ignore attribute?
pub fn is_ignore(self, db: &dyn HirDatabase) -> bool {
db.function_data(self.id).attrs.is_ignore()
}
/// Does this function have `#[bench]` attribute?
pub fn is_bench(self, db: &dyn HirDatabase) -> bool {
db.function_data(self.id).attrs.is_bench()
}
pub fn is_unsafe_to_call(self, db: &dyn HirDatabase) -> bool {
hir_ty::is_fn_unsafe_to_call(db, self.id)
}
@ -1962,7 +1987,7 @@ impl Function {
return r;
}
};
let (result, stdout, stderr) = interpret_mir(db, &body, false);
let (result, stdout, stderr) = interpret_mir(db, body, false);
let mut text = match result {
Ok(_) => "pass".to_string(),
Err(e) => {
@ -2132,7 +2157,27 @@ impl Const {
pub fn render_eval(self, db: &dyn HirDatabase) -> Result<String, ConstEvalError> {
let c = db.const_eval(self.id.into(), Substitution::empty(Interner))?;
let r = format!("{}", HexifiedConst(c).display(db));
let data = &c.data(Interner);
if let TyKind::Scalar(s) = data.ty.kind(Interner) {
if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) {
if let hir_ty::ConstValue::Concrete(c) = &data.value {
if let hir_ty::ConstScalar::Bytes(b, _) = &c.interned {
let value = u128::from_le_bytes(mir::pad16(b, false));
let value_signed =
i128::from_le_bytes(mir::pad16(b, matches!(s, Scalar::Int(_))));
if value >= 10 {
return Ok(format!("{} ({:#X})", value_signed, value));
} else {
return Ok(format!("{}", value_signed));
}
}
}
}
}
if let Ok(s) = mir::render_const_using_debug_impl(db, self.id, &c) {
return Ok(s);
}
let r = format!("{}", c.display(db));
return Ok(r);
}
}
@ -2270,7 +2315,7 @@ impl TypeAlias {
pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
let subst = db.generic_defaults(self.id.into());
subst.iter().any(|ty| match ty.skip_binders().data(Interner) {
GenericArgData::Ty(x) => x.is_unknown(),
GenericArgData::Ty(it) => it.is_unknown(),
_ => false,
})
}
@ -2660,8 +2705,8 @@ impl GenericDef {
let ty_params = generics.type_or_consts.iter().map(|(local_id, _)| {
let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: self.into(), local_id } };
match toc.split(db) {
Either::Left(x) => GenericParam::ConstParam(x),
Either::Right(x) => GenericParam::TypeParam(x),
Either::Left(it) => GenericParam::ConstParam(it),
Either::Right(it) => GenericParam::TypeParam(it),
}
});
self.lifetime_params(db)
@ -2709,14 +2754,14 @@ pub struct LocalSource {
impl LocalSource {
pub fn as_ident_pat(&self) -> Option<&ast::IdentPat> {
match &self.source.value {
Either::Left(x) => Some(x),
Either::Left(it) => Some(it),
Either::Right(_) => None,
}
}
pub fn into_ident_pat(self) -> Option<ast::IdentPat> {
match self.source.value {
Either::Left(x) => Some(x),
Either::Left(it) => Some(it),
Either::Right(_) => None,
}
}
@ -2738,7 +2783,7 @@ impl LocalSource {
}
pub fn syntax_ptr(self) -> InFile<SyntaxNodePtr> {
self.source.map(|x| SyntaxNodePtr::new(x.syntax()))
self.source.map(|it| SyntaxNodePtr::new(it.syntax()))
}
}
@ -2797,13 +2842,13 @@ impl Local {
Type::new(db, def, ty)
}
/// All definitions for this local. Example: `let (a$0, _) | (_, a$0) = x;`
/// All definitions for this local. Example: `let (a$0, _) | (_, a$0) = it;`
pub fn sources(self, db: &dyn HirDatabase) -> Vec<LocalSource> {
let (body, source_map) = db.body_with_source_map(self.parent);
self.sources_(db, &body, &source_map).collect()
}
/// The leftmost definition for this local. Example: `let (a$0, _) | (_, a) = x;`
/// The leftmost definition for this local. Example: `let (a$0, _) | (_, a) = it;`
pub fn primary_source(self, db: &dyn HirDatabase) -> LocalSource {
let (body, source_map) = db.body_with_source_map(self.parent);
let src = self.sources_(db, &body, &source_map).next().unwrap();
@ -3057,7 +3102,9 @@ impl TypeParam {
let subst = TyBuilder::placeholder_subst(db, self.id.parent());
let ty = ty.substitute(Interner, &subst);
match ty.data(Interner) {
GenericArgData::Ty(x) => Some(Type::new_with_resolver_inner(db, &resolver, x.clone())),
GenericArgData::Ty(it) => {
Some(Type::new_with_resolver_inner(db, &resolver, it.clone()))
}
_ => None,
}
}
@ -3096,7 +3143,7 @@ impl ConstParam {
pub fn name(self, db: &dyn HirDatabase) -> Name {
let params = db.generic_params(self.id.parent());
match params.type_or_consts[self.id.local_id()].name() {
Some(x) => x.clone(),
Some(it) => it.clone(),
None => {
never!();
Name::missing()
@ -3153,8 +3200,8 @@ impl TypeOrConstParam {
pub fn ty(self, db: &dyn HirDatabase) -> Type {
match self.split(db) {
Either::Left(x) => x.ty(db),
Either::Right(x) => x.ty(db),
Either::Left(it) => it.ty(db),
Either::Right(it) => it.ty(db),
}
}
}
@ -3260,9 +3307,9 @@ impl Impl {
self.id.lookup(db.upcast()).container.into()
}
pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
pub fn as_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
let src = self.source(db)?;
src.file_id.is_builtin_derive(db.upcast())
src.file_id.as_builtin_derive_attr_node(db.upcast())
}
}
@ -3652,9 +3699,9 @@ impl Type {
};
let parent_subst = TyBuilder::subst_for_def(db, trait_id, None)
.push(self.ty.clone())
.fill(|x| {
.fill(|it| {
// FIXME: this code is not covered in tests.
match x {
match it {
ParamKind::Type => {
GenericArgData::Ty(args.next().unwrap().ty.clone()).intern(Interner)
}
@ -3821,7 +3868,7 @@ impl Type {
pub fn as_array(&self, db: &dyn HirDatabase) -> Option<(Type, usize)> {
if let TyKind::Array(ty, len) = &self.ty.kind(Interner) {
try_const_usize(db, len).map(|x| (self.derived(ty.clone()), x as usize))
try_const_usize(db, len).map(|it| (self.derived(ty.clone()), it as usize))
} else {
None
}