Merge commit '457b966b17' into sync-from-ra

This commit is contained in:
Laurențiu Nicola 2023-12-11 11:16:01 +02:00
parent 5285df4f6c
commit f532576ac5
263 changed files with 9788 additions and 6258 deletions

View file

@ -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;

View file

@ -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()))
})
};

View file

@ -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}}")?,
},

View file

@ -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);

View file

@ -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()`.

View file

@ -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> {

View file

@ -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>,

View file

@ -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,

View file

@ -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());

View file

@ -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)),
)
}

View file

@ -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,
);
}

View file

@ -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};

View file

@ -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)

View file

@ -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>,

View file

@ -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
}

View file

@ -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]
//^ [(); _]
}
"#,
);
}

View file

@ -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> + '_ {