mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +00:00
Merge commit '457b966b17
' into sync-from-ra
This commit is contained in:
parent
5285df4f6c
commit
f532576ac5
263 changed files with 9788 additions and 6258 deletions
|
@ -1,9 +1,10 @@
|
|||
//! Constant evaluation details
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::{salsa::Cycle, CrateId};
|
||||
use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex};
|
||||
use hir_def::{
|
||||
hir::Expr,
|
||||
body::Body,
|
||||
hir::{Expr, ExprId},
|
||||
path::Path,
|
||||
resolver::{Resolver, ValueNs},
|
||||
type_ref::LiteralConstRef,
|
||||
|
@ -136,7 +137,7 @@ pub fn intern_const_ref(
|
|||
ty: Ty,
|
||||
krate: CrateId,
|
||||
) -> Const {
|
||||
let layout = db.layout_of_ty(ty.clone(), Arc::new(TraitEnvironment::empty(krate)));
|
||||
let layout = db.layout_of_ty(ty.clone(), TraitEnvironment::empty(krate));
|
||||
let bytes = match value {
|
||||
LiteralConstRef::Int(i) => {
|
||||
// FIXME: We should handle failure of layout better.
|
||||
|
@ -184,7 +185,7 @@ pub fn try_const_usize(db: &dyn HirDatabase, c: &Const) -> Option<u128> {
|
|||
|
||||
pub(crate) fn const_eval_recover(
|
||||
_: &dyn HirDatabase,
|
||||
_: &[String],
|
||||
_: &Cycle,
|
||||
_: &GeneralConstId,
|
||||
_: &Substitution,
|
||||
_: &Option<Arc<TraitEnvironment>>,
|
||||
|
@ -194,7 +195,7 @@ pub(crate) fn const_eval_recover(
|
|||
|
||||
pub(crate) fn const_eval_static_recover(
|
||||
_: &dyn HirDatabase,
|
||||
_: &[String],
|
||||
_: &Cycle,
|
||||
_: &StaticId,
|
||||
) -> Result<Const, ConstEvalError> {
|
||||
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
|
||||
|
@ -202,7 +203,7 @@ pub(crate) fn const_eval_static_recover(
|
|||
|
||||
pub(crate) fn const_eval_discriminant_recover(
|
||||
_: &dyn HirDatabase,
|
||||
_: &[String],
|
||||
_: &Cycle,
|
||||
_: &EnumVariantId,
|
||||
) -> Result<i128, ConstEvalError> {
|
||||
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
|
||||
|
@ -280,7 +281,7 @@ pub(crate) fn const_eval_discriminant_variant(
|
|||
// get an `InferenceResult` instead of an `InferenceContext`. And we should remove `ctx.clone().resolve_all()` here
|
||||
// and make this function private. See the fixme comment on `InferenceContext::resolve_all`.
|
||||
pub(crate) fn eval_to_const(
|
||||
expr: Idx<Expr>,
|
||||
expr: ExprId,
|
||||
mode: ParamLoweringMode,
|
||||
ctx: &mut InferenceContext<'_>,
|
||||
args: impl FnOnce() -> Generics,
|
||||
|
@ -288,13 +289,24 @@ pub(crate) fn eval_to_const(
|
|||
) -> Const {
|
||||
let db = ctx.db;
|
||||
let infer = ctx.clone().resolve_all();
|
||||
fn has_closure(body: &Body, expr: ExprId) -> bool {
|
||||
if matches!(body[expr], Expr::Closure { .. }) {
|
||||
return true;
|
||||
}
|
||||
let mut r = false;
|
||||
body[expr].walk_child_exprs(|idx| r |= has_closure(body, idx));
|
||||
r
|
||||
}
|
||||
if has_closure(&ctx.body, expr) {
|
||||
// Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic.
|
||||
return unknown_const(infer[expr].clone());
|
||||
}
|
||||
if let Expr::Path(p) = &ctx.body.exprs[expr] {
|
||||
let resolver = &ctx.resolver;
|
||||
if let Some(c) = path_to_const(db, resolver, p, mode, args, debruijn, infer[expr].clone()) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
let infer = ctx.clone().resolve_all();
|
||||
if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, &ctx.body, &infer, expr) {
|
||||
if let Ok(result) = interpret_mir(db, Arc::new(mir_body), true, None).0 {
|
||||
return result;
|
||||
|
|
|
@ -24,7 +24,7 @@ use hir_def::{
|
|||
};
|
||||
use hir_expand::{
|
||||
name::{AsName, Name},
|
||||
HirFileId,
|
||||
HirFileId, MacroFileIdExt,
|
||||
};
|
||||
use stdx::{always, never};
|
||||
use syntax::{
|
||||
|
@ -196,7 +196,7 @@ impl<'a> DeclValidator<'a> {
|
|||
AttrDefId::GenericParamId(_) => None,
|
||||
}
|
||||
.map_or(false, |file_id| {
|
||||
file_id.is_custom_derive(db.upcast()) || file_id.is_builtin_derive(db.upcast())
|
||||
matches!(file_id.macro_file(), Some(file_id) if file_id.is_custom_derive(db.upcast()) || file_id.is_builtin_derive(db.upcast()))
|
||||
})
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ use hir_def::{
|
|||
EnumVariantId, HasModule, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, ModuleId,
|
||||
TraitId,
|
||||
};
|
||||
use hir_expand::{hygiene::Hygiene, name::Name};
|
||||
use hir_expand::name::Name;
|
||||
use intern::{Internable, Interned};
|
||||
use itertools::Itertools;
|
||||
use la_arena::ArenaMap;
|
||||
|
@ -448,9 +448,8 @@ fn render_const_scalar(
|
|||
) -> Result<(), HirDisplayError> {
|
||||
// FIXME: We need to get krate from the final callers of the hir display
|
||||
// infrastructure and have it here as a field on `f`.
|
||||
let trait_env = Arc::new(TraitEnvironment::empty(
|
||||
*f.db.crate_graph().crates_in_topological_order().last().unwrap(),
|
||||
));
|
||||
let trait_env =
|
||||
TraitEnvironment::empty(*f.db.crate_graph().crates_in_topological_order().last().unwrap());
|
||||
match ty.kind(Interner) {
|
||||
TyKind::Scalar(s) => match s {
|
||||
Scalar::Bool => write!(f, "{}", if b[0] == 0 { false } else { true }),
|
||||
|
@ -1732,13 +1731,13 @@ impl HirDisplay for TypeRef {
|
|||
f.write_joined(bounds, " + ")?;
|
||||
}
|
||||
TypeRef::Macro(macro_call) => {
|
||||
let macro_call = macro_call.to_node(f.db.upcast());
|
||||
let ctx = hir_def::lower::LowerCtx::with_hygiene(
|
||||
let ctx = hir_def::lower::LowerCtx::with_span_map(
|
||||
f.db.upcast(),
|
||||
&Hygiene::new_unhygienic(),
|
||||
f.db.span_map(macro_call.file_id),
|
||||
);
|
||||
let macro_call = macro_call.to_node(f.db.upcast());
|
||||
match macro_call.path() {
|
||||
Some(path) => match Path::from_src(path, &ctx) {
|
||||
Some(path) => match Path::from_src(&ctx, path) {
|
||||
Some(path) => path.hir_fmt(f)?,
|
||||
None => write!(f, "{{macro}}")?,
|
||||
},
|
||||
|
|
|
@ -18,7 +18,6 @@ use hir_def::{
|
|||
use hir_expand::name::{name, Name};
|
||||
use stdx::always;
|
||||
use syntax::ast::RangeOp;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
autoderef::{builtin_deref, deref_by_trait, Autoderef},
|
||||
|
@ -40,7 +39,8 @@ use crate::{
|
|||
traits::FnTrait,
|
||||
utils::{generics, Generics},
|
||||
Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, FnPointer, FnSig, FnSubst,
|
||||
Interner, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
|
||||
Interner, Rawness, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt,
|
||||
TyKind,
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
@ -579,7 +579,7 @@ impl InferenceContext<'_> {
|
|||
}
|
||||
ty
|
||||
}
|
||||
Expr::Field { expr, name } => self.infer_field_access(tgt_expr, *expr, name),
|
||||
Expr::Field { expr, name } => self.infer_field_access(tgt_expr, *expr, name, expected),
|
||||
Expr::Await { expr } => {
|
||||
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
|
||||
self.resolve_associated_type(inner_ty, self.resolve_future_future_output())
|
||||
|
@ -1291,7 +1291,7 @@ impl InferenceContext<'_> {
|
|||
let g = self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr);
|
||||
let prev_env = block_id.map(|block_id| {
|
||||
let prev_env = self.table.trait_env.clone();
|
||||
Arc::make_mut(&mut self.table.trait_env).block = Some(block_id);
|
||||
TraitEnvironment::with_block(&mut self.table.trait_env, block_id);
|
||||
prev_env
|
||||
});
|
||||
|
||||
|
@ -1456,7 +1456,13 @@ impl InferenceContext<'_> {
|
|||
})
|
||||
}
|
||||
|
||||
fn infer_field_access(&mut self, tgt_expr: ExprId, receiver: ExprId, name: &Name) -> Ty {
|
||||
fn infer_field_access(
|
||||
&mut self,
|
||||
tgt_expr: ExprId,
|
||||
receiver: ExprId,
|
||||
name: &Name,
|
||||
expected: &Expectation,
|
||||
) -> Ty {
|
||||
let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none());
|
||||
|
||||
if name.is_missing() {
|
||||
|
@ -1482,28 +1488,42 @@ impl InferenceContext<'_> {
|
|||
ty
|
||||
}
|
||||
None => {
|
||||
// no field found,
|
||||
let method_with_same_name_exists = {
|
||||
self.get_traits_in_scope();
|
||||
|
||||
let canonicalized_receiver = self.canonicalize(receiver_ty.clone());
|
||||
method_resolution::lookup_method(
|
||||
self.db,
|
||||
&canonicalized_receiver.value,
|
||||
self.table.trait_env.clone(),
|
||||
self.get_traits_in_scope().as_ref().left_or_else(|&it| it),
|
||||
VisibleFromModule::Filter(self.resolver.module()),
|
||||
name,
|
||||
)
|
||||
.is_some()
|
||||
};
|
||||
// no field found, lets attempt to resolve it like a function so that IDE things
|
||||
// work out while people are typing
|
||||
let canonicalized_receiver = self.canonicalize(receiver_ty.clone());
|
||||
let resolved = method_resolution::lookup_method(
|
||||
self.db,
|
||||
&canonicalized_receiver.value,
|
||||
self.table.trait_env.clone(),
|
||||
self.get_traits_in_scope().as_ref().left_or_else(|&it| it),
|
||||
VisibleFromModule::Filter(self.resolver.module()),
|
||||
name,
|
||||
);
|
||||
self.result.diagnostics.push(InferenceDiagnostic::UnresolvedField {
|
||||
expr: tgt_expr,
|
||||
receiver: receiver_ty,
|
||||
receiver: receiver_ty.clone(),
|
||||
name: name.clone(),
|
||||
method_with_same_name_exists,
|
||||
method_with_same_name_exists: resolved.is_some(),
|
||||
});
|
||||
self.err_ty()
|
||||
match resolved {
|
||||
Some((adjust, func, _)) => {
|
||||
let (ty, adjustments) = adjust.apply(&mut self.table, receiver_ty);
|
||||
let generics = generics(self.db.upcast(), func.into());
|
||||
let substs = self.substs_for_method_call(generics, None);
|
||||
self.write_expr_adj(receiver, adjustments);
|
||||
self.write_method_resolution(tgt_expr, func, substs.clone());
|
||||
|
||||
self.check_method_call(
|
||||
tgt_expr,
|
||||
&[],
|
||||
self.db.value_ty(func.into()),
|
||||
substs,
|
||||
ty,
|
||||
expected,
|
||||
)
|
||||
}
|
||||
None => self.err_ty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1517,7 +1537,7 @@ impl InferenceContext<'_> {
|
|||
generic_args: Option<&GenericArgs>,
|
||||
expected: &Expectation,
|
||||
) -> Ty {
|
||||
let receiver_ty = self.infer_expr(receiver, &Expectation::none());
|
||||
let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none());
|
||||
let canonicalized_receiver = self.canonicalize(receiver_ty.clone());
|
||||
|
||||
let resolved = method_resolution::lookup_method(
|
||||
|
@ -1568,23 +1588,32 @@ impl InferenceContext<'_> {
|
|||
)
|
||||
}
|
||||
};
|
||||
self.check_method_call(tgt_expr, args, method_ty, substs, receiver_ty, expected)
|
||||
}
|
||||
|
||||
fn check_method_call(
|
||||
&mut self,
|
||||
tgt_expr: ExprId,
|
||||
args: &[ExprId],
|
||||
method_ty: Binders<Ty>,
|
||||
substs: Substitution,
|
||||
receiver_ty: Ty,
|
||||
expected: &Expectation,
|
||||
) -> Ty {
|
||||
let method_ty = method_ty.substitute(Interner, &substs);
|
||||
self.register_obligations_for_call(&method_ty);
|
||||
let (formal_receiver_ty, param_tys, ret_ty, is_varargs) =
|
||||
let ((formal_receiver_ty, param_tys), ret_ty, is_varargs) =
|
||||
match method_ty.callable_sig(self.db) {
|
||||
Some(sig) => {
|
||||
Some(sig) => (
|
||||
if !sig.params().is_empty() {
|
||||
(
|
||||
sig.params()[0].clone(),
|
||||
sig.params()[1..].to_vec(),
|
||||
sig.ret().clone(),
|
||||
sig.is_varargs,
|
||||
)
|
||||
(sig.params()[0].clone(), sig.params()[1..].to_vec())
|
||||
} else {
|
||||
(self.err_ty(), Vec::new(), sig.ret().clone(), sig.is_varargs)
|
||||
}
|
||||
}
|
||||
None => (self.err_ty(), Vec::new(), self.err_ty(), true),
|
||||
(self.err_ty(), Vec::new())
|
||||
},
|
||||
sig.ret().clone(),
|
||||
sig.is_varargs,
|
||||
),
|
||||
None => ((self.err_ty(), Vec::new()), self.err_ty(), true),
|
||||
};
|
||||
self.unify(&formal_receiver_ty, &receiver_ty);
|
||||
|
||||
|
|
|
@ -390,6 +390,7 @@ impl InferenceContext<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ValuePathResolution {
|
||||
// It's awkward to wrap a single ID in two enums, but we need both and this saves fallible
|
||||
// conversion between them + `unwrap()`.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use base_db::salsa::Cycle;
|
||||
use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
|
||||
use hir_def::{
|
||||
layout::{
|
||||
|
@ -431,7 +432,7 @@ pub fn layout_of_ty_query(
|
|||
|
||||
pub fn layout_of_ty_recover(
|
||||
_: &dyn HirDatabase,
|
||||
_: &[String],
|
||||
_: &Cycle,
|
||||
_: &Ty,
|
||||
_: &Arc<TraitEnvironment>,
|
||||
) -> Result<Arc<Layout>, LayoutError> {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use std::{cmp, ops::Bound};
|
||||
|
||||
use base_db::salsa::Cycle;
|
||||
use hir_def::{
|
||||
data::adt::VariantData,
|
||||
layout::{Integer, LayoutCalculator, ReprOptions, TargetDataLayout},
|
||||
|
@ -140,7 +141,7 @@ fn layout_scalar_valid_range(db: &dyn HirDatabase, def: AdtId) -> (Bound<u128>,
|
|||
|
||||
pub fn layout_of_adt_recover(
|
||||
_: &dyn HirDatabase,
|
||||
_: &[String],
|
||||
_: &Cycle,
|
||||
_: &AdtId,
|
||||
_: &Substitution,
|
||||
_: &Arc<TraitEnvironment>,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! The type system. We currently use this to infer types for completion, hover
|
||||
//! information and various assists.
|
||||
#![warn(rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros)]
|
||||
#![warn(rust_2018_idioms, unused_lifetimes)]
|
||||
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
|
||||
|
||||
#[allow(unused)]
|
||||
|
@ -73,8 +73,8 @@ pub use infer::{
|
|||
};
|
||||
pub use interner::Interner;
|
||||
pub use lower::{
|
||||
associated_type_shorthand_candidates, CallableDefId, ImplTraitLoweringMode, TyDefId,
|
||||
TyLoweringContext, ValueTyDefId,
|
||||
associated_type_shorthand_candidates, CallableDefId, ImplTraitLoweringMode, ParamLoweringMode,
|
||||
TyDefId, TyLoweringContext, ValueTyDefId,
|
||||
};
|
||||
pub use mapping::{
|
||||
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
|
||||
|
@ -122,7 +122,7 @@ pub type TyKind = chalk_ir::TyKind<Interner>;
|
|||
pub type TypeFlags = chalk_ir::TypeFlags;
|
||||
pub type DynTy = chalk_ir::DynTy<Interner>;
|
||||
pub type FnPointer = chalk_ir::FnPointer<Interner>;
|
||||
// pub type FnSubst = chalk_ir::FnSubst<Interner>;
|
||||
// pub type FnSubst = chalk_ir::FnSubst<Interner>; // a re-export so we don't lose the tuple constructor
|
||||
pub use chalk_ir::FnSubst;
|
||||
pub type ProjectionTy = chalk_ir::ProjectionTy<Interner>;
|
||||
pub type AliasTy = chalk_ir::AliasTy<Interner>;
|
||||
|
@ -322,8 +322,7 @@ impl CallableSig {
|
|||
pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
|
||||
CallableSig {
|
||||
// FIXME: what to do about lifetime params? -> return PolyFnSig
|
||||
// FIXME: use `Arc::from_iter` when it becomes available
|
||||
params_and_return: Arc::from(
|
||||
params_and_return: Arc::from_iter(
|
||||
fn_ptr
|
||||
.substitution
|
||||
.clone()
|
||||
|
@ -332,8 +331,7 @@ impl CallableSig {
|
|||
.0
|
||||
.as_slice(Interner)
|
||||
.iter()
|
||||
.map(|arg| arg.assert_ty_ref(Interner).clone())
|
||||
.collect::<Vec<_>>(),
|
||||
.map(|arg| arg.assert_ty_ref(Interner).clone()),
|
||||
),
|
||||
is_varargs: fn_ptr.sig.variadic,
|
||||
safety: fn_ptr.sig.safety,
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::{
|
|||
iter,
|
||||
};
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::{salsa::Cycle, CrateId};
|
||||
use chalk_ir::{
|
||||
cast::Cast, fold::Shift, fold::TypeFoldable, interner::HasInterner, Mutability, Safety,
|
||||
};
|
||||
|
@ -407,11 +407,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
drop(expander);
|
||||
let ty = self.lower_ty(&type_ref);
|
||||
|
||||
self.expander
|
||||
.borrow_mut()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.exit(self.db.upcast(), mark);
|
||||
self.expander.borrow_mut().as_mut().unwrap().exit(mark);
|
||||
Some(ty)
|
||||
}
|
||||
_ => {
|
||||
|
@ -1458,13 +1454,12 @@ pub(crate) fn generic_predicates_for_param_query(
|
|||
|
||||
pub(crate) fn generic_predicates_for_param_recover(
|
||||
_db: &dyn HirDatabase,
|
||||
_cycle: &[String],
|
||||
_cycle: &Cycle,
|
||||
_def: &GenericDefId,
|
||||
_param_id: &TypeOrConstParamId,
|
||||
_assoc_name: &Option<Name>,
|
||||
) -> Arc<[Binders<QuantifiedWhereClause>]> {
|
||||
// FIXME: use `Arc::from_iter` when it becomes available
|
||||
Arc::from(vec![])
|
||||
Arc::from_iter(None)
|
||||
}
|
||||
|
||||
pub(crate) fn trait_environment_for_body_query(
|
||||
|
@ -1473,7 +1468,7 @@ pub(crate) fn trait_environment_for_body_query(
|
|||
) -> Arc<TraitEnvironment> {
|
||||
let Some(def) = def.as_generic_def_id() else {
|
||||
let krate = def.module(db.upcast()).krate();
|
||||
return Arc::new(TraitEnvironment::empty(krate));
|
||||
return TraitEnvironment::empty(krate);
|
||||
};
|
||||
db.trait_environment(def)
|
||||
}
|
||||
|
@ -1533,12 +1528,7 @@ pub(crate) fn trait_environment_query(
|
|||
|
||||
let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
|
||||
|
||||
Arc::new(TraitEnvironment {
|
||||
krate,
|
||||
block: None,
|
||||
traits_from_clauses: traits_in_scope.into_boxed_slice(),
|
||||
env,
|
||||
})
|
||||
TraitEnvironment::new(krate, None, traits_in_scope.into_boxed_slice(), env)
|
||||
}
|
||||
|
||||
/// Resolve the where clause(s) of an item with generics.
|
||||
|
@ -1607,69 +1597,54 @@ pub(crate) fn generic_defaults_query(
|
|||
let generic_params = generics(db.upcast(), def);
|
||||
let parent_start_idx = generic_params.len_self();
|
||||
|
||||
let defaults = Arc::from(
|
||||
generic_params
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, (id, p))| {
|
||||
match p {
|
||||
TypeOrConstParamData::TypeParamData(p) => {
|
||||
let mut ty = p
|
||||
.default
|
||||
.as_ref()
|
||||
.map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
|
||||
// Each default can only refer to previous parameters.
|
||||
// Type variable default referring to parameter coming
|
||||
// after it is forbidden (FIXME: report diagnostic)
|
||||
ty = fallback_bound_vars(ty, idx, parent_start_idx);
|
||||
crate::make_binders(db, &generic_params, ty.cast(Interner))
|
||||
}
|
||||
TypeOrConstParamData::ConstParamData(p) => {
|
||||
let mut val = p.default.as_ref().map_or_else(
|
||||
|| {
|
||||
unknown_const_as_generic(
|
||||
db.const_param_ty(ConstParamId::from_unchecked(id)),
|
||||
)
|
||||
},
|
||||
|c| {
|
||||
let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
|
||||
c.cast(Interner)
|
||||
},
|
||||
);
|
||||
// Each default can only refer to previous parameters, see above.
|
||||
val = fallback_bound_vars(val, idx, parent_start_idx);
|
||||
make_binders(db, &generic_params, val)
|
||||
}
|
||||
}
|
||||
})
|
||||
// FIXME: use `Arc::from_iter` when it becomes available
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
let defaults = Arc::from_iter(generic_params.iter().enumerate().map(|(idx, (id, p))| {
|
||||
match p {
|
||||
TypeOrConstParamData::TypeParamData(p) => {
|
||||
let mut ty =
|
||||
p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
|
||||
// Each default can only refer to previous parameters.
|
||||
// Type variable default referring to parameter coming
|
||||
// after it is forbidden (FIXME: report diagnostic)
|
||||
ty = fallback_bound_vars(ty, idx, parent_start_idx);
|
||||
crate::make_binders(db, &generic_params, ty.cast(Interner))
|
||||
}
|
||||
TypeOrConstParamData::ConstParamData(p) => {
|
||||
let mut val = p.default.as_ref().map_or_else(
|
||||
|| {
|
||||
unknown_const_as_generic(
|
||||
db.const_param_ty(ConstParamId::from_unchecked(id)),
|
||||
)
|
||||
},
|
||||
|c| {
|
||||
let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
|
||||
c.cast(Interner)
|
||||
},
|
||||
);
|
||||
// Each default can only refer to previous parameters, see above.
|
||||
val = fallback_bound_vars(val, idx, parent_start_idx);
|
||||
make_binders(db, &generic_params, val)
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
defaults
|
||||
}
|
||||
|
||||
pub(crate) fn generic_defaults_recover(
|
||||
db: &dyn HirDatabase,
|
||||
_cycle: &[String],
|
||||
_cycle: &Cycle,
|
||||
def: &GenericDefId,
|
||||
) -> Arc<[Binders<crate::GenericArg>]> {
|
||||
let generic_params = generics(db.upcast(), *def);
|
||||
// FIXME: this code is not covered in tests.
|
||||
// we still need one default per parameter
|
||||
let defaults = Arc::from(
|
||||
generic_params
|
||||
.iter_id()
|
||||
.map(|id| {
|
||||
let val = match id {
|
||||
Either::Left(_) => TyKind::Error.intern(Interner).cast(Interner),
|
||||
Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
|
||||
};
|
||||
crate::make_binders(db, &generic_params, val)
|
||||
})
|
||||
// FIXME: use `Arc::from_iter` when it becomes available
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
let defaults = Arc::from_iter(generic_params.iter_id().map(|id| {
|
||||
let val = match id {
|
||||
Either::Left(_) => TyKind::Error.intern(Interner).cast(Interner),
|
||||
Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
|
||||
};
|
||||
crate::make_binders(db, &generic_params, val)
|
||||
}));
|
||||
|
||||
defaults
|
||||
}
|
||||
|
@ -1885,7 +1860,7 @@ pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
|
||||
pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &Cycle, def: &TyDefId) -> Binders<Ty> {
|
||||
let generics = match *def {
|
||||
TyDefId::BuiltinType(_) => return Binders::empty(Interner, TyKind::Error.intern(Interner)),
|
||||
TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
|
||||
|
@ -1935,7 +1910,7 @@ pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> T
|
|||
|
||||
pub(crate) fn impl_self_ty_recover(
|
||||
db: &dyn HirDatabase,
|
||||
_cycle: &[String],
|
||||
_cycle: &Cycle,
|
||||
impl_id: &ImplId,
|
||||
) -> Binders<Ty> {
|
||||
let generics = generics(db.upcast(), (*impl_id).into());
|
||||
|
|
|
@ -168,12 +168,9 @@ impl TraitImpls {
|
|||
) -> Arc<[Arc<Self>]> {
|
||||
let _p = profile::span("trait_impls_in_deps_query").detail(|| format!("{krate:?}"));
|
||||
let crate_graph = db.crate_graph();
|
||||
// FIXME: use `Arc::from_iter` when it becomes available
|
||||
Arc::from(
|
||||
crate_graph
|
||||
.transitive_deps(krate)
|
||||
.map(|krate| db.trait_impls_in_crate(krate))
|
||||
.collect::<Vec<_>>(),
|
||||
|
||||
Arc::from_iter(
|
||||
crate_graph.transitive_deps(krate).map(|krate| db.trait_impls_in_crate(krate)),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ pub use monomorphization::{
|
|||
use rustc_hash::FxHashMap;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use stdx::{impl_from, never};
|
||||
use triomphe::Arc;
|
||||
|
||||
use super::consteval::{intern_const_scalar, try_const_usize};
|
||||
|
||||
|
@ -147,7 +146,7 @@ impl<V, T> ProjectionElem<V, T> {
|
|||
base = normalize(
|
||||
db,
|
||||
// FIXME: we should get this from caller
|
||||
Arc::new(TraitEnvironment::empty(krate)),
|
||||
TraitEnvironment::empty(krate),
|
||||
base,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ use hir_def::{
|
|||
AdtId, ConstId, DefWithBodyId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup,
|
||||
StaticId, VariantId,
|
||||
};
|
||||
use hir_expand::{mod_path::ModPath, InFile};
|
||||
use hir_expand::{mod_path::ModPath, HirFileIdExt, InFile};
|
||||
use intern::Interned;
|
||||
use la_arena::ArenaMap;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{fmt::Write, iter, mem};
|
||||
|
||||
use base_db::FileId;
|
||||
use base_db::{salsa::Cycle, FileId};
|
||||
use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind};
|
||||
use hir_def::{
|
||||
body::Body,
|
||||
|
@ -2110,7 +2110,7 @@ pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<Mi
|
|||
|
||||
pub fn mir_body_recover(
|
||||
_db: &dyn HirDatabase,
|
||||
_cycle: &[String],
|
||||
_cycle: &Cycle,
|
||||
_def: &DefWithBodyId,
|
||||
) -> Result<Arc<MirBody>> {
|
||||
Err(MirLowerError::Loop)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
use std::mem;
|
||||
|
||||
use base_db::salsa::Cycle;
|
||||
use chalk_ir::{
|
||||
fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable},
|
||||
ConstData, DebruijnIndex,
|
||||
|
@ -300,7 +301,7 @@ pub fn monomorphized_mir_body_query(
|
|||
|
||||
pub fn monomorphized_mir_body_recover(
|
||||
_: &dyn HirDatabase,
|
||||
_: &[String],
|
||||
_: &Cycle,
|
||||
_: &DefWithBodyId,
|
||||
_: &Substitution,
|
||||
_: &Arc<crate::TraitEnvironment>,
|
||||
|
|
|
@ -30,6 +30,7 @@ pub(crate) struct TestDB {
|
|||
impl Default for TestDB {
|
||||
fn default() -> Self {
|
||||
let mut this = Self { storage: Default::default(), events: Default::default() };
|
||||
this.setup_syntax_context_root();
|
||||
this.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH);
|
||||
this
|
||||
}
|
||||
|
|
|
@ -2000,3 +2000,15 @@ fn test() {
|
|||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rustc_test_issue_52437() {
|
||||
check_types(
|
||||
r#"
|
||||
fn main() {
|
||||
let x = [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
|
||||
//^ [(); _]
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -48,18 +48,32 @@ pub struct TraitEnvironment {
|
|||
pub krate: CrateId,
|
||||
pub block: Option<BlockId>,
|
||||
// FIXME make this a BTreeMap
|
||||
pub(crate) traits_from_clauses: Box<[(Ty, TraitId)]>,
|
||||
traits_from_clauses: Box<[(Ty, TraitId)]>,
|
||||
pub env: chalk_ir::Environment<Interner>,
|
||||
}
|
||||
|
||||
impl TraitEnvironment {
|
||||
pub fn empty(krate: CrateId) -> Self {
|
||||
TraitEnvironment {
|
||||
pub fn empty(krate: CrateId) -> Arc<Self> {
|
||||
Arc::new(TraitEnvironment {
|
||||
krate,
|
||||
block: None,
|
||||
traits_from_clauses: Box::default(),
|
||||
env: chalk_ir::Environment::new(Interner),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
krate: CrateId,
|
||||
block: Option<BlockId>,
|
||||
traits_from_clauses: Box<[(Ty, TraitId)]>,
|
||||
env: chalk_ir::Environment<Interner>,
|
||||
) -> Arc<Self> {
|
||||
Arc::new(TraitEnvironment { krate, block, traits_from_clauses, env })
|
||||
}
|
||||
|
||||
// pub fn with_block(self: &mut Arc<Self>, block: BlockId) {
|
||||
pub fn with_block(this: &mut Arc<Self>, block: BlockId) {
|
||||
Arc::make_mut(this).block = Some(block);
|
||||
}
|
||||
|
||||
pub fn traits_in_scope_from_clauses(&self, ty: Ty) -> impl Iterator<Item = TraitId> + '_ {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue