mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Lower const params with a bad id
This commit is contained in:
parent
68bdf609f3
commit
a481e004b0
@ -215,7 +215,7 @@ impl ChangeFixture {
|
|||||||
None,
|
None,
|
||||||
default_cfg,
|
default_cfg,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
Env::default(),
|
Env::new_for_test_fixture(),
|
||||||
false,
|
false,
|
||||||
CrateOrigin::Local { repo: None, name: None },
|
CrateOrigin::Local { repo: None, name: None },
|
||||||
default_target_data_layout
|
default_target_data_layout
|
||||||
@ -259,7 +259,7 @@ impl ChangeFixture {
|
|||||||
None,
|
None,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
Env::default(),
|
Env::new_for_test_fixture(),
|
||||||
false,
|
false,
|
||||||
CrateOrigin::Lang(LangCrateOrigin::Core),
|
CrateOrigin::Lang(LangCrateOrigin::Core),
|
||||||
target_layout.clone(),
|
target_layout.clone(),
|
||||||
@ -298,7 +298,7 @@ impl ChangeFixture {
|
|||||||
None,
|
None,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
Env::default(),
|
Env::new_for_test_fixture(),
|
||||||
true,
|
true,
|
||||||
CrateOrigin::Local { repo: None, name: None },
|
CrateOrigin::Local { repo: None, name: None },
|
||||||
target_layout,
|
target_layout,
|
||||||
|
@ -151,6 +151,12 @@ pub enum CrateOrigin {
|
|||||||
Lang(LangCrateOrigin),
|
Lang(LangCrateOrigin),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CrateOrigin {
|
||||||
|
pub fn is_local(&self) -> bool {
|
||||||
|
matches!(self, CrateOrigin::Local { .. })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum LangCrateOrigin {
|
pub enum LangCrateOrigin {
|
||||||
Alloc,
|
Alloc,
|
||||||
@ -333,6 +339,17 @@ pub struct Env {
|
|||||||
entries: FxHashMap<String, String>,
|
entries: FxHashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Env {
|
||||||
|
pub fn new_for_test_fixture() -> Self {
|
||||||
|
Env {
|
||||||
|
entries: FxHashMap::from_iter([(
|
||||||
|
String::from("__ra_is_test_fixture"),
|
||||||
|
String::from("__ra_is_test_fixture"),
|
||||||
|
)]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Dependency {
|
pub struct Dependency {
|
||||||
pub crate_id: CrateId,
|
pub crate_id: CrateId,
|
||||||
@ -456,6 +473,10 @@ impl CrateGraph {
|
|||||||
self.arena.iter().map(|(idx, _)| idx)
|
self.arena.iter().map(|(idx, _)| idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter_mut(&mut self) -> impl Iterator<Item = (CrateId, &mut CrateData)> + '_ {
|
||||||
|
self.arena.iter_mut()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all transitive dependencies of the given crate,
|
/// Returns an iterator over all transitive dependencies of the given crate,
|
||||||
/// including the crate itself.
|
/// including the crate itself.
|
||||||
pub fn transitive_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> {
|
pub fn transitive_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> {
|
||||||
|
@ -118,7 +118,7 @@ impl Body {
|
|||||||
let _p = profile::span("body_with_source_map_query");
|
let _p = profile::span("body_with_source_map_query");
|
||||||
let mut params = None;
|
let mut params = None;
|
||||||
|
|
||||||
let (file_id, module, body, is_async_fn) = {
|
let (file_id, body, is_async_fn) = {
|
||||||
match def {
|
match def {
|
||||||
DefWithBodyId::FunctionId(f) => {
|
DefWithBodyId::FunctionId(f) => {
|
||||||
let data = db.function_data(f);
|
let data = db.function_data(f);
|
||||||
@ -138,31 +138,29 @@ impl Body {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
(
|
(src.file_id, src.value.body().map(ast::Expr::from), data.has_async_kw())
|
||||||
src.file_id,
|
|
||||||
f.module(db),
|
|
||||||
src.value.body().map(ast::Expr::from),
|
|
||||||
data.has_async_kw(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
DefWithBodyId::ConstId(c) => {
|
DefWithBodyId::ConstId(c) => {
|
||||||
let c = c.lookup(db);
|
let c = c.lookup(db);
|
||||||
let src = c.source(db);
|
let src = c.source(db);
|
||||||
(src.file_id, c.module(db), src.value.body(), false)
|
(src.file_id, src.value.body(), false)
|
||||||
}
|
}
|
||||||
DefWithBodyId::StaticId(s) => {
|
DefWithBodyId::StaticId(s) => {
|
||||||
let s = s.lookup(db);
|
let s = s.lookup(db);
|
||||||
let src = s.source(db);
|
let src = s.source(db);
|
||||||
(src.file_id, s.module(db), src.value.body(), false)
|
(src.file_id, src.value.body(), false)
|
||||||
}
|
}
|
||||||
DefWithBodyId::VariantId(v) => {
|
DefWithBodyId::VariantId(v) => {
|
||||||
let e = v.parent.lookup(db);
|
|
||||||
let src = v.parent.child_source(db);
|
let src = v.parent.child_source(db);
|
||||||
let variant = &src.value[v.local_id];
|
let variant = &src.value[v.local_id];
|
||||||
(src.file_id, e.container, variant.expr(), false)
|
(src.file_id, variant.expr(), false)
|
||||||
|
}
|
||||||
|
DefWithBodyId::InTypeConstId(c) => {
|
||||||
|
(c.lookup(db).0.file_id, Some(c.source(db)), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let module = def.module(db);
|
||||||
let expander = Expander::new(db, file_id, module);
|
let expander = Expander::new(db, file_id, module);
|
||||||
let (mut body, source_map) =
|
let (mut body, source_map) =
|
||||||
Body::new(db, def, expander, params, body, module.krate, is_async_fn);
|
Body::new(db, def, expander, params, body, module.krate, is_async_fn);
|
||||||
|
@ -40,6 +40,7 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo
|
|||||||
};
|
};
|
||||||
format!("const {name} = ")
|
format!("const {name} = ")
|
||||||
}
|
}
|
||||||
|
DefWithBodyId::InTypeConstId(_) => format!("In type const = "),
|
||||||
DefWithBodyId::VariantId(it) => {
|
DefWithBodyId::VariantId(it) => {
|
||||||
let src = it.parent.child_source(db);
|
let src = it.parent.child_source(db);
|
||||||
let variant = &src.value[it.local_id];
|
let variant = &src.value[it.local_id];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Defines database & queries for name resolution.
|
//! Defines database & queries for name resolution.
|
||||||
use base_db::{salsa, CrateId, SourceDatabase, Upcast};
|
use base_db::{salsa, CrateId, SourceDatabase, Upcast};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{db::ExpandDatabase, HirFileId};
|
use hir_expand::{db::ExpandDatabase, AstId, HirFileId};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use la_arena::ArenaMap;
|
use la_arena::ArenaMap;
|
||||||
use syntax::{ast, AstPtr};
|
use syntax::{ast, AstPtr};
|
||||||
@ -24,9 +24,10 @@ use crate::{
|
|||||||
visibility::{self, Visibility},
|
visibility::{self, Visibility},
|
||||||
AnonymousConstId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId,
|
AnonymousConstId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId,
|
||||||
EnumLoc, ExternBlockId, ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc,
|
EnumLoc, ExternBlockId, ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc,
|
||||||
LocalEnumVariantId, LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId, MacroRulesLoc,
|
InTypeConstId, LocalEnumVariantId, LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId,
|
||||||
ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitAliasId,
|
MacroRulesLoc, ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc,
|
||||||
TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId,
|
TraitAliasId, TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, TypeOwnerId,
|
||||||
|
UnionId, UnionLoc, VariantId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[salsa::query_group(InternDatabaseStorage)]
|
#[salsa::query_group(InternDatabaseStorage)]
|
||||||
@ -63,6 +64,8 @@ pub trait InternDatabase: SourceDatabase {
|
|||||||
fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId;
|
fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId;
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_anonymous_const(&self, id: (DefWithBodyId, ExprId)) -> AnonymousConstId;
|
fn intern_anonymous_const(&self, id: (DefWithBodyId, ExprId)) -> AnonymousConstId;
|
||||||
|
#[salsa::interned]
|
||||||
|
fn intern_in_type_const(&self, id: (AstId<ast::Expr>, TypeOwnerId)) -> InTypeConstId;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[salsa::query_group(DefDatabaseStorage)]
|
#[salsa::query_group(DefDatabaseStorage)]
|
||||||
|
@ -155,7 +155,7 @@ impl Expander {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_path(&mut self, db: &dyn DefDatabase, path: ast::Path) -> Option<Path> {
|
pub(crate) fn parse_path(&mut self, db: &dyn DefDatabase, path: ast::Path) -> Option<Path> {
|
||||||
let ctx = LowerCtx::with_hygiene(db, &self.cfg_expander.hygiene);
|
let ctx = LowerCtx::new(db, &self.cfg_expander.hygiene, self.current_file_id);
|
||||||
Path::from_src(path, &ctx)
|
Path::from_src(path, &ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ pub enum TypeRef {
|
|||||||
Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability),
|
Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability),
|
||||||
// FIXME: for full const generics, the latter element (length) here is going to have to be an
|
// FIXME: for full const generics, the latter element (length) here is going to have to be an
|
||||||
// expression that is further lowered later in hir_ty.
|
// expression that is further lowered later in hir_ty.
|
||||||
Array(Box<TypeRef>, ConstRefOrPath),
|
Array(Box<TypeRef>, ConstRef),
|
||||||
Slice(Box<TypeRef>),
|
Slice(Box<TypeRef>),
|
||||||
/// A fn pointer. Last element of the vector is the return type.
|
/// A fn pointer. Last element of the vector is the return type.
|
||||||
Fn(Vec<(Option<Name>, TypeRef)>, bool /*varargs*/, bool /*is_unsafe*/),
|
Fn(Vec<(Option<Name>, TypeRef)>, bool /*varargs*/, bool /*is_unsafe*/),
|
||||||
@ -190,7 +190,7 @@ impl TypeRef {
|
|||||||
// `hir_def::body::lower` to lower this into an `Expr` and then evaluate it at the
|
// `hir_def::body::lower` to lower this into an `Expr` and then evaluate it at the
|
||||||
// `hir_ty` level, which would allow knowing the type of:
|
// `hir_ty` level, which would allow knowing the type of:
|
||||||
// let v: [u8; 2 + 2] = [0u8; 4];
|
// let v: [u8; 2 + 2] = [0u8; 4];
|
||||||
let len = ConstRefOrPath::from_expr_opt(inner.expr());
|
let len = ConstRef::from_expr_opt(ctx, inner.expr());
|
||||||
TypeRef::Array(Box::new(TypeRef::from_ast_opt(ctx, inner.ty())), len)
|
TypeRef::Array(Box::new(TypeRef::from_ast_opt(ctx, inner.ty())), len)
|
||||||
}
|
}
|
||||||
ast::Type::SliceType(inner) => {
|
ast::Type::SliceType(inner) => {
|
||||||
@ -380,73 +380,84 @@ impl TypeBound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum ConstRefOrPath {
|
pub enum ConstRef {
|
||||||
Scalar(ConstRef),
|
Scalar(LiteralConstRef),
|
||||||
Path(Name),
|
Path(Name),
|
||||||
|
Complex(AstId<ast::Expr>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstRefOrPath {
|
impl ConstRef {
|
||||||
pub(crate) fn from_expr_opt(expr: Option<ast::Expr>) -> Self {
|
pub(crate) fn from_expr_opt(lower_ctx: &LowerCtx<'_>, expr: Option<ast::Expr>) -> Self {
|
||||||
match expr {
|
match expr {
|
||||||
Some(x) => Self::from_expr(x),
|
Some(x) => {
|
||||||
None => Self::Scalar(ConstRef::Unknown),
|
let ast_id = lower_ctx.ast_id(&x);
|
||||||
|
Self::from_expr(x, ast_id)
|
||||||
|
}
|
||||||
|
None => Self::Scalar(LiteralConstRef::Unknown),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn display<'a>(&'a self, db: &'a dyn ExpandDatabase) -> impl fmt::Display + 'a {
|
pub fn display<'a>(&'a self, db: &'a dyn ExpandDatabase) -> impl fmt::Display + 'a {
|
||||||
struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRefOrPath);
|
struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRef);
|
||||||
impl fmt::Display for Display<'_> {
|
impl fmt::Display for Display<'_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self.1 {
|
match self.1 {
|
||||||
ConstRefOrPath::Scalar(s) => s.fmt(f),
|
ConstRef::Scalar(s) => s.fmt(f),
|
||||||
ConstRefOrPath::Path(n) => n.display(self.0).fmt(f),
|
ConstRef::Path(n) => n.display(self.0).fmt(f),
|
||||||
|
ConstRef::Complex(_) => f.write_str("{const}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Display(db, self)
|
Display(db, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: as per the comments on `TypeRef::Array`, this evaluation should not happen at this
|
// We special case literals and single identifiers, to speed up things.
|
||||||
// parse stage.
|
fn from_expr(expr: ast::Expr, ast_id: Option<AstId<ast::Expr>>) -> Self {
|
||||||
fn from_expr(expr: ast::Expr) -> Self {
|
fn is_path_ident(p: &ast::PathExpr) -> bool {
|
||||||
|
let Some(path) = p.path() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if path.coloncolon_token().is_some() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if let Some(s) = path.segment() {
|
||||||
|
if s.coloncolon_token().is_some() || s.generic_arg_list().is_some() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
match expr {
|
match expr {
|
||||||
ast::Expr::PathExpr(p) => {
|
ast::Expr::PathExpr(p) if is_path_ident(&p) => {
|
||||||
match p.path().and_then(|x| x.segment()).and_then(|x| x.name_ref()) {
|
match p.path().and_then(|x| x.segment()).and_then(|x| x.name_ref()) {
|
||||||
Some(x) => Self::Path(x.as_name()),
|
Some(x) => Self::Path(x.as_name()),
|
||||||
None => Self::Scalar(ConstRef::Unknown),
|
None => Self::Scalar(LiteralConstRef::Unknown),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Expr::PrefixExpr(prefix_expr) => match prefix_expr.op_kind() {
|
|
||||||
Some(ast::UnaryOp::Neg) => {
|
|
||||||
let unsigned = Self::from_expr_opt(prefix_expr.expr());
|
|
||||||
// Add sign
|
|
||||||
match unsigned {
|
|
||||||
Self::Scalar(ConstRef::UInt(num)) => {
|
|
||||||
Self::Scalar(ConstRef::Int(-(num as i128)))
|
|
||||||
}
|
|
||||||
other => other,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => Self::from_expr_opt(prefix_expr.expr()),
|
|
||||||
},
|
|
||||||
ast::Expr::Literal(literal) => Self::Scalar(match literal.kind() {
|
ast::Expr::Literal(literal) => Self::Scalar(match literal.kind() {
|
||||||
ast::LiteralKind::IntNumber(num) => {
|
ast::LiteralKind::IntNumber(num) => {
|
||||||
num.value().map(ConstRef::UInt).unwrap_or(ConstRef::Unknown)
|
num.value().map(LiteralConstRef::UInt).unwrap_or(LiteralConstRef::Unknown)
|
||||||
}
|
}
|
||||||
ast::LiteralKind::Char(c) => {
|
ast::LiteralKind::Char(c) => {
|
||||||
c.value().map(ConstRef::Char).unwrap_or(ConstRef::Unknown)
|
c.value().map(LiteralConstRef::Char).unwrap_or(LiteralConstRef::Unknown)
|
||||||
}
|
}
|
||||||
ast::LiteralKind::Bool(f) => ConstRef::Bool(f),
|
ast::LiteralKind::Bool(f) => LiteralConstRef::Bool(f),
|
||||||
_ => ConstRef::Unknown,
|
_ => LiteralConstRef::Unknown,
|
||||||
}),
|
}),
|
||||||
_ => Self::Scalar(ConstRef::Unknown),
|
_ => {
|
||||||
|
if let Some(ast_id) = ast_id {
|
||||||
|
Self::Complex(ast_id)
|
||||||
|
} else {
|
||||||
|
Self::Scalar(LiteralConstRef::Unknown)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A concrete constant value
|
/// A literal constant value
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum ConstRef {
|
pub enum LiteralConstRef {
|
||||||
Int(i128),
|
Int(i128),
|
||||||
UInt(u128),
|
UInt(u128),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
@ -460,18 +471,20 @@ pub enum ConstRef {
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstRef {
|
impl LiteralConstRef {
|
||||||
pub fn builtin_type(&self) -> BuiltinType {
|
pub fn builtin_type(&self) -> BuiltinType {
|
||||||
match self {
|
match self {
|
||||||
ConstRef::UInt(_) | ConstRef::Unknown => BuiltinType::Uint(BuiltinUint::U128),
|
LiteralConstRef::UInt(_) | LiteralConstRef::Unknown => {
|
||||||
ConstRef::Int(_) => BuiltinType::Int(BuiltinInt::I128),
|
BuiltinType::Uint(BuiltinUint::U128)
|
||||||
ConstRef::Char(_) => BuiltinType::Char,
|
}
|
||||||
ConstRef::Bool(_) => BuiltinType::Bool,
|
LiteralConstRef::Int(_) => BuiltinType::Int(BuiltinInt::I128),
|
||||||
|
LiteralConstRef::Char(_) => BuiltinType::Char,
|
||||||
|
LiteralConstRef::Bool(_) => BuiltinType::Bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Literal> for ConstRef {
|
impl From<Literal> for LiteralConstRef {
|
||||||
fn from(literal: Literal) -> Self {
|
fn from(literal: Literal) -> Self {
|
||||||
match literal {
|
match literal {
|
||||||
Literal::Char(c) => Self::Char(c),
|
Literal::Char(c) => Self::Char(c),
|
||||||
@ -483,14 +496,14 @@ impl From<Literal> for ConstRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for ConstRef {
|
impl std::fmt::Display for LiteralConstRef {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
match self {
|
match self {
|
||||||
ConstRef::Int(num) => num.fmt(f),
|
LiteralConstRef::Int(num) => num.fmt(f),
|
||||||
ConstRef::UInt(num) => num.fmt(f),
|
LiteralConstRef::UInt(num) => num.fmt(f),
|
||||||
ConstRef::Bool(flag) => flag.fmt(f),
|
LiteralConstRef::Bool(flag) => flag.fmt(f),
|
||||||
ConstRef::Char(c) => write!(f, "'{c}'"),
|
LiteralConstRef::Char(c) => write!(f, "'{c}'"),
|
||||||
ConstRef::Unknown => f.write_char('_'),
|
LiteralConstRef::Unknown => f.write_char('_'),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,8 @@ use crate::{
|
|||||||
builtin_type::BuiltinType,
|
builtin_type::BuiltinType,
|
||||||
data::adt::VariantData,
|
data::adt::VariantData,
|
||||||
item_tree::{
|
item_tree::{
|
||||||
Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, ModItem,
|
Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, Static,
|
||||||
Static, Struct, Trait, TraitAlias, TypeAlias, Union,
|
Struct, Trait, TraitAlias, TypeAlias, Union,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -476,20 +476,55 @@ impl_from!(
|
|||||||
for ModuleDefId
|
for ModuleDefId
|
||||||
);
|
);
|
||||||
|
|
||||||
// FIXME: make this a DefWithBodyId
|
/// Id of the anonymous const block expression and patterns. This is very similar to `ClosureId` and
|
||||||
|
/// shouldn't be a `DefWithBodyId` since its type inference is dependent on its parent.
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||||
pub struct AnonymousConstId(InternId);
|
pub struct AnonymousConstId(InternId);
|
||||||
impl_intern_key!(AnonymousConstId);
|
impl_intern_key!(AnonymousConstId);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||||
|
pub enum TypeOwnerId {
|
||||||
|
ModuleId(ModuleId),
|
||||||
|
DefWithBodyId(DefWithBodyId),
|
||||||
|
GenericDefId(GenericDefId),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeOwnerId {
|
||||||
|
fn as_generic_def_id(self) -> Option<GenericDefId> {
|
||||||
|
match self {
|
||||||
|
TypeOwnerId::ModuleId(_) => None,
|
||||||
|
TypeOwnerId::DefWithBodyId(x) => x.as_generic_def_id(),
|
||||||
|
TypeOwnerId::GenericDefId(x) => Some(x),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_from!(ModuleId, DefWithBodyId(FunctionId, ConstId, StaticId), GenericDefId(AdtId, TypeAliasId, ImplId) for TypeOwnerId);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||||
|
pub struct InTypeConstId(InternId);
|
||||||
|
type InTypeConstLoc = (AstId<ast::Expr>, TypeOwnerId);
|
||||||
|
impl_intern!(InTypeConstId, InTypeConstLoc, intern_in_type_const, lookup_intern_in_type_const);
|
||||||
|
|
||||||
|
impl InTypeConstId {
|
||||||
|
pub fn source(&self, db: &dyn db::DefDatabase) -> ast::Expr {
|
||||||
|
let src = self.lookup(db).0;
|
||||||
|
let file_id = src.file_id;
|
||||||
|
let root = &db.parse_or_expand(file_id);
|
||||||
|
db.ast_id_map(file_id).get(src.value).to_node(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A constant, which might appears as a const item, an annonymous const block in expressions
|
/// A constant, which might appears as a const item, an annonymous const block in expressions
|
||||||
/// or patterns, or as a constant in types with const generics.
|
/// or patterns, or as a constant in types with const generics.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum GeneralConstId {
|
pub enum GeneralConstId {
|
||||||
ConstId(ConstId),
|
ConstId(ConstId),
|
||||||
AnonymousConstId(AnonymousConstId),
|
AnonymousConstId(AnonymousConstId),
|
||||||
|
InTypeConstId(InTypeConstId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_from!(ConstId, AnonymousConstId for GeneralConstId);
|
impl_from!(ConstId, AnonymousConstId, InTypeConstId for GeneralConstId);
|
||||||
|
|
||||||
impl GeneralConstId {
|
impl GeneralConstId {
|
||||||
pub fn generic_def(self, db: &dyn db::DefDatabase) -> Option<GenericDefId> {
|
pub fn generic_def(self, db: &dyn db::DefDatabase) -> Option<GenericDefId> {
|
||||||
@ -499,6 +534,10 @@ impl GeneralConstId {
|
|||||||
let (parent, _) = db.lookup_intern_anonymous_const(x);
|
let (parent, _) = db.lookup_intern_anonymous_const(x);
|
||||||
parent.as_generic_def_id()
|
parent.as_generic_def_id()
|
||||||
}
|
}
|
||||||
|
GeneralConstId::InTypeConstId(x) => {
|
||||||
|
let (_, parent) = x.lookup(db);
|
||||||
|
parent.as_generic_def_id()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,6 +551,7 @@ impl GeneralConstId {
|
|||||||
.unwrap_or("_")
|
.unwrap_or("_")
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
GeneralConstId::AnonymousConstId(id) => format!("{{anonymous const {id:?}}}"),
|
GeneralConstId::AnonymousConstId(id) => format!("{{anonymous const {id:?}}}"),
|
||||||
|
GeneralConstId::InTypeConstId(id) => format!("{{in type const {id:?}}}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -522,10 +562,11 @@ pub enum DefWithBodyId {
|
|||||||
FunctionId(FunctionId),
|
FunctionId(FunctionId),
|
||||||
StaticId(StaticId),
|
StaticId(StaticId),
|
||||||
ConstId(ConstId),
|
ConstId(ConstId),
|
||||||
|
InTypeConstId(InTypeConstId),
|
||||||
VariantId(EnumVariantId),
|
VariantId(EnumVariantId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
|
impl_from!(FunctionId, ConstId, StaticId, InTypeConstId for DefWithBodyId);
|
||||||
|
|
||||||
impl From<EnumVariantId> for DefWithBodyId {
|
impl From<EnumVariantId> for DefWithBodyId {
|
||||||
fn from(id: EnumVariantId) -> Self {
|
fn from(id: EnumVariantId) -> Self {
|
||||||
@ -540,6 +581,9 @@ impl DefWithBodyId {
|
|||||||
DefWithBodyId::StaticId(_) => None,
|
DefWithBodyId::StaticId(_) => None,
|
||||||
DefWithBodyId::ConstId(c) => Some(c.into()),
|
DefWithBodyId::ConstId(c) => Some(c.into()),
|
||||||
DefWithBodyId::VariantId(c) => Some(c.into()),
|
DefWithBodyId::VariantId(c) => Some(c.into()),
|
||||||
|
// FIXME: stable rust doesn't allow generics in constants, but we should
|
||||||
|
// use `TypeOwnerId::as_generic_def_id` when it does.
|
||||||
|
DefWithBodyId::InTypeConstId(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -734,6 +778,16 @@ impl HasModule for MacroId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasModule for TypeOwnerId {
|
||||||
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
||||||
|
match self {
|
||||||
|
TypeOwnerId::ModuleId(x) => *x,
|
||||||
|
TypeOwnerId::DefWithBodyId(x) => x.module(db),
|
||||||
|
TypeOwnerId::GenericDefId(x) => x.module(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HasModule for DefWithBodyId {
|
impl HasModule for DefWithBodyId {
|
||||||
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
||||||
match self {
|
match self {
|
||||||
@ -741,17 +795,7 @@ impl HasModule for DefWithBodyId {
|
|||||||
DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
|
DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
|
||||||
DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
|
DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
|
||||||
DefWithBodyId::VariantId(it) => it.parent.lookup(db).container,
|
DefWithBodyId::VariantId(it) => it.parent.lookup(db).container,
|
||||||
}
|
DefWithBodyId::InTypeConstId(it) => it.lookup(db).1.module(db),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DefWithBodyId {
|
|
||||||
pub fn as_mod_item(self, db: &dyn db::DefDatabase) -> ModItem {
|
|
||||||
match self {
|
|
||||||
DefWithBodyId::FunctionId(it) => it.lookup(db).id.value.into(),
|
|
||||||
DefWithBodyId::StaticId(it) => it.lookup(db).id.value.into(),
|
|
||||||
DefWithBodyId::ConstId(it) => it.lookup(db).id.value.into(),
|
|
||||||
DefWithBodyId::VariantId(it) => it.parent.lookup(db).id.value.into(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use std::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
lang_item::LangItemTarget,
|
lang_item::LangItemTarget,
|
||||||
lower::LowerCtx,
|
lower::LowerCtx,
|
||||||
type_ref::{ConstRefOrPath, LifetimeRef, TypeBound, TypeRef},
|
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
@ -90,7 +90,7 @@ pub struct AssociatedTypeBinding {
|
|||||||
pub enum GenericArg {
|
pub enum GenericArg {
|
||||||
Type(TypeRef),
|
Type(TypeRef),
|
||||||
Lifetime(LifetimeRef),
|
Lifetime(LifetimeRef),
|
||||||
Const(ConstRefOrPath),
|
Const(ConstRef),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Path {
|
impl Path {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use crate::{lower::LowerCtx, type_ref::ConstRefOrPath};
|
use crate::{lower::LowerCtx, type_ref::ConstRef};
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::name::{name, AsName};
|
use hir_expand::name::{name, AsName};
|
||||||
@ -217,7 +217,7 @@ pub(super) fn lower_generic_args(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::GenericArg::ConstArg(arg) => {
|
ast::GenericArg::ConstArg(arg) => {
|
||||||
let arg = ConstRefOrPath::from_expr_opt(arg.expr());
|
let arg = ConstRef::from_expr_opt(lower_ctx, arg.expr());
|
||||||
args.push(GenericArg::Const(arg))
|
args.push(GenericArg::Const(arg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@ use crate::{
|
|||||||
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId,
|
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId,
|
||||||
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
||||||
LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId,
|
LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId,
|
||||||
StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId,
|
StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId,
|
||||||
VariantId,
|
TypeParamId, VariantId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -1009,6 +1009,16 @@ impl HasResolver for ExternBlockId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasResolver for TypeOwnerId {
|
||||||
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
|
match self {
|
||||||
|
TypeOwnerId::ModuleId(it) => it.resolver(db),
|
||||||
|
TypeOwnerId::DefWithBodyId(it) => it.resolver(db),
|
||||||
|
TypeOwnerId::GenericDefId(it) => it.resolver(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HasResolver for DefWithBodyId {
|
impl HasResolver for DefWithBodyId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
match self {
|
match self {
|
||||||
@ -1016,6 +1026,7 @@ impl HasResolver for DefWithBodyId {
|
|||||||
DefWithBodyId::FunctionId(f) => f.resolver(db),
|
DefWithBodyId::FunctionId(f) => f.resolver(db),
|
||||||
DefWithBodyId::StaticId(s) => s.resolver(db),
|
DefWithBodyId::StaticId(s) => s.resolver(db),
|
||||||
DefWithBodyId::VariantId(v) => v.parent.resolver(db),
|
DefWithBodyId::VariantId(v) => v.parent.resolver(db),
|
||||||
|
DefWithBodyId::InTypeConstId(c) => c.lookup(db).1.resolver(db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ impl AstIdMap {
|
|||||||
|| ast::Variant::can_cast(kind)
|
|| ast::Variant::can_cast(kind)
|
||||||
|| ast::RecordField::can_cast(kind)
|
|| ast::RecordField::can_cast(kind)
|
||||||
|| ast::TupleField::can_cast(kind)
|
|| ast::TupleField::can_cast(kind)
|
||||||
|
|| ast::Expr::can_cast(kind)
|
||||||
{
|
{
|
||||||
res.alloc(&it);
|
res.alloc(&it);
|
||||||
true
|
true
|
||||||
|
@ -497,7 +497,7 @@ pub(crate) fn associated_ty_data_query(
|
|||||||
let generic_params = generics(db.upcast(), type_alias.into());
|
let generic_params = generics(db.upcast(), type_alias.into());
|
||||||
// let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
|
// let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
|
||||||
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
|
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
|
||||||
let ctx = crate::TyLoweringContext::new(db, &resolver)
|
let ctx = crate::TyLoweringContext::new(db, &resolver, type_alias.into())
|
||||||
.with_type_param_mode(crate::lower::ParamLoweringMode::Variable);
|
.with_type_param_mode(crate::lower::ParamLoweringMode::Variable);
|
||||||
|
|
||||||
let trait_subst = TyBuilder::subst_for_def(db, trait_, None)
|
let trait_subst = TyBuilder::subst_for_def(db, trait_, None)
|
||||||
|
@ -6,7 +6,7 @@ use hir_def::{
|
|||||||
hir::Expr,
|
hir::Expr,
|
||||||
path::Path,
|
path::Path,
|
||||||
resolver::{Resolver, ValueNs},
|
resolver::{Resolver, ValueNs},
|
||||||
type_ref::ConstRef,
|
type_ref::LiteralConstRef,
|
||||||
EnumVariantId, GeneralConstId, StaticId,
|
EnumVariantId, GeneralConstId, StaticId,
|
||||||
};
|
};
|
||||||
use la_arena::{Idx, RawIdx};
|
use la_arena::{Idx, RawIdx};
|
||||||
@ -129,23 +129,28 @@ pub fn intern_const_scalar(value: ConstScalar, ty: Ty) -> Const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Interns a constant scalar with the given type
|
/// Interns a constant scalar with the given type
|
||||||
pub fn intern_const_ref(db: &dyn HirDatabase, value: &ConstRef, ty: Ty, krate: CrateId) -> Const {
|
pub fn intern_const_ref(
|
||||||
|
db: &dyn HirDatabase,
|
||||||
|
value: &LiteralConstRef,
|
||||||
|
ty: Ty,
|
||||||
|
krate: CrateId,
|
||||||
|
) -> Const {
|
||||||
let layout = db.layout_of_ty(ty.clone(), krate);
|
let layout = db.layout_of_ty(ty.clone(), krate);
|
||||||
let bytes = match value {
|
let bytes = match value {
|
||||||
ConstRef::Int(i) => {
|
LiteralConstRef::Int(i) => {
|
||||||
// FIXME: We should handle failure of layout better.
|
// FIXME: We should handle failure of layout better.
|
||||||
let size = layout.map(|x| x.size.bytes_usize()).unwrap_or(16);
|
let size = layout.map(|x| x.size.bytes_usize()).unwrap_or(16);
|
||||||
ConstScalar::Bytes(i.to_le_bytes()[0..size].to_vec(), MemoryMap::default())
|
ConstScalar::Bytes(i.to_le_bytes()[0..size].to_vec(), MemoryMap::default())
|
||||||
}
|
}
|
||||||
ConstRef::UInt(i) => {
|
LiteralConstRef::UInt(i) => {
|
||||||
let size = layout.map(|x| x.size.bytes_usize()).unwrap_or(16);
|
let size = layout.map(|x| x.size.bytes_usize()).unwrap_or(16);
|
||||||
ConstScalar::Bytes(i.to_le_bytes()[0..size].to_vec(), MemoryMap::default())
|
ConstScalar::Bytes(i.to_le_bytes()[0..size].to_vec(), MemoryMap::default())
|
||||||
}
|
}
|
||||||
ConstRef::Bool(b) => ConstScalar::Bytes(vec![*b as u8], MemoryMap::default()),
|
LiteralConstRef::Bool(b) => ConstScalar::Bytes(vec![*b as u8], MemoryMap::default()),
|
||||||
ConstRef::Char(c) => {
|
LiteralConstRef::Char(c) => {
|
||||||
ConstScalar::Bytes((*c as u32).to_le_bytes().to_vec(), MemoryMap::default())
|
ConstScalar::Bytes((*c as u32).to_le_bytes().to_vec(), MemoryMap::default())
|
||||||
}
|
}
|
||||||
ConstRef::Unknown => ConstScalar::Unknown,
|
LiteralConstRef::Unknown => ConstScalar::Unknown,
|
||||||
};
|
};
|
||||||
intern_const_scalar(bytes, ty)
|
intern_const_scalar(bytes, ty)
|
||||||
}
|
}
|
||||||
@ -154,7 +159,7 @@ pub fn intern_const_ref(db: &dyn HirDatabase, value: &ConstRef, ty: Ty, krate: C
|
|||||||
pub fn usize_const(db: &dyn HirDatabase, value: Option<u128>, krate: CrateId) -> Const {
|
pub fn usize_const(db: &dyn HirDatabase, value: Option<u128>, krate: CrateId) -> Const {
|
||||||
intern_const_ref(
|
intern_const_ref(
|
||||||
db,
|
db,
|
||||||
&value.map_or(ConstRef::Unknown, ConstRef::UInt),
|
&value.map_or(LiteralConstRef::Unknown, LiteralConstRef::UInt),
|
||||||
TyBuilder::usize(),
|
TyBuilder::usize(),
|
||||||
krate,
|
krate,
|
||||||
)
|
)
|
||||||
@ -221,6 +226,7 @@ pub(crate) fn const_eval_query(
|
|||||||
db.trait_environment_for_body(def),
|
db.trait_environment_for_body(def),
|
||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
|
GeneralConstId::InTypeConstId(c) => db.mir_body(c.into())?,
|
||||||
};
|
};
|
||||||
let c = interpret_mir(db, &body, false).0?;
|
let c = interpret_mir(db, &body, false).0?;
|
||||||
Ok(c)
|
Ok(c)
|
||||||
|
@ -2051,6 +2051,17 @@ fn extern_weak_statics() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_ne_bytes() {
|
||||||
|
check_number(
|
||||||
|
r#"
|
||||||
|
//- minicore: int_impl
|
||||||
|
const GOAL: u32 = u32::from_ne_bytes([44, 1, 0, 0]);
|
||||||
|
"#,
|
||||||
|
300,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn enums() {
|
fn enums() {
|
||||||
check_number(
|
check_number(
|
||||||
|
@ -278,6 +278,7 @@ fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult>
|
|||||||
DefWithBodyId::VariantId(it) => {
|
DefWithBodyId::VariantId(it) => {
|
||||||
db.enum_data(it.parent).variants[it.local_id].name.display(db.upcast()).to_string()
|
db.enum_data(it.parent).variants[it.local_id].name.display(db.upcast()).to_string()
|
||||||
}
|
}
|
||||||
|
DefWithBodyId::InTypeConstId(it) => format!("in type const {it:?}"),
|
||||||
});
|
});
|
||||||
db.infer_query(def)
|
db.infer_query(def)
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,10 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> Vec<ExprId> {
|
|||||||
|
|
||||||
let is_unsafe = match def {
|
let is_unsafe = match def {
|
||||||
DefWithBodyId::FunctionId(it) => db.function_data(it).has_unsafe_kw(),
|
DefWithBodyId::FunctionId(it) => db.function_data(it).has_unsafe_kw(),
|
||||||
DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) | DefWithBodyId::VariantId(_) => {
|
DefWithBodyId::StaticId(_)
|
||||||
false
|
| DefWithBodyId::ConstId(_)
|
||||||
}
|
| DefWithBodyId::VariantId(_)
|
||||||
|
| DefWithBodyId::InTypeConstId(_) => false,
|
||||||
};
|
};
|
||||||
if is_unsafe {
|
if is_unsafe {
|
||||||
return res;
|
return res;
|
||||||
|
@ -42,9 +42,9 @@ use triomphe::Arc;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, fold_tys, infer::coerce::CoerceMany, lower::ImplTraitLoweringMode,
|
db::HirDatabase, fold_tys, infer::coerce::CoerceMany, lower::ImplTraitLoweringMode,
|
||||||
static_lifetime, to_assoc_type_id, traits::FnTrait, AliasEq, AliasTy, ClosureId, DomainGoal,
|
static_lifetime, to_assoc_type_id, traits::FnTrait, utils::UnevaluatedConstEvaluatorFolder,
|
||||||
GenericArg, Goal, ImplTraitId, InEnvironment, Interner, ProjectionTy, RpitId, Substitution,
|
AliasEq, AliasTy, ClosureId, DomainGoal, GenericArg, Goal, ImplTraitId, InEnvironment,
|
||||||
TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt,
|
Interner, ProjectionTy, RpitId, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This lint has a false positive here. See the link below for details.
|
// This lint has a false positive here. See the link below for details.
|
||||||
@ -102,6 +102,10 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
DefWithBodyId::InTypeConstId(_) => {
|
||||||
|
// FIXME: We should know the expected type here.
|
||||||
|
ctx.return_ty = ctx.table.new_type_var();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.infer_body();
|
ctx.infer_body();
|
||||||
@ -684,7 +688,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
|
|
||||||
fn collect_fn(&mut self, func: FunctionId) {
|
fn collect_fn(&mut self, func: FunctionId) {
|
||||||
let data = self.db.function_data(func);
|
let data = self.db.function_data(func);
|
||||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
|
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, func.into())
|
||||||
.with_impl_trait_mode(ImplTraitLoweringMode::Param);
|
.with_impl_trait_mode(ImplTraitLoweringMode::Param);
|
||||||
let mut param_tys =
|
let mut param_tys =
|
||||||
data.params.iter().map(|type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
|
data.params.iter().map(|type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
|
||||||
@ -708,7 +712,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
}
|
}
|
||||||
let return_ty = &*data.ret_type;
|
let return_ty = &*data.ret_type;
|
||||||
|
|
||||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
|
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into())
|
||||||
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
|
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
|
||||||
let return_ty = ctx.lower_ty(return_ty);
|
let return_ty = ctx.lower_ty(return_ty);
|
||||||
let return_ty = self.insert_type_vars(return_ty);
|
let return_ty = self.insert_type_vars(return_ty);
|
||||||
@ -823,7 +827,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
|
fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
|
||||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
|
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||||
let ty = ctx.lower_ty(type_ref);
|
let ty = ctx.lower_ty(type_ref);
|
||||||
let ty = self.insert_type_vars(ty);
|
let ty = self.insert_type_vars(ty);
|
||||||
self.normalize_associated_types_in(ty)
|
self.normalize_associated_types_in(ty)
|
||||||
@ -850,7 +854,21 @@ impl<'a> InferenceContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
|
fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
|
||||||
self.table.unify(ty1, ty2)
|
let ty1 = ty1
|
||||||
|
.clone()
|
||||||
|
.try_fold_with(
|
||||||
|
&mut UnevaluatedConstEvaluatorFolder { db: self.db },
|
||||||
|
DebruijnIndex::INNERMOST,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let ty2 = ty2
|
||||||
|
.clone()
|
||||||
|
.try_fold_with(
|
||||||
|
&mut UnevaluatedConstEvaluatorFolder { db: self.db },
|
||||||
|
DebruijnIndex::INNERMOST,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
self.table.unify(&ty1, &ty2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to returns the deeply last field of nested structures, but
|
/// Attempts to returns the deeply last field of nested structures, but
|
||||||
@ -973,7 +991,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
None => return (self.err_ty(), None),
|
None => return (self.err_ty(), None),
|
||||||
};
|
};
|
||||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
|
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||||
let (resolution, unresolved) = if value_ns {
|
let (resolution, unresolved) = if value_ns {
|
||||||
match self.resolver.resolve_path_in_value_ns(self.db.upcast(), path) {
|
match self.resolver.resolve_path_in_value_ns(self.db.upcast(), path) {
|
||||||
Some(ResolveValueResult::ValueNs(value)) => match value {
|
Some(ResolveValueResult::ValueNs(value)) => match value {
|
||||||
|
@ -1715,6 +1715,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
const_or_path_to_chalk(
|
const_or_path_to_chalk(
|
||||||
this.db,
|
this.db,
|
||||||
&this.resolver,
|
&this.resolver,
|
||||||
|
this.owner.into(),
|
||||||
ty,
|
ty,
|
||||||
c,
|
c,
|
||||||
ParamLoweringMode::Placeholder,
|
ParamLoweringMode::Placeholder,
|
||||||
|
@ -44,7 +44,8 @@ impl InferenceContext<'_> {
|
|||||||
let last = path.segments().last()?;
|
let last = path.segments().last()?;
|
||||||
|
|
||||||
// Don't use `self.make_ty()` here as we need `orig_ns`.
|
// Don't use `self.make_ty()` here as we need `orig_ns`.
|
||||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
|
let ctx =
|
||||||
|
crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||||
let (ty, orig_ns) = ctx.lower_ty_ext(type_ref);
|
let (ty, orig_ns) = ctx.lower_ty_ext(type_ref);
|
||||||
let ty = self.table.insert_type_vars(ty);
|
let ty = self.table.insert_type_vars(ty);
|
||||||
let ty = self.table.normalize_associated_types_in(ty);
|
let ty = self.table.normalize_associated_types_in(ty);
|
||||||
@ -108,7 +109,7 @@ impl InferenceContext<'_> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
|
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||||
let substs = ctx.substs_from_path(path, value_def, true);
|
let substs = ctx.substs_from_path(path, value_def, true);
|
||||||
let substs = substs.as_slice(Interner);
|
let substs = substs.as_slice(Interner);
|
||||||
let parent_substs = self_subst.or_else(|| {
|
let parent_substs = self_subst.or_else(|| {
|
||||||
@ -190,7 +191,11 @@ impl InferenceContext<'_> {
|
|||||||
(TypeNs::TraitId(trait_), true) => {
|
(TypeNs::TraitId(trait_), true) => {
|
||||||
let segment =
|
let segment =
|
||||||
remaining_segments.last().expect("there should be at least one segment here");
|
remaining_segments.last().expect("there should be at least one segment here");
|
||||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
|
let ctx = crate::lower::TyLoweringContext::new(
|
||||||
|
self.db,
|
||||||
|
&self.resolver,
|
||||||
|
self.owner.into(),
|
||||||
|
);
|
||||||
let trait_ref =
|
let trait_ref =
|
||||||
ctx.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
|
ctx.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
|
||||||
self.resolve_trait_assoc_item(trait_ref, segment, id)
|
self.resolve_trait_assoc_item(trait_ref, segment, id)
|
||||||
@ -202,7 +207,11 @@ impl InferenceContext<'_> {
|
|||||||
// as Iterator>::Item::default`)
|
// as Iterator>::Item::default`)
|
||||||
let remaining_segments_for_ty =
|
let remaining_segments_for_ty =
|
||||||
remaining_segments.take(remaining_segments.len() - 1);
|
remaining_segments.take(remaining_segments.len() - 1);
|
||||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
|
let ctx = crate::lower::TyLoweringContext::new(
|
||||||
|
self.db,
|
||||||
|
&self.resolver,
|
||||||
|
self.owner.into(),
|
||||||
|
);
|
||||||
let (ty, _) = ctx.lower_partly_resolved_path(
|
let (ty, _) = ctx.lower_partly_resolved_path(
|
||||||
def,
|
def,
|
||||||
resolved_segment,
|
resolved_segment,
|
||||||
|
@ -266,7 +266,7 @@ impl chalk_ir::interner::Interner for Interner {
|
|||||||
c1: &Self::InternedConcreteConst,
|
c1: &Self::InternedConcreteConst,
|
||||||
c2: &Self::InternedConcreteConst,
|
c2: &Self::InternedConcreteConst,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
(c1 == &ConstScalar::Unknown) || (c2 == &ConstScalar::Unknown) || (c1 == c2)
|
!matches!(c1, ConstScalar::Bytes(..)) || !matches!(c2, ConstScalar::Bytes(..)) || (c1 == c2)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_generic_arg(
|
fn intern_generic_arg(
|
||||||
|
@ -2,6 +2,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use base_db::fixture::WithFixture;
|
use base_db::fixture::WithFixture;
|
||||||
use chalk_ir::{AdtId, TyKind};
|
use chalk_ir::{AdtId, TyKind};
|
||||||
|
use either::Either;
|
||||||
use hir_def::db::DefDatabase;
|
use hir_def::db::DefDatabase;
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
@ -25,27 +26,38 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
|
|||||||
);
|
);
|
||||||
|
|
||||||
let (db, file_ids) = TestDB::with_many_files(&ra_fixture);
|
let (db, file_ids) = TestDB::with_many_files(&ra_fixture);
|
||||||
let (adt_id, module_id) = file_ids
|
let (adt_or_type_alias_id, module_id) = file_ids
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find_map(|file_id| {
|
.find_map(|file_id| {
|
||||||
let module_id = db.module_for_file(file_id);
|
let module_id = db.module_for_file(file_id);
|
||||||
let def_map = module_id.def_map(&db);
|
let def_map = module_id.def_map(&db);
|
||||||
let scope = &def_map[module_id.local_id].scope;
|
let scope = &def_map[module_id.local_id].scope;
|
||||||
let adt_id = scope.declarations().find_map(|x| match x {
|
let adt_or_type_alias_id = scope.declarations().find_map(|x| match x {
|
||||||
hir_def::ModuleDefId::AdtId(x) => {
|
hir_def::ModuleDefId::AdtId(x) => {
|
||||||
let name = match x {
|
let name = match x {
|
||||||
hir_def::AdtId::StructId(x) => db.struct_data(x).name.to_smol_str(),
|
hir_def::AdtId::StructId(x) => db.struct_data(x).name.to_smol_str(),
|
||||||
hir_def::AdtId::UnionId(x) => db.union_data(x).name.to_smol_str(),
|
hir_def::AdtId::UnionId(x) => db.union_data(x).name.to_smol_str(),
|
||||||
hir_def::AdtId::EnumId(x) => db.enum_data(x).name.to_smol_str(),
|
hir_def::AdtId::EnumId(x) => db.enum_data(x).name.to_smol_str(),
|
||||||
};
|
};
|
||||||
(name == "Goal").then_some(x)
|
(name == "Goal").then_some(Either::Left(x))
|
||||||
|
}
|
||||||
|
hir_def::ModuleDefId::TypeAliasId(x) => {
|
||||||
|
let name = db.type_alias_data(x).name.to_smol_str();
|
||||||
|
(name == "Goal").then_some(Either::Right(x))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})?;
|
})?;
|
||||||
Some((adt_id, module_id))
|
Some((adt_or_type_alias_id, module_id))
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let goal_ty = TyKind::Adt(AdtId(adt_id), Substitution::empty(Interner)).intern(Interner);
|
let goal_ty = match adt_or_type_alias_id {
|
||||||
|
Either::Left(adt_id) => {
|
||||||
|
TyKind::Adt(AdtId(adt_id), Substitution::empty(Interner)).intern(Interner)
|
||||||
|
}
|
||||||
|
Either::Right(ty_id) => {
|
||||||
|
db.ty(ty_id.into()).substitute(Interner, &Substitution::empty(Interner))
|
||||||
|
}
|
||||||
|
};
|
||||||
db.layout_of_ty(goal_ty, module_id.krate())
|
db.layout_of_ty(goal_ty, module_id.krate())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,10 +391,23 @@ fn niche_optimization() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn const_eval() {
|
fn const_eval() {
|
||||||
|
size_and_align! {
|
||||||
|
struct Goal([i32; 2 + 2]);
|
||||||
|
}
|
||||||
size_and_align! {
|
size_and_align! {
|
||||||
const X: usize = 5;
|
const X: usize = 5;
|
||||||
struct Goal([i32; X]);
|
struct Goal([i32; X]);
|
||||||
}
|
}
|
||||||
|
size_and_align! {
|
||||||
|
mod foo {
|
||||||
|
pub(super) const BAR: usize = 5;
|
||||||
|
}
|
||||||
|
struct Ar<T>([T; foo::BAR]);
|
||||||
|
struct Goal(Ar<Ar<i32>>);
|
||||||
|
}
|
||||||
|
size_and_align! {
|
||||||
|
type Goal = [u8; 2 + 2];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -27,10 +27,11 @@ use hir_def::{
|
|||||||
nameres::MacroSubNs,
|
nameres::MacroSubNs,
|
||||||
path::{GenericArg, GenericArgs, ModPath, Path, PathKind, PathSegment, PathSegments},
|
path::{GenericArg, GenericArgs, ModPath, Path, PathKind, PathSegment, PathSegments},
|
||||||
resolver::{HasResolver, Resolver, TypeNs},
|
resolver::{HasResolver, Resolver, TypeNs},
|
||||||
type_ref::{ConstRefOrPath, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef},
|
type_ref::{ConstRef, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef},
|
||||||
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
|
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
|
||||||
GenericDefId, HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, StaticId,
|
GenericDefId, HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, StaticId,
|
||||||
StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId,
|
StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UnionId,
|
||||||
|
VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{name::Name, ExpandResult};
|
use hir_expand::{name::Name, ExpandResult};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
@ -43,17 +44,21 @@ use triomphe::Arc;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
all_super_traits,
|
all_super_traits,
|
||||||
consteval::{intern_const_ref, path_to_const, unknown_const, unknown_const_as_generic},
|
consteval::{
|
||||||
|
intern_const_ref, intern_const_scalar, path_to_const, unknown_const,
|
||||||
|
unknown_const_as_generic,
|
||||||
|
},
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
make_binders,
|
make_binders,
|
||||||
mapping::{from_chalk_trait_id, ToChalk},
|
mapping::{from_chalk_trait_id, ToChalk},
|
||||||
static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
|
static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
|
||||||
utils::Generics,
|
utils::Generics,
|
||||||
utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics},
|
utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics},
|
||||||
AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DynTy, FnPointer,
|
AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy,
|
||||||
FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
|
FnPointer, FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig,
|
||||||
QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
|
ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait,
|
||||||
Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
|
ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder,
|
||||||
|
TyKind, WhereClause,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -106,6 +111,7 @@ pub struct TyLoweringContext<'a> {
|
|||||||
pub db: &'a dyn HirDatabase,
|
pub db: &'a dyn HirDatabase,
|
||||||
resolver: &'a Resolver,
|
resolver: &'a Resolver,
|
||||||
in_binders: DebruijnIndex,
|
in_binders: DebruijnIndex,
|
||||||
|
owner: TypeOwnerId,
|
||||||
/// Note: Conceptually, it's thinkable that we could be in a location where
|
/// Note: Conceptually, it's thinkable that we could be in a location where
|
||||||
/// some type params should be represented as placeholders, and others
|
/// some type params should be represented as placeholders, and others
|
||||||
/// should be converted to variables. I think in practice, this isn't
|
/// should be converted to variables. I think in practice, this isn't
|
||||||
@ -118,13 +124,14 @@ pub struct TyLoweringContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TyLoweringContext<'a> {
|
impl<'a> TyLoweringContext<'a> {
|
||||||
pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self {
|
pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver, owner: TypeOwnerId) -> Self {
|
||||||
let impl_trait_mode = ImplTraitLoweringState::Disallowed;
|
let impl_trait_mode = ImplTraitLoweringState::Disallowed;
|
||||||
let type_param_mode = ParamLoweringMode::Placeholder;
|
let type_param_mode = ParamLoweringMode::Placeholder;
|
||||||
let in_binders = DebruijnIndex::INNERMOST;
|
let in_binders = DebruijnIndex::INNERMOST;
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
resolver,
|
resolver,
|
||||||
|
owner,
|
||||||
in_binders,
|
in_binders,
|
||||||
impl_trait_mode,
|
impl_trait_mode,
|
||||||
type_param_mode,
|
type_param_mode,
|
||||||
@ -235,6 +242,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||||||
let const_len = const_or_path_to_chalk(
|
let const_len = const_or_path_to_chalk(
|
||||||
self.db,
|
self.db,
|
||||||
self.resolver,
|
self.resolver,
|
||||||
|
self.owner,
|
||||||
TyBuilder::usize(),
|
TyBuilder::usize(),
|
||||||
len,
|
len,
|
||||||
self.type_param_mode,
|
self.type_param_mode,
|
||||||
@ -840,6 +848,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||||||
const_or_path_to_chalk(
|
const_or_path_to_chalk(
|
||||||
self.db,
|
self.db,
|
||||||
self.resolver,
|
self.resolver,
|
||||||
|
self.owner,
|
||||||
ty,
|
ty,
|
||||||
c,
|
c,
|
||||||
self.type_param_mode,
|
self.type_param_mode,
|
||||||
@ -1356,8 +1365,8 @@ pub(crate) fn field_types_query(
|
|||||||
};
|
};
|
||||||
let generics = generics(db.upcast(), def);
|
let generics = generics(db.upcast(), def);
|
||||||
let mut res = ArenaMap::default();
|
let mut res = ArenaMap::default();
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, GenericDefId::from(variant_id.adt_id()).into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
for (field_id, field_data) in var_data.fields().iter() {
|
for (field_id, field_data) in var_data.fields().iter() {
|
||||||
res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)));
|
res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)));
|
||||||
}
|
}
|
||||||
@ -1379,8 +1388,8 @@ pub(crate) fn generic_predicates_for_param_query(
|
|||||||
assoc_name: Option<Name>,
|
assoc_name: Option<Name>,
|
||||||
) -> Arc<[Binders<QuantifiedWhereClause>]> {
|
) -> Arc<[Binders<QuantifiedWhereClause>]> {
|
||||||
let resolver = def.resolver(db.upcast());
|
let resolver = def.resolver(db.upcast());
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
let generics = generics(db.upcast(), def);
|
let generics = generics(db.upcast(), def);
|
||||||
let mut predicates: Vec<_> = resolver
|
let mut predicates: Vec<_> = resolver
|
||||||
.where_predicates_in_scope()
|
.where_predicates_in_scope()
|
||||||
@ -1468,8 +1477,8 @@ pub(crate) fn trait_environment_query(
|
|||||||
def: GenericDefId,
|
def: GenericDefId,
|
||||||
) -> Arc<TraitEnvironment> {
|
) -> Arc<TraitEnvironment> {
|
||||||
let resolver = def.resolver(db.upcast());
|
let resolver = def.resolver(db.upcast());
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Placeholder);
|
.with_type_param_mode(ParamLoweringMode::Placeholder);
|
||||||
let mut traits_in_scope = Vec::new();
|
let mut traits_in_scope = Vec::new();
|
||||||
let mut clauses = Vec::new();
|
let mut clauses = Vec::new();
|
||||||
for pred in resolver.where_predicates_in_scope() {
|
for pred in resolver.where_predicates_in_scope() {
|
||||||
@ -1527,8 +1536,8 @@ pub(crate) fn generic_predicates_query(
|
|||||||
def: GenericDefId,
|
def: GenericDefId,
|
||||||
) -> Arc<[Binders<QuantifiedWhereClause>]> {
|
) -> Arc<[Binders<QuantifiedWhereClause>]> {
|
||||||
let resolver = def.resolver(db.upcast());
|
let resolver = def.resolver(db.upcast());
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
let generics = generics(db.upcast(), def);
|
let generics = generics(db.upcast(), def);
|
||||||
|
|
||||||
let mut predicates = resolver
|
let mut predicates = resolver
|
||||||
@ -1582,8 +1591,8 @@ pub(crate) fn generic_defaults_query(
|
|||||||
def: GenericDefId,
|
def: GenericDefId,
|
||||||
) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
|
) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
|
||||||
let resolver = def.resolver(db.upcast());
|
let resolver = def.resolver(db.upcast());
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
let generic_params = generics(db.upcast(), def);
|
let generic_params = generics(db.upcast(), def);
|
||||||
let parent_start_idx = generic_params.len_self();
|
let parent_start_idx = generic_params.len_self();
|
||||||
|
|
||||||
@ -1648,11 +1657,11 @@ pub(crate) fn generic_defaults_recover(
|
|||||||
fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
|
fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
|
||||||
let data = db.function_data(def);
|
let data = db.function_data(def);
|
||||||
let resolver = def.resolver(db.upcast());
|
let resolver = def.resolver(db.upcast());
|
||||||
let ctx_params = TyLoweringContext::new(db, &resolver)
|
let ctx_params = TyLoweringContext::new(db, &resolver, def.into())
|
||||||
.with_impl_trait_mode(ImplTraitLoweringMode::Variable)
|
.with_impl_trait_mode(ImplTraitLoweringMode::Variable)
|
||||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
let params = data.params.iter().map(|tr| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
|
let params = data.params.iter().map(|tr| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
|
||||||
let ctx_ret = TyLoweringContext::new(db, &resolver)
|
let ctx_ret = TyLoweringContext::new(db, &resolver, def.into())
|
||||||
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
|
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
|
||||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
let ret = ctx_ret.lower_ty(&data.ret_type);
|
let ret = ctx_ret.lower_ty(&data.ret_type);
|
||||||
@ -1683,8 +1692,8 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
|
|||||||
let data = db.const_data(def);
|
let data = db.const_data(def);
|
||||||
let generics = generics(db.upcast(), def.into());
|
let generics = generics(db.upcast(), def.into());
|
||||||
let resolver = def.resolver(db.upcast());
|
let resolver = def.resolver(db.upcast());
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
|
|
||||||
make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
|
make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
|
||||||
}
|
}
|
||||||
@ -1693,7 +1702,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
|
|||||||
fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
|
fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
|
||||||
let data = db.static_data(def);
|
let data = db.static_data(def);
|
||||||
let resolver = def.resolver(db.upcast());
|
let resolver = def.resolver(db.upcast());
|
||||||
let ctx = TyLoweringContext::new(db, &resolver);
|
let ctx = TyLoweringContext::new(db, &resolver, def.into());
|
||||||
|
|
||||||
Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
|
Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
|
||||||
}
|
}
|
||||||
@ -1702,8 +1711,8 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
|
|||||||
let struct_data = db.struct_data(def);
|
let struct_data = db.struct_data(def);
|
||||||
let fields = struct_data.variant_data.fields();
|
let fields = struct_data.variant_data.fields();
|
||||||
let resolver = def.resolver(db.upcast());
|
let resolver = def.resolver(db.upcast());
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, AdtId::from(def).into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
|
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
|
||||||
let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
|
let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
|
||||||
Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe))
|
Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe))
|
||||||
@ -1715,7 +1724,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
|
|||||||
if let StructKind::Unit = struct_data.variant_data.kind() {
|
if let StructKind::Unit = struct_data.variant_data.kind() {
|
||||||
return type_for_adt(db, def.into());
|
return type_for_adt(db, def.into());
|
||||||
}
|
}
|
||||||
let generics = generics(db.upcast(), def.into());
|
let generics = generics(db.upcast(), AdtId::from(def).into());
|
||||||
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
|
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
|
||||||
make_binders(
|
make_binders(
|
||||||
db,
|
db,
|
||||||
@ -1729,8 +1738,8 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
|
|||||||
let var_data = &enum_data.variants[def.local_id];
|
let var_data = &enum_data.variants[def.local_id];
|
||||||
let fields = var_data.variant_data.fields();
|
let fields = var_data.variant_data.fields();
|
||||||
let resolver = def.parent.resolver(db.upcast());
|
let resolver = def.parent.resolver(db.upcast());
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, DefWithBodyId::VariantId(def).into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
|
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
|
||||||
let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
|
let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
|
||||||
Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe))
|
Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe))
|
||||||
@ -1762,8 +1771,8 @@ fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
|
|||||||
fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
|
fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
|
||||||
let generics = generics(db.upcast(), t.into());
|
let generics = generics(db.upcast(), t.into());
|
||||||
let resolver = t.resolver(db.upcast());
|
let resolver = t.resolver(db.upcast());
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, t.into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
if db.type_alias_data(t).is_extern {
|
if db.type_alias_data(t).is_extern {
|
||||||
Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
|
Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
|
||||||
} else {
|
} else {
|
||||||
@ -1884,8 +1893,8 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
|
|||||||
"impl_self_ty_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
|
"impl_self_ty_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
|
||||||
));
|
));
|
||||||
let generics = generics(db.upcast(), impl_id.into());
|
let generics = generics(db.upcast(), impl_id.into());
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
|
make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1894,7 +1903,7 @@ pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> T
|
|||||||
let parent_data = db.generic_params(def.parent());
|
let parent_data = db.generic_params(def.parent());
|
||||||
let data = &parent_data.type_or_consts[def.local_id()];
|
let data = &parent_data.type_or_consts[def.local_id()];
|
||||||
let resolver = def.parent().resolver(db.upcast());
|
let resolver = def.parent().resolver(db.upcast());
|
||||||
let ctx = TyLoweringContext::new(db, &resolver);
|
let ctx = TyLoweringContext::new(db, &resolver, def.parent().into());
|
||||||
match data {
|
match data {
|
||||||
TypeOrConstParamData::TypeParamData(_) => {
|
TypeOrConstParamData::TypeParamData(_) => {
|
||||||
never!();
|
never!();
|
||||||
@ -1920,8 +1929,8 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<
|
|||||||
let _cx = stdx::panic_context::enter(format!(
|
let _cx = stdx::panic_context::enter(format!(
|
||||||
"impl_trait_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
|
"impl_trait_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
|
||||||
));
|
));
|
||||||
let ctx =
|
let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
|
||||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
|
let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
|
||||||
let target_trait = impl_data.target_trait.as_ref()?;
|
let target_trait = impl_data.target_trait.as_ref()?;
|
||||||
Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
|
Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
|
||||||
@ -1934,7 +1943,7 @@ pub(crate) fn return_type_impl_traits(
|
|||||||
// FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
|
// FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
|
||||||
let data = db.function_data(def);
|
let data = db.function_data(def);
|
||||||
let resolver = def.resolver(db.upcast());
|
let resolver = def.resolver(db.upcast());
|
||||||
let ctx_ret = TyLoweringContext::new(db, &resolver)
|
let ctx_ret = TyLoweringContext::new(db, &resolver, def.into())
|
||||||
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
|
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
|
||||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
let _ret = ctx_ret.lower_ty(&data.ret_type);
|
let _ret = ctx_ret.lower_ty(&data.ret_type);
|
||||||
@ -1969,7 +1978,7 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
|
|||||||
arg: &'a GenericArg,
|
arg: &'a GenericArg,
|
||||||
this: &mut T,
|
this: &mut T,
|
||||||
for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
|
for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
|
||||||
for_const: impl FnOnce(&mut T, &ConstRefOrPath, Ty) -> Const + 'a,
|
for_const: impl FnOnce(&mut T, &ConstRef, Ty) -> Const + 'a,
|
||||||
) -> Option<crate::GenericArg> {
|
) -> Option<crate::GenericArg> {
|
||||||
let kind = match kind_id {
|
let kind = match kind_id {
|
||||||
Either::Left(_) => ParamKind::Type,
|
Either::Left(_) => ParamKind::Type,
|
||||||
@ -1997,7 +2006,7 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
|
|||||||
let p = p.mod_path()?;
|
let p = p.mod_path()?;
|
||||||
if p.kind == PathKind::Plain {
|
if p.kind == PathKind::Plain {
|
||||||
if let [n] = p.segments() {
|
if let [n] = p.segments() {
|
||||||
let c = ConstRefOrPath::Path(n.clone());
|
let c = ConstRef::Path(n.clone());
|
||||||
return Some(
|
return Some(
|
||||||
GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
|
GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
|
||||||
);
|
);
|
||||||
@ -2013,15 +2022,16 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
|
|||||||
pub(crate) fn const_or_path_to_chalk(
|
pub(crate) fn const_or_path_to_chalk(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
|
owner: TypeOwnerId,
|
||||||
expected_ty: Ty,
|
expected_ty: Ty,
|
||||||
value: &ConstRefOrPath,
|
value: &ConstRef,
|
||||||
mode: ParamLoweringMode,
|
mode: ParamLoweringMode,
|
||||||
args: impl FnOnce() -> Generics,
|
args: impl FnOnce() -> Generics,
|
||||||
debruijn: DebruijnIndex,
|
debruijn: DebruijnIndex,
|
||||||
) -> Const {
|
) -> Const {
|
||||||
match value {
|
match value {
|
||||||
ConstRefOrPath::Scalar(s) => intern_const_ref(db, s, expected_ty, resolver.krate()),
|
ConstRef::Scalar(s) => intern_const_ref(db, s, expected_ty, resolver.krate()),
|
||||||
ConstRefOrPath::Path(n) => {
|
ConstRef::Path(n) => {
|
||||||
let path = ModPath::from_segments(PathKind::Plain, Some(n.clone()));
|
let path = ModPath::from_segments(PathKind::Plain, Some(n.clone()));
|
||||||
path_to_const(
|
path_to_const(
|
||||||
db,
|
db,
|
||||||
@ -2034,6 +2044,20 @@ pub(crate) fn const_or_path_to_chalk(
|
|||||||
)
|
)
|
||||||
.unwrap_or_else(|| unknown_const(expected_ty))
|
.unwrap_or_else(|| unknown_const(expected_ty))
|
||||||
}
|
}
|
||||||
|
&ConstRef::Complex(x) => {
|
||||||
|
let crate_data = &db.crate_graph()[owner.module(db.upcast()).krate()];
|
||||||
|
if crate_data.env.get("__ra_is_test_fixture").is_none() && crate_data.origin.is_local()
|
||||||
|
{
|
||||||
|
// FIXME: current `InTypeConstId` is very unstable, so we only use it in non local crate
|
||||||
|
// that are unlikely to be edited.
|
||||||
|
return unknown_const(expected_ty);
|
||||||
|
}
|
||||||
|
let c = db.intern_in_type_const((x, owner)).into();
|
||||||
|
intern_const_scalar(
|
||||||
|
ConstScalar::UnevaluatedConst(c, Substitution::empty(Interner)),
|
||||||
|
expected_ty,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,7 +570,7 @@ impl ReceiverAdjustments {
|
|||||||
.intern(Interner);
|
.intern(Interner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
never!("unsize_array with non-reference-to-array {:?}", ty);
|
// FIXME: report diagnostic if array unsizing happens without indirection.
|
||||||
ty
|
ty
|
||||||
};
|
};
|
||||||
adjust.push(Adjustment {
|
adjust.push(Adjustment {
|
||||||
|
@ -1876,6 +1876,7 @@ pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<Mi
|
|||||||
DefWithBodyId::VariantId(it) => {
|
DefWithBodyId::VariantId(it) => {
|
||||||
db.enum_data(it.parent).variants[it.local_id].name.display(db.upcast()).to_string()
|
db.enum_data(it.parent).variants[it.local_id].name.display(db.upcast()).to_string()
|
||||||
}
|
}
|
||||||
|
DefWithBodyId::InTypeConstId(it) => format!("in type const {it:?}"),
|
||||||
});
|
});
|
||||||
let body = db.body(def);
|
let body = db.body(def);
|
||||||
let infer = db.infer(def);
|
let infer = db.infer(def);
|
||||||
|
@ -60,6 +60,9 @@ impl MirBody {
|
|||||||
let data = db.enum_data(id.parent);
|
let data = db.enum_data(id.parent);
|
||||||
w!(this, "enum {} = ", data.name.display(db.upcast()));
|
w!(this, "enum {} = ", data.name.display(db.upcast()));
|
||||||
}
|
}
|
||||||
|
hir_def::DefWithBodyId::InTypeConstId(id) => {
|
||||||
|
w!(this, "in type const {id:?} = ");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
ctx.result
|
ctx.result
|
||||||
}
|
}
|
||||||
|
@ -146,6 +146,7 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
|
|||||||
let loc = db.lookup_intern_enum(it.parent);
|
let loc = db.lookup_intern_enum(it.parent);
|
||||||
loc.source(&db).value.syntax().text_range().start()
|
loc.source(&db).value.syntax().text_range().start()
|
||||||
}
|
}
|
||||||
|
DefWithBodyId::InTypeConstId(it) => it.source(&db).syntax().text_range().start(),
|
||||||
});
|
});
|
||||||
let mut unexpected_type_mismatches = String::new();
|
let mut unexpected_type_mismatches = String::new();
|
||||||
for def in defs {
|
for def in defs {
|
||||||
@ -391,6 +392,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
|||||||
let loc = db.lookup_intern_enum(it.parent);
|
let loc = db.lookup_intern_enum(it.parent);
|
||||||
loc.source(&db).value.syntax().text_range().start()
|
loc.source(&db).value.syntax().text_range().start()
|
||||||
}
|
}
|
||||||
|
DefWithBodyId::InTypeConstId(it) => it.source(&db).syntax().text_range().start(),
|
||||||
});
|
});
|
||||||
for def in defs {
|
for def in defs {
|
||||||
let (body, source_map) = db.body_with_source_map(def);
|
let (body, source_map) = db.body_with_source_map(def);
|
||||||
|
@ -1955,3 +1955,26 @@ impl Inner<1> {
|
|||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dont_crash_on_slice_unsizing() {
|
||||||
|
check_no_mismatches(
|
||||||
|
r#"
|
||||||
|
//- minicore: slice, unsize, coerce_unsized
|
||||||
|
trait Tr {
|
||||||
|
fn f(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tr for [i32] {
|
||||||
|
fn f(self) {
|
||||||
|
let t;
|
||||||
|
x(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn x(a: [i32; 4]) {
|
||||||
|
let b = a.f();
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -40,6 +40,7 @@ from_id![
|
|||||||
(hir_def::TraitAliasId, crate::TraitAlias),
|
(hir_def::TraitAliasId, crate::TraitAlias),
|
||||||
(hir_def::StaticId, crate::Static),
|
(hir_def::StaticId, crate::Static),
|
||||||
(hir_def::ConstId, crate::Const),
|
(hir_def::ConstId, crate::Const),
|
||||||
|
(hir_def::InTypeConstId, crate::InTypeConst),
|
||||||
(hir_def::FunctionId, crate::Function),
|
(hir_def::FunctionId, crate::Function),
|
||||||
(hir_def::ImplId, crate::Impl),
|
(hir_def::ImplId, crate::Impl),
|
||||||
(hir_def::TypeOrConstParamId, crate::TypeOrConstParam),
|
(hir_def::TypeOrConstParamId, crate::TypeOrConstParam),
|
||||||
@ -144,6 +145,7 @@ impl From<DefWithBody> for DefWithBodyId {
|
|||||||
DefWithBody::Static(it) => DefWithBodyId::StaticId(it.id),
|
DefWithBody::Static(it) => DefWithBodyId::StaticId(it.id),
|
||||||
DefWithBody::Const(it) => DefWithBodyId::ConstId(it.id),
|
DefWithBody::Const(it) => DefWithBodyId::ConstId(it.id),
|
||||||
DefWithBody::Variant(it) => DefWithBodyId::VariantId(it.into()),
|
DefWithBody::Variant(it) => DefWithBodyId::VariantId(it.into()),
|
||||||
|
DefWithBody::InTypeConst(it) => DefWithBodyId::InTypeConstId(it.id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,6 +157,7 @@ impl From<DefWithBodyId> for DefWithBody {
|
|||||||
DefWithBodyId::StaticId(it) => DefWithBody::Static(it.into()),
|
DefWithBodyId::StaticId(it) => DefWithBody::Static(it.into()),
|
||||||
DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()),
|
DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()),
|
||||||
DefWithBodyId::VariantId(it) => DefWithBody::Variant(it.into()),
|
DefWithBodyId::VariantId(it) => DefWithBody::Variant(it.into()),
|
||||||
|
DefWithBodyId::InTypeConstId(it) => DefWithBody::InTypeConst(it.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,10 @@ use hir_def::{
|
|||||||
resolver::{HasResolver, Resolver},
|
resolver::{HasResolver, Resolver},
|
||||||
src::HasSource as _,
|
src::HasSource as _,
|
||||||
AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
|
AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
|
||||||
EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, InTypeConstId, ItemContainerId,
|
||||||
LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
|
LifetimeParamId, LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId,
|
||||||
TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
|
StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId,
|
||||||
|
UnionId,
|
||||||
};
|
};
|
||||||
use hir_expand::{name::name, MacroCallKind};
|
use hir_expand::{name::name, MacroCallKind};
|
||||||
use hir_ty::{
|
use hir_ty::{
|
||||||
@ -1375,8 +1376,9 @@ pub enum DefWithBody {
|
|||||||
Static(Static),
|
Static(Static),
|
||||||
Const(Const),
|
Const(Const),
|
||||||
Variant(Variant),
|
Variant(Variant),
|
||||||
|
InTypeConst(InTypeConst),
|
||||||
}
|
}
|
||||||
impl_from!(Function, Const, Static, Variant for DefWithBody);
|
impl_from!(Function, Const, Static, Variant, InTypeConst for DefWithBody);
|
||||||
|
|
||||||
impl DefWithBody {
|
impl DefWithBody {
|
||||||
pub fn module(self, db: &dyn HirDatabase) -> Module {
|
pub fn module(self, db: &dyn HirDatabase) -> Module {
|
||||||
@ -1385,6 +1387,7 @@ impl DefWithBody {
|
|||||||
DefWithBody::Function(f) => f.module(db),
|
DefWithBody::Function(f) => f.module(db),
|
||||||
DefWithBody::Static(s) => s.module(db),
|
DefWithBody::Static(s) => s.module(db),
|
||||||
DefWithBody::Variant(v) => v.module(db),
|
DefWithBody::Variant(v) => v.module(db),
|
||||||
|
DefWithBody::InTypeConst(c) => c.module(db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1394,6 +1397,7 @@ impl DefWithBody {
|
|||||||
DefWithBody::Static(s) => Some(s.name(db)),
|
DefWithBody::Static(s) => Some(s.name(db)),
|
||||||
DefWithBody::Const(c) => c.name(db),
|
DefWithBody::Const(c) => c.name(db),
|
||||||
DefWithBody::Variant(v) => Some(v.name(db)),
|
DefWithBody::Variant(v) => Some(v.name(db)),
|
||||||
|
DefWithBody::InTypeConst(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1404,6 +1408,11 @@ impl DefWithBody {
|
|||||||
DefWithBody::Static(it) => it.ty(db),
|
DefWithBody::Static(it) => it.ty(db),
|
||||||
DefWithBody::Const(it) => it.ty(db),
|
DefWithBody::Const(it) => it.ty(db),
|
||||||
DefWithBody::Variant(it) => it.parent.variant_body_ty(db),
|
DefWithBody::Variant(it) => it.parent.variant_body_ty(db),
|
||||||
|
DefWithBody::InTypeConst(it) => Type::new_with_resolver_inner(
|
||||||
|
db,
|
||||||
|
&DefWithBodyId::from(it.id).resolver(db.upcast()),
|
||||||
|
TyKind::Error.intern(Interner),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1413,6 +1422,7 @@ impl DefWithBody {
|
|||||||
DefWithBody::Static(it) => it.id.into(),
|
DefWithBody::Static(it) => it.id.into(),
|
||||||
DefWithBody::Const(it) => it.id.into(),
|
DefWithBody::Const(it) => it.id.into(),
|
||||||
DefWithBody::Variant(it) => it.into(),
|
DefWithBody::Variant(it) => it.into(),
|
||||||
|
DefWithBody::InTypeConst(it) => it.id.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1797,6 +1807,8 @@ impl DefWithBody {
|
|||||||
DefWithBody::Static(it) => it.into(),
|
DefWithBody::Static(it) => it.into(),
|
||||||
DefWithBody::Const(it) => it.into(),
|
DefWithBody::Const(it) => it.into(),
|
||||||
DefWithBody::Variant(it) => it.into(),
|
DefWithBody::Variant(it) => it.into(),
|
||||||
|
// FIXME: don't ignore diagnostics for in type const
|
||||||
|
DefWithBody::InTypeConst(_) => return,
|
||||||
};
|
};
|
||||||
for diag in hir_ty::diagnostics::incorrect_case(db, krate, def.into()) {
|
for diag in hir_ty::diagnostics::incorrect_case(db, krate, def.into()) {
|
||||||
acc.push(diag.into())
|
acc.push(diag.into())
|
||||||
@ -2085,6 +2097,17 @@ impl HasVisibility for Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct InTypeConst {
|
||||||
|
pub(crate) id: InTypeConstId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InTypeConst {
|
||||||
|
pub fn module(self, db: &dyn HirDatabase) -> Module {
|
||||||
|
Module { id: self.id.lookup(db.upcast()).1.module(db.upcast()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct Const {
|
pub struct Const {
|
||||||
pub(crate) id: ConstId,
|
pub(crate) id: ConstId,
|
||||||
@ -2515,7 +2538,7 @@ impl AsAssocItem for DefWithBody {
|
|||||||
match self {
|
match self {
|
||||||
DefWithBody::Function(it) => it.as_assoc_item(db),
|
DefWithBody::Function(it) => it.as_assoc_item(db),
|
||||||
DefWithBody::Const(it) => it.as_assoc_item(db),
|
DefWithBody::Const(it) => it.as_assoc_item(db),
|
||||||
DefWithBody::Static(_) | DefWithBody::Variant(_) => None,
|
DefWithBody::Static(_) | DefWithBody::Variant(_) | DefWithBody::InTypeConst(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1074,7 +1074,11 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
fn resolve_type(&self, ty: &ast::Type) -> Option<Type> {
|
fn resolve_type(&self, ty: &ast::Type) -> Option<Type> {
|
||||||
let analyze = self.analyze(ty.syntax())?;
|
let analyze = self.analyze(ty.syntax())?;
|
||||||
let ctx = LowerCtx::with_file_id(self.db.upcast(), analyze.file_id);
|
let ctx = LowerCtx::with_file_id(self.db.upcast(), analyze.file_id);
|
||||||
let ty = hir_ty::TyLoweringContext::new(self.db, &analyze.resolver)
|
let ty = hir_ty::TyLoweringContext::new(
|
||||||
|
self.db,
|
||||||
|
&analyze.resolver,
|
||||||
|
analyze.resolver.module().into(),
|
||||||
|
)
|
||||||
.lower_ty(&crate::TypeRef::from_ast(&ctx, ty.clone()));
|
.lower_ty(&crate::TypeRef::from_ast(&ctx, ty.clone()));
|
||||||
Some(Type::new_with_resolver(self.db, &analyze.resolver, ty))
|
Some(Type::new_with_resolver(self.db, &analyze.resolver, ty))
|
||||||
}
|
}
|
||||||
|
@ -978,7 +978,8 @@ fn resolve_hir_path_(
|
|||||||
let types = || {
|
let types = || {
|
||||||
let (ty, unresolved) = match path.type_anchor() {
|
let (ty, unresolved) = match path.type_anchor() {
|
||||||
Some(type_ref) => {
|
Some(type_ref) => {
|
||||||
let (_, res) = TyLoweringContext::new(db, resolver).lower_ty_ext(type_ref);
|
let (_, res) = TyLoweringContext::new(db, resolver, resolver.module().into())
|
||||||
|
.lower_ty_ext(type_ref);
|
||||||
res.map(|ty_ns| (ty_ns, path.segments().first()))
|
res.map(|ty_ns| (ty_ns, path.segments().first()))
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -233,6 +233,7 @@ impl<'a> SymbolCollector<'a> {
|
|||||||
DefWithBodyId::VariantId(id) => {
|
DefWithBodyId::VariantId(id) => {
|
||||||
Some(self.db.enum_data(id.parent).variants[id.local_id].name.to_smol_str())
|
Some(self.db.enum_data(id.parent).variants[id.local_id].name.to_smol_str())
|
||||||
}
|
}
|
||||||
|
DefWithBodyId::InTypeConstId(_) => Some("in type const".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,6 +243,8 @@ impl Definition {
|
|||||||
DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()),
|
DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()),
|
||||||
DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()),
|
DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()),
|
||||||
DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()),
|
DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()),
|
||||||
|
// FIXME: implement
|
||||||
|
DefWithBody::InTypeConst(_) => return SearchScope::empty(),
|
||||||
};
|
};
|
||||||
return match def {
|
return match def {
|
||||||
Some(def) => SearchScope::file_range(def.as_ref().original_file_range_full(db)),
|
Some(def) => SearchScope::file_range(def.as_ref().original_file_range_full(db)),
|
||||||
|
@ -474,7 +474,7 @@ fn main() {
|
|||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9332..9340,
|
range: 9333..9341,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
@ -487,7 +487,7 @@ fn main() {
|
|||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9364..9368,
|
range: 9365..9369,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
@ -511,7 +511,7 @@ fn main() {
|
|||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9332..9340,
|
range: 9333..9341,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
@ -524,7 +524,7 @@ fn main() {
|
|||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9364..9368,
|
range: 9365..9369,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
@ -548,7 +548,7 @@ fn main() {
|
|||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9332..9340,
|
range: 9333..9341,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
@ -561,7 +561,7 @@ fn main() {
|
|||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9364..9368,
|
range: 9365..9369,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -1403,6 +1403,12 @@ fn handle_hack_cargo_workspace(
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
crate_graph.remove_and_replace(fake, original).unwrap();
|
crate_graph.remove_and_replace(fake, original).unwrap();
|
||||||
}
|
}
|
||||||
|
for (_, c) in crate_graph.iter_mut() {
|
||||||
|
if c.origin.is_local() {
|
||||||
|
// LangCrateOrigin::Other is good enough for a hack.
|
||||||
|
c.origin = CrateOrigin::Lang(LangCrateOrigin::Other);
|
||||||
|
}
|
||||||
|
}
|
||||||
sysroot
|
sysroot
|
||||||
.crates()
|
.crates()
|
||||||
.filter_map(|krate| {
|
.filter_map(|krate| {
|
||||||
|
@ -328,14 +328,21 @@ impl flags::AnalysisStats {
|
|||||||
let analysis = host.analysis();
|
let analysis = host.analysis();
|
||||||
for f in funcs.iter().copied() {
|
for f in funcs.iter().copied() {
|
||||||
let name = f.name(db);
|
let name = f.name(db);
|
||||||
let full_name = f
|
let module = f.module(db);
|
||||||
.module(db)
|
let full_name = module
|
||||||
|
.krate()
|
||||||
|
.display_name(db)
|
||||||
|
.map(|x| x.canonical_name().to_string())
|
||||||
|
.into_iter()
|
||||||
|
.chain(
|
||||||
|
module
|
||||||
.path_to_root(db)
|
.path_to_root(db)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.rev()
|
|
||||||
.filter_map(|it| it.name(db))
|
.filter_map(|it| it.name(db))
|
||||||
|
.rev()
|
||||||
.chain(Some(f.name(db)))
|
.chain(Some(f.name(db)))
|
||||||
.map(|it| it.display(db).to_string())
|
.map(|it| it.display(db).to_string()),
|
||||||
|
)
|
||||||
.join("::");
|
.join("::");
|
||||||
if let Some(only_name) = self.only.as_deref() {
|
if let Some(only_name) = self.only.as_deref() {
|
||||||
if name.display(db).to_string() != only_name && full_name != only_name {
|
if name.display(db).to_string() != only_name && full_name != only_name {
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
//! include:
|
//! include:
|
||||||
//! index: sized
|
//! index: sized
|
||||||
//! infallible:
|
//! infallible:
|
||||||
|
//! int_impl: size_of, transmute
|
||||||
//! iterator: option
|
//! iterator: option
|
||||||
//! iterators: iterator, fn
|
//! iterators: iterator, fn
|
||||||
//! manually_drop: drop
|
//! manually_drop: drop
|
||||||
@ -44,6 +45,7 @@
|
|||||||
//! range:
|
//! range:
|
||||||
//! result:
|
//! result:
|
||||||
//! send: sized
|
//! send: sized
|
||||||
|
//! size_of: sized
|
||||||
//! sized:
|
//! sized:
|
||||||
//! slice:
|
//! slice:
|
||||||
//! sync: sized
|
//! sync: sized
|
||||||
@ -345,6 +347,12 @@ pub mod mem {
|
|||||||
pub fn transmute<Src, Dst>(src: Src) -> Dst;
|
pub fn transmute<Src, Dst>(src: Src) -> Dst;
|
||||||
}
|
}
|
||||||
// endregion:transmute
|
// endregion:transmute
|
||||||
|
|
||||||
|
// region:size_of
|
||||||
|
extern "rust-intrinsic" {
|
||||||
|
pub fn size_of<T>() -> usize;
|
||||||
|
}
|
||||||
|
// endregion:size_of
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod ptr {
|
pub mod ptr {
|
||||||
@ -1307,6 +1315,25 @@ impl bool {
|
|||||||
}
|
}
|
||||||
// endregion:bool_impl
|
// endregion:bool_impl
|
||||||
|
|
||||||
|
// region:int_impl
|
||||||
|
macro_rules! impl_int {
|
||||||
|
($($t:ty)*) => {
|
||||||
|
$(
|
||||||
|
impl $t {
|
||||||
|
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
|
||||||
|
unsafe { mem::transmute(bytes) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_int! {
|
||||||
|
usize u8 u16 u32 u64 u128
|
||||||
|
isize i8 i16 i32 i64 i128
|
||||||
|
}
|
||||||
|
// endregion:int_impl
|
||||||
|
|
||||||
// region:error
|
// region:error
|
||||||
pub mod error {
|
pub mod error {
|
||||||
#[rustc_has_incoherent_inherent_impls]
|
#[rustc_has_incoherent_inherent_impls]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user