Merge from rustc
This commit is contained in:
commit
d5feca99d6
493 changed files with 8190 additions and 2263 deletions
75
Cargo.lock
75
Cargo.lock
|
|
@ -638,7 +638,7 @@ dependencies = [
|
|||
"filetime",
|
||||
"futures",
|
||||
"if_chain",
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"parking_lot",
|
||||
"quote",
|
||||
"regex",
|
||||
|
|
@ -670,7 +670,7 @@ dependencies = [
|
|||
"aho-corasick",
|
||||
"clap",
|
||||
"indoc",
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"opener 0.6.1",
|
||||
"shell-escape",
|
||||
"walkdir",
|
||||
|
|
@ -685,7 +685,7 @@ dependencies = [
|
|||
"clippy_config",
|
||||
"clippy_utils",
|
||||
"declare_clippy_lint",
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"quine-mc_cluskey",
|
||||
"regex",
|
||||
"regex-syntax 0.8.4",
|
||||
|
|
@ -707,7 +707,7 @@ version = "0.1.81"
|
|||
dependencies = [
|
||||
"arrayvec",
|
||||
"clippy_config",
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"rustc-semver",
|
||||
"rustc_apfloat",
|
||||
]
|
||||
|
|
@ -1026,7 +1026,7 @@ dependencies = [
|
|||
name = "declare_clippy_lint"
|
||||
version = "0.1.81"
|
||||
dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
|
@ -1133,16 +1133,16 @@ version = "5.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
||||
dependencies = [
|
||||
"dirs-sys 0.4.1",
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "4.0.0"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
dependencies = [
|
||||
"dirs-sys 0.3.7",
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1155,17 +1155,6 @@ dependencies = [
|
|||
"dirs-sys-next",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
|
|
@ -2076,15 +2065,6 @@ version = "1.70.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
|
|
@ -2227,7 +2207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.48.5",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3665,7 +3645,7 @@ dependencies = [
|
|||
name = "rustc_ast_passes"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"rustc_ast",
|
||||
"rustc_ast_pretty",
|
||||
"rustc_attr",
|
||||
|
|
@ -3685,7 +3665,7 @@ dependencies = [
|
|||
name = "rustc_ast_pretty"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"rustc_ast",
|
||||
"rustc_lexer",
|
||||
"rustc_span",
|
||||
|
|
@ -3726,7 +3706,7 @@ name = "rustc_borrowck"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"either",
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"polonius-engine",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
|
|
@ -3779,7 +3759,7 @@ name = "rustc_codegen_llvm"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"libc",
|
||||
"measureme",
|
||||
"object 0.32.2",
|
||||
|
|
@ -3818,7 +3798,7 @@ dependencies = [
|
|||
"bitflags 2.5.0",
|
||||
"cc",
|
||||
"either",
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"jobserver",
|
||||
"libc",
|
||||
"object 0.32.2",
|
||||
|
|
@ -4098,7 +4078,7 @@ dependencies = [
|
|||
name = "rustc_hir_analysis"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
"rustc_attr",
|
||||
|
|
@ -4137,7 +4117,7 @@ dependencies = [
|
|||
name = "rustc_hir_typeck"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"rustc_ast",
|
||||
"rustc_ast_ir",
|
||||
"rustc_attr",
|
||||
|
|
@ -4421,7 +4401,7 @@ dependencies = [
|
|||
name = "rustc_mir_build"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"rustc_apfloat",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
|
|
@ -4468,7 +4448,7 @@ name = "rustc_mir_transform"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"either",
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
"rustc_attr",
|
||||
|
|
@ -4762,6 +4742,7 @@ dependencies = [
|
|||
name = "rustc_span"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"md-5",
|
||||
|
|
@ -4823,7 +4804,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"derivative",
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"rustc_ast",
|
||||
"rustc_ast_ir",
|
||||
"rustc_attr",
|
||||
|
|
@ -4866,7 +4847,7 @@ dependencies = [
|
|||
name = "rustc_transmute"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
"rustc_hir",
|
||||
|
|
@ -4882,7 +4863,7 @@ dependencies = [
|
|||
name = "rustc_ty_utils"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
|
|
@ -4946,7 +4927,7 @@ dependencies = [
|
|||
"base64",
|
||||
"expect-test",
|
||||
"indexmap",
|
||||
"itertools 0.12.1",
|
||||
"itertools",
|
||||
"minifier",
|
||||
"regex",
|
||||
"rustdoc-json-types",
|
||||
|
|
@ -5027,20 +5008,19 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustfmt-nightly"
|
||||
version = "1.7.0"
|
||||
version = "1.7.1"
|
||||
dependencies = [
|
||||
"annotate-snippets 0.9.2",
|
||||
"anyhow",
|
||||
"bytecount",
|
||||
"cargo_metadata 0.15.4",
|
||||
"cargo_metadata 0.18.1",
|
||||
"clap",
|
||||
"clap-cargo",
|
||||
"diff",
|
||||
"dirs",
|
||||
"getopts",
|
||||
"ignore",
|
||||
"itertools 0.11.0",
|
||||
"lazy_static",
|
||||
"itertools",
|
||||
"regex",
|
||||
"rustfmt-config_proc_macro",
|
||||
"serde",
|
||||
|
|
@ -5699,6 +5679,7 @@ name = "tidy"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cargo_metadata 0.15.4",
|
||||
"fluent-syntax",
|
||||
"ignore",
|
||||
"miropt-test-tools",
|
||||
"regex",
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ ast_lowering_inline_asm_unsupported_target =
|
|||
ast_lowering_invalid_abi =
|
||||
invalid ABI: found `{$abi}`
|
||||
.label = invalid ABI
|
||||
.note = invoke `{$command}` for a full list of supported calling conventions.
|
||||
.note = invoke `{$command}` for a full list of supported calling conventions
|
||||
|
||||
ast_lowering_invalid_abi_clobber_abi =
|
||||
invalid ABI for `clobber_abi`
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetim
|
|||
|
||||
ast_passes_bad_c_variadic = only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
|
||||
ast_passes_bare_fn_invalid_safety = function pointers cannot be declared with `safe` safety qualifier
|
||||
.suggestion = remove safe from this item
|
||||
|
||||
ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
|
||||
.cannot_have = cannot have a body
|
||||
.invalid = the invalid body
|
||||
|
|
@ -167,6 +170,9 @@ ast_passes_invalid_unnamed_field_ty =
|
|||
unnamed fields can only have struct or union types
|
||||
.label = not a struct or union
|
||||
|
||||
ast_passes_item_invalid_safety = items outside of `unsafe extern {"{ }"}` cannot be declared with `safe` safety qualifier
|
||||
.suggestion = remove safe from this item
|
||||
|
||||
ast_passes_item_underscore = `{$kind}` items in this context need a name
|
||||
.label = `_` is not a valid name for this `{$kind}` item
|
||||
|
||||
|
|
|
|||
|
|
@ -456,15 +456,29 @@ impl<'a> AstValidator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_foreign_item_safety(&self, item_span: Span, safety: Safety) {
|
||||
if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
|
||||
&& (self.extern_mod_safety == Some(Safety::Default)
|
||||
|| !self.features.unsafe_extern_blocks)
|
||||
{
|
||||
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
|
||||
item_span,
|
||||
block: self.current_extern_span(),
|
||||
});
|
||||
fn check_item_safety(&self, span: Span, safety: Safety) {
|
||||
match self.extern_mod_safety {
|
||||
Some(extern_safety) => {
|
||||
if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
|
||||
&& (extern_safety == Safety::Default || !self.features.unsafe_extern_blocks)
|
||||
{
|
||||
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
|
||||
item_span: span,
|
||||
block: self.current_extern_span(),
|
||||
});
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if matches!(safety, Safety::Safe(_)) {
|
||||
self.dcx().emit_err(errors::InvalidSafetyOnItem { span });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_bare_fn_safety(&self, span: Span, safety: Safety) {
|
||||
if matches!(safety, Safety::Safe(_)) {
|
||||
self.dcx().emit_err(errors::InvalidSafetyOnBareFn { span });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -746,6 +760,7 @@ impl<'a> AstValidator<'a> {
|
|||
fn visit_ty_common(&mut self, ty: &'a Ty) {
|
||||
match &ty.kind {
|
||||
TyKind::BareFn(bfty) => {
|
||||
self.check_bare_fn_safety(bfty.decl_span, bfty.safety);
|
||||
self.check_fn_decl(&bfty.decl, SelfSemantic::No);
|
||||
Self::check_decl_no_pat(&bfty.decl, |span, _, _| {
|
||||
self.dcx().emit_err(errors::PatternFnPointer { span });
|
||||
|
|
@ -1174,11 +1189,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
});
|
||||
}
|
||||
}
|
||||
ItemKind::Static(box StaticItem { expr: None, .. }) => {
|
||||
self.dcx().emit_err(errors::StaticWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
ItemKind::Static(box StaticItem { expr, safety, .. }) => {
|
||||
self.check_item_safety(item.span, *safety);
|
||||
|
||||
if expr.is_none() {
|
||||
self.dcx().emit_err(errors::StaticWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
}
|
||||
ItemKind::TyAlias(
|
||||
ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. },
|
||||
|
|
@ -1212,7 +1231,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
|
||||
match &fi.kind {
|
||||
ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => {
|
||||
self.check_foreign_item_safety(fi.span, sig.header.safety);
|
||||
self.check_defaultness(fi.span, *defaultness);
|
||||
self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
|
||||
self.check_foreign_fn_headerless(sig.header);
|
||||
|
|
@ -1233,7 +1251,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
self.check_foreign_item_ascii_only(fi.ident);
|
||||
}
|
||||
ForeignItemKind::Static(box StaticItem { expr, safety, .. }) => {
|
||||
self.check_foreign_item_safety(fi.span, *safety);
|
||||
self.check_item_safety(fi.span, *safety);
|
||||
self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span));
|
||||
self.check_foreign_item_ascii_only(fi.ident);
|
||||
}
|
||||
|
|
@ -1453,6 +1471,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
};
|
||||
self.check_fn_decl(fk.decl(), self_semantic);
|
||||
|
||||
if let Some(&FnHeader { safety, .. }) = fk.header() {
|
||||
self.check_item_safety(span, safety);
|
||||
}
|
||||
|
||||
self.check_c_variadic_type(fk);
|
||||
|
||||
// Functions cannot both be `const async` or `const gen`
|
||||
|
|
|
|||
|
|
@ -225,6 +225,20 @@ pub struct InvalidSafetyOnExtern {
|
|||
pub block: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_item_invalid_safety)]
|
||||
pub struct InvalidSafetyOnItem {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_bare_fn_invalid_safety)]
|
||||
pub struct InvalidSafetyOnBareFn {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_bound_in_context)]
|
||||
pub struct BoundInContext<'a> {
|
||||
|
|
|
|||
|
|
@ -1110,7 +1110,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for OpaqueFolder<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use rustc_codegen_ssa::traits::*;
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_middle::{bug, span_bug, ty::Instance};
|
||||
use rustc_span::{Pos, Span};
|
||||
use rustc_span::{sym, Pos, Span, Symbol};
|
||||
use rustc_target::abi::*;
|
||||
use rustc_target::asm::*;
|
||||
use tracing::debug;
|
||||
|
|
@ -64,7 +64,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
let mut layout = None;
|
||||
let ty = if let Some(ref place) = place {
|
||||
layout = Some(&place.layout);
|
||||
llvm_fixup_output_type(self.cx, reg.reg_class(), &place.layout)
|
||||
llvm_fixup_output_type(self.cx, reg.reg_class(), &place.layout, instance)
|
||||
} else if matches!(
|
||||
reg.reg_class(),
|
||||
InlineAsmRegClass::X86(
|
||||
|
|
@ -112,7 +112,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
// so we just use the type of the input.
|
||||
&in_value.layout
|
||||
};
|
||||
let ty = llvm_fixup_output_type(self.cx, reg.reg_class(), layout);
|
||||
let ty = llvm_fixup_output_type(self.cx, reg.reg_class(), layout, instance);
|
||||
output_types.push(ty);
|
||||
op_idx.insert(idx, constraints.len());
|
||||
let prefix = if late { "=" } else { "=&" };
|
||||
|
|
@ -127,8 +127,13 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
for (idx, op) in operands.iter().enumerate() {
|
||||
match *op {
|
||||
InlineAsmOperandRef::In { reg, value } => {
|
||||
let llval =
|
||||
llvm_fixup_input(self, value.immediate(), reg.reg_class(), &value.layout);
|
||||
let llval = llvm_fixup_input(
|
||||
self,
|
||||
value.immediate(),
|
||||
reg.reg_class(),
|
||||
&value.layout,
|
||||
instance,
|
||||
);
|
||||
inputs.push(llval);
|
||||
op_idx.insert(idx, constraints.len());
|
||||
constraints.push(reg_to_llvm(reg, Some(&value.layout)));
|
||||
|
|
@ -139,6 +144,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
in_value.immediate(),
|
||||
reg.reg_class(),
|
||||
&in_value.layout,
|
||||
instance,
|
||||
);
|
||||
inputs.push(value);
|
||||
|
||||
|
|
@ -341,7 +347,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
} else {
|
||||
self.extract_value(result, op_idx[&idx] as u64)
|
||||
};
|
||||
let value = llvm_fixup_output(self, value, reg.reg_class(), &place.layout);
|
||||
let value =
|
||||
llvm_fixup_output(self, value, reg.reg_class(), &place.layout, instance);
|
||||
OperandValue::Immediate(value).store(self, place);
|
||||
}
|
||||
}
|
||||
|
|
@ -913,12 +920,22 @@ fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Ty
|
|||
}
|
||||
}
|
||||
|
||||
fn any_target_feature_enabled(
|
||||
cx: &CodegenCx<'_, '_>,
|
||||
instance: Instance<'_>,
|
||||
features: &[Symbol],
|
||||
) -> bool {
|
||||
let enabled = cx.tcx.asm_target_features(instance.def_id());
|
||||
features.iter().any(|feat| enabled.contains(feat))
|
||||
}
|
||||
|
||||
/// Fix up an input value to work around LLVM bugs.
|
||||
fn llvm_fixup_input<'ll, 'tcx>(
|
||||
bx: &mut Builder<'_, 'll, 'tcx>,
|
||||
mut value: &'ll Value,
|
||||
reg: InlineAsmRegClass,
|
||||
layout: &TyAndLayout<'tcx>,
|
||||
instance: Instance<'_>,
|
||||
) -> &'ll Value {
|
||||
let dl = &bx.tcx.data_layout;
|
||||
match (reg, layout.abi) {
|
||||
|
|
@ -1020,6 +1037,19 @@ fn llvm_fixup_input<'ll, 'tcx>(
|
|||
value
|
||||
}
|
||||
}
|
||||
(
|
||||
InlineAsmRegClass::Arm(
|
||||
ArmInlineAsmRegClass::dreg
|
||||
| ArmInlineAsmRegClass::dreg_low8
|
||||
| ArmInlineAsmRegClass::dreg_low16
|
||||
| ArmInlineAsmRegClass::qreg
|
||||
| ArmInlineAsmRegClass::qreg_low4
|
||||
| ArmInlineAsmRegClass::qreg_low8,
|
||||
),
|
||||
Abi::Vector { element, count: count @ (4 | 8) },
|
||||
) if element.primitive() == Primitive::Float(Float::F16) => {
|
||||
bx.bitcast(value, bx.type_vector(bx.type_i16(), count))
|
||||
}
|
||||
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
|
||||
match s.primitive() {
|
||||
// MIPS only supports register-length arithmetics.
|
||||
|
|
@ -1029,6 +1059,16 @@ fn llvm_fixup_input<'ll, 'tcx>(
|
|||
_ => value,
|
||||
}
|
||||
}
|
||||
(InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
|
||||
if s.primitive() == Primitive::Float(Float::F16)
|
||||
&& !any_target_feature_enabled(bx, instance, &[sym::zfhmin, sym::zfh]) =>
|
||||
{
|
||||
// Smaller floats are always "NaN-boxed" inside larger floats on RISC-V.
|
||||
let value = bx.bitcast(value, bx.type_i16());
|
||||
let value = bx.zext(value, bx.type_i32());
|
||||
let value = bx.or(value, bx.const_u32(0xFFFF_0000));
|
||||
bx.bitcast(value, bx.type_f32())
|
||||
}
|
||||
_ => value,
|
||||
}
|
||||
}
|
||||
|
|
@ -1039,6 +1079,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
|
|||
mut value: &'ll Value,
|
||||
reg: InlineAsmRegClass,
|
||||
layout: &TyAndLayout<'tcx>,
|
||||
instance: Instance<'_>,
|
||||
) -> &'ll Value {
|
||||
match (reg, layout.abi) {
|
||||
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
|
||||
|
|
@ -1130,6 +1171,19 @@ fn llvm_fixup_output<'ll, 'tcx>(
|
|||
value
|
||||
}
|
||||
}
|
||||
(
|
||||
InlineAsmRegClass::Arm(
|
||||
ArmInlineAsmRegClass::dreg
|
||||
| ArmInlineAsmRegClass::dreg_low8
|
||||
| ArmInlineAsmRegClass::dreg_low16
|
||||
| ArmInlineAsmRegClass::qreg
|
||||
| ArmInlineAsmRegClass::qreg_low4
|
||||
| ArmInlineAsmRegClass::qreg_low8,
|
||||
),
|
||||
Abi::Vector { element, count: count @ (4 | 8) },
|
||||
) if element.primitive() == Primitive::Float(Float::F16) => {
|
||||
bx.bitcast(value, bx.type_vector(bx.type_f16(), count))
|
||||
}
|
||||
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
|
||||
match s.primitive() {
|
||||
// MIPS only supports register-length arithmetics.
|
||||
|
|
@ -1140,6 +1194,14 @@ fn llvm_fixup_output<'ll, 'tcx>(
|
|||
_ => value,
|
||||
}
|
||||
}
|
||||
(InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
|
||||
if s.primitive() == Primitive::Float(Float::F16)
|
||||
&& !any_target_feature_enabled(bx, instance, &[sym::zfhmin, sym::zfh]) =>
|
||||
{
|
||||
let value = bx.bitcast(value, bx.type_i32());
|
||||
let value = bx.trunc(value, bx.type_i16());
|
||||
bx.bitcast(value, bx.type_f16())
|
||||
}
|
||||
_ => value,
|
||||
}
|
||||
}
|
||||
|
|
@ -1149,6 +1211,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
|
|||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
reg: InlineAsmRegClass,
|
||||
layout: &TyAndLayout<'tcx>,
|
||||
instance: Instance<'_>,
|
||||
) -> &'ll Type {
|
||||
match (reg, layout.abi) {
|
||||
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
|
||||
|
|
@ -1233,6 +1296,19 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
|
|||
layout.llvm_type(cx)
|
||||
}
|
||||
}
|
||||
(
|
||||
InlineAsmRegClass::Arm(
|
||||
ArmInlineAsmRegClass::dreg
|
||||
| ArmInlineAsmRegClass::dreg_low8
|
||||
| ArmInlineAsmRegClass::dreg_low16
|
||||
| ArmInlineAsmRegClass::qreg
|
||||
| ArmInlineAsmRegClass::qreg_low4
|
||||
| ArmInlineAsmRegClass::qreg_low8,
|
||||
),
|
||||
Abi::Vector { element, count: count @ (4 | 8) },
|
||||
) if element.primitive() == Primitive::Float(Float::F16) => {
|
||||
cx.type_vector(cx.type_i16(), count)
|
||||
}
|
||||
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
|
||||
match s.primitive() {
|
||||
// MIPS only supports register-length arithmetics.
|
||||
|
|
@ -1242,6 +1318,12 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
|
|||
_ => layout.llvm_type(cx),
|
||||
}
|
||||
}
|
||||
(InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
|
||||
if s.primitive() == Primitive::Float(Float::F16)
|
||||
&& !any_target_feature_enabled(cx, instance, &[sym::zfhmin, sym::zfh]) =>
|
||||
{
|
||||
cx.type_f32()
|
||||
}
|
||||
_ => layout.llvm_type(cx),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -341,8 +341,7 @@ const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in
|
|||
const_eval_unallowed_heap_allocations =
|
||||
allocations are not allowed in {const_eval_const_context}s
|
||||
.label = allocation not allowed in {const_eval_const_context}s
|
||||
.teach_note =
|
||||
The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
|
||||
.teach_note = The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
|
||||
|
||||
const_eval_unallowed_inline_asm =
|
||||
inline assembly is not allowed in {const_eval_const_context}s
|
||||
|
|
|
|||
|
|
@ -630,6 +630,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gives raw, immutable access to the `Allocation` address, without bounds or alignment checks.
|
||||
/// The caller is responsible for calling the access hooks!
|
||||
pub fn get_alloc_bytes_unchecked_raw(&self, id: AllocId) -> InterpResult<'tcx, *const u8> {
|
||||
let alloc = self.get_alloc_raw(id)?;
|
||||
Ok(alloc.get_bytes_unchecked_raw())
|
||||
}
|
||||
|
||||
/// Bounds-checked *but not align-checked* allocation access.
|
||||
pub fn get_ptr_alloc<'a>(
|
||||
&'a self,
|
||||
|
|
@ -713,6 +720,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
Ok((alloc, &mut self.machine))
|
||||
}
|
||||
|
||||
/// Gives raw, mutable access to the `Allocation` address, without bounds or alignment checks.
|
||||
/// The caller is responsible for calling the access hooks!
|
||||
pub fn get_alloc_bytes_unchecked_raw_mut(
|
||||
&mut self,
|
||||
id: AllocId,
|
||||
) -> InterpResult<'tcx, *mut u8> {
|
||||
let alloc = self.get_alloc_raw_mut(id)?.0;
|
||||
Ok(alloc.get_bytes_unchecked_raw_mut())
|
||||
}
|
||||
|
||||
/// Bounds-checked *but not align-checked* allocation access.
|
||||
pub fn get_ptr_alloc_mut<'a>(
|
||||
&'a mut self,
|
||||
|
|
|
|||
|
|
@ -441,7 +441,7 @@ where
|
|||
|
||||
/// Take an operand, representing a pointer, and dereference it to a place.
|
||||
/// Corresponds to the `*` operator in Rust.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
pub fn deref_pointer(
|
||||
&self,
|
||||
src: &impl Readable<'tcx, M::Provenance>,
|
||||
|
|
@ -533,7 +533,7 @@ where
|
|||
|
||||
/// Computes a place. You should only use this if you intend to write into this
|
||||
/// place; for reading, a more efficient alternative is `eval_place_to_op`.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
pub fn eval_place(
|
||||
&self,
|
||||
mir_place: mir::Place<'tcx>,
|
||||
|
|
@ -570,7 +570,7 @@ where
|
|||
|
||||
/// Write an immediate to a place
|
||||
#[inline(always)]
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
pub fn write_immediate(
|
||||
&mut self,
|
||||
src: Immediate<M::Provenance>,
|
||||
|
|
@ -808,7 +808,7 @@ where
|
|||
/// Copies the data from an operand to a place.
|
||||
/// `allow_transmute` indicates whether the layouts may disagree.
|
||||
#[inline(always)]
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn copy_op_inner(
|
||||
&mut self,
|
||||
src: &impl Readable<'tcx, M::Provenance>,
|
||||
|
|
@ -837,7 +837,7 @@ where
|
|||
/// `allow_transmute` indicates whether the layouts may disagree.
|
||||
/// Also, if you use this you are responsible for validating that things get copied at the
|
||||
/// right type.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn copy_op_no_validate(
|
||||
&mut self,
|
||||
src: &impl Readable<'tcx, M::Provenance>,
|
||||
|
|
@ -914,7 +914,7 @@ where
|
|||
/// If the place currently refers to a local that doesn't yet have a matching allocation,
|
||||
/// create such an allocation.
|
||||
/// This is essentially `force_to_memplace`.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
pub fn force_allocation(
|
||||
&mut self,
|
||||
place: &PlaceTy<'tcx, M::Provenance>,
|
||||
|
|
|
|||
|
|
@ -1905,7 +1905,7 @@ impl HumanEmitter {
|
|||
//
|
||||
// LL | this line was highlighted
|
||||
// LL | this line is just for context
|
||||
// ...
|
||||
// ...
|
||||
// LL | this line is just for context
|
||||
// LL | this line was highlighted
|
||||
_ => {
|
||||
|
|
@ -1926,7 +1926,7 @@ impl HumanEmitter {
|
|||
)
|
||||
}
|
||||
|
||||
buffer.puts(row_num, max_line_num_len - 1, "...", Style::LineNumber);
|
||||
buffer.puts(row_num, 0, "...", Style::LineNumber);
|
||||
row_num += 1;
|
||||
|
||||
if let Some((p, l)) = last_line {
|
||||
|
|
|
|||
|
|
@ -1088,6 +1088,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
ErrorFollowing, EncodeCrossCrate::No,
|
||||
"the `#[custom_mir]` attribute is just used for the Rust test suite",
|
||||
),
|
||||
rustc_attr!(
|
||||
TEST, rustc_dump_item_bounds, Normal, template!(Word),
|
||||
WarnFollowing, EncodeCrossCrate::No
|
||||
),
|
||||
rustc_attr!(
|
||||
TEST, rustc_dump_predicates, Normal, template!(Word),
|
||||
WarnFollowing, EncodeCrossCrate::No
|
||||
),
|
||||
rustc_attr!(
|
||||
TEST, rustc_object_lifetime_default, Normal, template!(Word),
|
||||
WarnFollowing, EncodeCrossCrate::No
|
||||
|
|
|
|||
|
|
@ -449,7 +449,7 @@ declare_features! (
|
|||
/// Allows `dyn* Trait` objects.
|
||||
(incomplete, dyn_star, "1.65.0", Some(102425)),
|
||||
/// Uses generic effect parameters for ~const bounds
|
||||
(unstable, effects, "1.72.0", Some(102090)),
|
||||
(incomplete, effects, "1.72.0", Some(102090)),
|
||||
/// Allows exhaustive pattern matching on types that contain uninhabited types.
|
||||
(unstable, exhaustive_patterns, "1.13.0", Some(51085)),
|
||||
/// Allows explicit tail calls via `become` expression.
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ hir_analysis_inherent_ty_outside = cannot define inherent `impl` for a type outs
|
|||
.span_help = alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items
|
||||
|
||||
hir_analysis_inherent_ty_outside_new = cannot define inherent `impl` for a type outside of the crate where the type is defined
|
||||
.label = impl for type defined outside of crate.
|
||||
.label = impl for type defined outside of crate
|
||||
.note = define and implement a trait or new type instead
|
||||
|
||||
hir_analysis_inherent_ty_outside_primitive = cannot define inherent `impl` for primitive types outside of `core`
|
||||
|
|
@ -510,7 +510,7 @@ hir_analysis_ty_param_some = type parameter `{$param}` must be used as the type
|
|||
.note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
|
||||
.only_note = only traits defined in the current crate can be implemented for a type parameter
|
||||
|
||||
hir_analysis_type_of = {$type_of}
|
||||
hir_analysis_type_of = {$ty}
|
||||
|
||||
hir_analysis_typeof_reserved_keyword_used =
|
||||
`typeof` is a reserved keyword but unimplemented
|
||||
|
|
@ -544,7 +544,7 @@ hir_analysis_unrecognized_intrinsic_function =
|
|||
|
||||
hir_analysis_unused_associated_type_bounds =
|
||||
unnecessary associated type bound for not object safe associated type
|
||||
.note = this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
|
||||
.note = this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
|
||||
.suggestion = remove this bound
|
||||
|
||||
hir_analysis_unused_generic_parameter =
|
||||
|
|
@ -566,7 +566,7 @@ hir_analysis_value_of_associated_struct_already_specified =
|
|||
hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like {$conventions}
|
||||
.label = C-variadic function must have a compatible calling convention
|
||||
|
||||
hir_analysis_variances_of = {$variances_of}
|
||||
hir_analysis_variances_of = {$variances}
|
||||
|
||||
hir_analysis_where_clause_on_main = `main` function is not allowed to have a `where` clause
|
||||
.label = `main` cannot have a `where` clause
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ struct RemapLateBound<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
@ -790,13 +790,13 @@ impl<'tcx, E> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx, E
|
|||
where
|
||||
E: 'tcx,
|
||||
{
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.ocx.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if let ty::Alias(ty::Projection, proj) = ty.kind()
|
||||
&& self.interner().is_impl_trait_in_trait(proj.def_id)
|
||||
&& self.cx().is_impl_trait_in_trait(proj.def_id)
|
||||
{
|
||||
if let Some((ty, _)) = self.types.get(&proj.def_id) {
|
||||
return *ty;
|
||||
|
|
@ -810,9 +810,9 @@ where
|
|||
self.types.insert(proj.def_id, (infer_ty, proj.args));
|
||||
// Recurse into bounds
|
||||
for (pred, pred_span) in self
|
||||
.interner()
|
||||
.cx()
|
||||
.explicit_item_bounds(proj.def_id)
|
||||
.iter_instantiated_copied(self.interner(), proj.args)
|
||||
.iter_instantiated_copied(self.cx(), proj.args)
|
||||
{
|
||||
let pred = pred.fold_with(self);
|
||||
let pred = self.ocx.normalize(
|
||||
|
|
@ -822,7 +822,7 @@ where
|
|||
);
|
||||
|
||||
self.ocx.register_obligation(traits::Obligation::new(
|
||||
self.interner(),
|
||||
self.cx(),
|
||||
ObligationCause::new(
|
||||
self.span,
|
||||
self.body_id,
|
||||
|
|
@ -853,7 +853,7 @@ struct RemapHiddenTyRegions<'tcx> {
|
|||
impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
||||
type Error = ErrorGuaranteed;
|
||||
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
@ -2072,7 +2072,7 @@ struct ReplaceTy<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceTy<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ struct Anonymize<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Anonymize<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -429,17 +429,17 @@ pub fn check_intrinsic_type(
|
|||
|
||||
sym::ptr_guaranteed_cmp => (
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
|
||||
tcx.types.u8,
|
||||
),
|
||||
|
||||
sym::const_allocate => {
|
||||
(0, 1, vec![tcx.types.usize, tcx.types.usize], Ty::new_mut_ptr(tcx, tcx.types.u8))
|
||||
(0, 0, vec![tcx.types.usize, tcx.types.usize], Ty::new_mut_ptr(tcx, tcx.types.u8))
|
||||
}
|
||||
sym::const_deallocate => (
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
vec![Ty::new_mut_ptr(tcx, tcx.types.u8), tcx.types.usize, tcx.types.usize],
|
||||
tcx.types.unit,
|
||||
),
|
||||
|
|
@ -478,16 +478,16 @@ pub fn check_intrinsic_type(
|
|||
| sym::frem_algebraic => (1, 0, vec![param(0), param(0)], param(0)),
|
||||
sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)),
|
||||
|
||||
sym::assume => (0, 1, vec![tcx.types.bool], tcx.types.unit),
|
||||
sym::likely => (0, 1, vec![tcx.types.bool], tcx.types.bool),
|
||||
sym::unlikely => (0, 1, vec![tcx.types.bool], tcx.types.bool),
|
||||
sym::assume => (0, 0, vec![tcx.types.bool], tcx.types.unit),
|
||||
sym::likely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
|
||||
sym::unlikely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
|
||||
|
||||
sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
|
||||
sym::write_via_move => {
|
||||
(1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
|
||||
}
|
||||
|
||||
sym::typed_swap => (1, 1, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit),
|
||||
sym::typed_swap => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit),
|
||||
|
||||
sym::discriminant_value => {
|
||||
let assoc_items = tcx.associated_item_def_ids(
|
||||
|
|
@ -566,9 +566,9 @@ pub fn check_intrinsic_type(
|
|||
|
||||
sym::black_box => (1, 0, vec![param(0)], param(0)),
|
||||
|
||||
sym::is_val_statically_known => (1, 1, vec![param(0)], tcx.types.bool),
|
||||
sym::is_val_statically_known => (1, 0, vec![param(0)], tcx.types.bool),
|
||||
|
||||
sym::const_eval_select => (4, 1, vec![param(0), param(1), param(2)], param(3)),
|
||||
sym::const_eval_select => (4, 0, vec![param(0), param(1), param(2)], param(3)),
|
||||
|
||||
sym::vtable_size | sym::vtable_align => {
|
||||
(0, 0, vec![Ty::new_imm_ptr(tcx, tcx.types.unit)], tcx.types.usize)
|
||||
|
|
@ -576,10 +576,10 @@ pub fn check_intrinsic_type(
|
|||
|
||||
// This type check is not particularly useful, but the `where` bounds
|
||||
// on the definition in `core` do the heavy lifting for checking it.
|
||||
sym::aggregate_raw_ptr => (3, 1, vec![param(1), param(2)], param(0)),
|
||||
sym::ptr_metadata => (2, 1, vec![Ty::new_imm_ptr(tcx, param(0))], param(1)),
|
||||
sym::aggregate_raw_ptr => (3, 0, vec![param(1), param(2)], param(0)),
|
||||
sym::ptr_metadata => (2, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(1)),
|
||||
|
||||
sym::ub_checks => (0, 1, Vec::new(), tcx.types.bool),
|
||||
sym::ub_checks => (0, 0, Vec::new(), tcx.types.bool),
|
||||
|
||||
sym::simd_eq
|
||||
| sym::simd_ne
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ struct TyVarReplacer<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for TyVarReplacer<'cx, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ use std::ops::Bound;
|
|||
use crate::check::intrinsic::intrinsic_operation_unsafety;
|
||||
use crate::errors;
|
||||
use crate::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
|
||||
pub use type_of::test_opaque_hidden_types;
|
||||
|
||||
pub(crate) mod dump;
|
||||
mod generics_of;
|
||||
mod item_bounds;
|
||||
mod predicates_of;
|
||||
|
|
|
|||
43
compiler/rustc_hir_analysis/src/collect/dump.rs
Normal file
43
compiler/rustc_hir_analysis/src/collect/dump.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::CRATE_DEF_ID;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::sym;
|
||||
|
||||
pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
|
||||
if !tcx.has_attr(CRATE_DEF_ID, sym::rustc_hidden_type_of_opaques) {
|
||||
return;
|
||||
}
|
||||
|
||||
for id in tcx.hir().items() {
|
||||
let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
|
||||
|
||||
let ty = tcx.type_of(id.owner_id).instantiate_identity();
|
||||
|
||||
tcx.dcx().emit_err(crate::errors::TypeOf { span: tcx.def_span(id.owner_id), ty });
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) {
|
||||
for id in tcx.hir_crate_items(()).owners() {
|
||||
if tcx.has_attr(id, sym::rustc_dump_predicates) {
|
||||
let preds = tcx.predicates_of(id).instantiate_identity(tcx).predicates;
|
||||
let span = tcx.def_span(id);
|
||||
|
||||
let mut diag = tcx.dcx().struct_span_err(span, sym::rustc_dump_predicates.as_str());
|
||||
for pred in preds {
|
||||
diag.note(format!("{pred:?}"));
|
||||
}
|
||||
diag.emit();
|
||||
}
|
||||
if tcx.has_attr(id, sym::rustc_dump_item_bounds) {
|
||||
let bounds = tcx.item_bounds(id).instantiate_identity();
|
||||
let span = tcx.def_span(id);
|
||||
|
||||
let mut diag = tcx.dcx().struct_span_err(span, sym::rustc_dump_item_bounds.as_str());
|
||||
for bound in bounds {
|
||||
diag.note(format!("{bound:?}"));
|
||||
}
|
||||
diag.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -203,7 +203,7 @@ struct AssocTyToOpaque<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTyToOpaque<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ use crate::errors::TypeofReservedKeywordUsed;
|
|||
|
||||
use super::bad_placeholder;
|
||||
use super::ItemCtxt;
|
||||
pub use opaque::test_opaque_hidden_types;
|
||||
|
||||
mod opaque;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,14 @@
|
|||
use rustc_errors::StashKey;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{self as hir, def, Expr, ImplItem, Item, Node, TraitItem};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP};
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
use crate::errors::{TaitForwardCompat, TaitForwardCompat2, TypeOf, UnconstrainedOpaqueType};
|
||||
|
||||
pub fn test_opaque_hidden_types(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
let mut res = Ok(());
|
||||
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_hidden_type_of_opaques) {
|
||||
for id in tcx.hir().items() {
|
||||
if matches!(tcx.def_kind(id.owner_id), DefKind::OpaqueTy) {
|
||||
let type_of = tcx.type_of(id.owner_id).instantiate_identity();
|
||||
|
||||
res = Err(tcx.dcx().emit_err(TypeOf { span: tcx.def_span(id.owner_id), type_of }));
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
use crate::errors::{TaitForwardCompat, TaitForwardCompat2, UnconstrainedOpaqueType};
|
||||
|
||||
/// Checks "defining uses" of opaque `impl Trait` in associated types.
|
||||
/// These can only be defined by associated items of the same trait.
|
||||
|
|
|
|||
|
|
@ -682,7 +682,7 @@ pub(crate) enum CannotCaptureLateBound {
|
|||
pub(crate) struct VariancesOf {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub variances_of: String,
|
||||
pub variances: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
@ -690,7 +690,7 @@ pub(crate) struct VariancesOf {
|
|||
pub(crate) struct TypeOf<'tcx> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub type_of: Ty<'tcx>,
|
||||
pub ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
|||
|
|
@ -151,10 +151,6 @@ pub fn provide(providers: &mut Providers) {
|
|||
pub fn check_crate(tcx: TyCtxt<'_>) {
|
||||
let _prof_timer = tcx.sess.timer("type_check_crate");
|
||||
|
||||
if tcx.features().rustc_attrs {
|
||||
let _ = tcx.sess.time("outlives_testing", || outlives::test::test_inferred_outlives(tcx));
|
||||
}
|
||||
|
||||
tcx.sess.time("coherence_checking", || {
|
||||
tcx.hir().par_for_each_module(|module| {
|
||||
let _ = tcx.ensure().check_mod_type_wf(module);
|
||||
|
|
@ -169,11 +165,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
|
|||
});
|
||||
|
||||
if tcx.features().rustc_attrs {
|
||||
let _ = tcx.sess.time("variance_testing", || variance::test::test_variance(tcx));
|
||||
}
|
||||
|
||||
if tcx.features().rustc_attrs {
|
||||
let _ = collect::test_opaque_hidden_types(tcx);
|
||||
tcx.sess.time("outlives_dumping", || outlives::dump::inferred_outlives(tcx));
|
||||
tcx.sess.time("variance_dumping", || variance::dump::variances(tcx));
|
||||
collect::dump::opaque_hidden_types(tcx);
|
||||
collect::dump::predicates_and_item_bounds(tcx);
|
||||
}
|
||||
|
||||
// Make sure we evaluate all static and (non-associated) const items, even if unused.
|
||||
|
|
|
|||
29
compiler/rustc_hir_analysis/src/outlives/dump.rs
Normal file
29
compiler/rustc_hir_analysis/src/outlives/dump.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::sym;
|
||||
|
||||
pub(crate) fn inferred_outlives(tcx: TyCtxt<'_>) {
|
||||
for id in tcx.hir().items() {
|
||||
if !tcx.has_attr(id.owner_id, sym::rustc_outlives) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let preds = tcx.inferred_outlives_of(id.owner_id);
|
||||
let mut preds: Vec<_> = preds
|
||||
.iter()
|
||||
.map(|(pred, _)| match pred.kind().skip_binder() {
|
||||
ty::ClauseKind::RegionOutlives(p) => p.to_string(),
|
||||
ty::ClauseKind::TypeOutlives(p) => p.to_string(),
|
||||
err => bug!("unexpected clause {:?}", err),
|
||||
})
|
||||
.collect();
|
||||
preds.sort();
|
||||
|
||||
let span = tcx.def_span(id.owner_id);
|
||||
let mut err = tcx.dcx().struct_span_err(span, sym::rustc_outlives.as_str());
|
||||
for pred in preds {
|
||||
err.note(pred);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,10 +5,9 @@ use rustc_middle::ty::GenericArgKind;
|
|||
use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt, Upcast};
|
||||
use rustc_span::Span;
|
||||
|
||||
pub(crate) mod dump;
|
||||
mod explicit;
|
||||
mod implicit_infer;
|
||||
/// Code to write unit test for outlives.
|
||||
pub mod test;
|
||||
mod utils;
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::{symbol::sym, ErrorGuaranteed};
|
||||
|
||||
pub fn test_inferred_outlives(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
let mut res = Ok(());
|
||||
for id in tcx.hir().items() {
|
||||
// For unit testing: check for a special "rustc_outlives"
|
||||
// attribute and report an error with various results if found.
|
||||
if tcx.has_attr(id.owner_id, sym::rustc_outlives) {
|
||||
let predicates = tcx.inferred_outlives_of(id.owner_id);
|
||||
let mut pred: Vec<String> = predicates
|
||||
.iter()
|
||||
.map(|(out_pred, _)| match out_pred.kind().skip_binder() {
|
||||
ty::ClauseKind::RegionOutlives(p) => p.to_string(),
|
||||
ty::ClauseKind::TypeOutlives(p) => p.to_string(),
|
||||
err => bug!("unexpected clause {:?}", err),
|
||||
})
|
||||
.collect();
|
||||
pred.sort();
|
||||
|
||||
let span = tcx.def_span(id.owner_id);
|
||||
let mut err = tcx.dcx().struct_span_err(span, "rustc_outlives");
|
||||
for p in pred {
|
||||
err.note(p);
|
||||
}
|
||||
res = Err(err.emit());
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
32
compiler/rustc_hir_analysis/src/variance/dump.rs
Normal file
32
compiler/rustc_hir_analysis/src/variance/dump.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::CRATE_DEF_ID;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
pub(crate) fn variances(tcx: TyCtxt<'_>) {
|
||||
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
|
||||
for id in tcx.hir().items() {
|
||||
let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
|
||||
|
||||
let variances = tcx.variances_of(id.owner_id);
|
||||
|
||||
tcx.dcx().emit_err(crate::errors::VariancesOf {
|
||||
span: tcx.def_span(id.owner_id),
|
||||
variances: format!("{variances:?}"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for id in tcx.hir().items() {
|
||||
if !tcx.has_attr(id.owner_id, sym::rustc_variance) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let variances = tcx.variances_of(id.owner_id);
|
||||
|
||||
tcx.dcx().emit_err(crate::errors::VariancesOf {
|
||||
span: tcx.def_span(id.owner_id),
|
||||
variances: format!("{variances:?}"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -22,8 +22,7 @@ mod constraints;
|
|||
/// Code to solve constraints and write out the results.
|
||||
mod solve;
|
||||
|
||||
/// Code to write unit tests of variance.
|
||||
pub mod test;
|
||||
pub(crate) mod dump;
|
||||
|
||||
/// Code for transforming variances.
|
||||
mod xform;
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::CRATE_DEF_ID;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::ErrorGuaranteed;
|
||||
|
||||
use crate::errors;
|
||||
|
||||
pub fn test_variance(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
let mut res = Ok(());
|
||||
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
|
||||
for id in tcx.hir().items() {
|
||||
if matches!(tcx.def_kind(id.owner_id), DefKind::OpaqueTy) {
|
||||
let variances_of = tcx.variances_of(id.owner_id);
|
||||
|
||||
res = Err(tcx.dcx().emit_err(errors::VariancesOf {
|
||||
span: tcx.def_span(id.owner_id),
|
||||
variances_of: format!("{variances_of:?}"),
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For unit testing: check for a special "rustc_variance"
|
||||
// attribute and report an error with various results if found.
|
||||
for id in tcx.hir().items() {
|
||||
if tcx.has_attr(id.owner_id, sym::rustc_variance) {
|
||||
let variances_of = tcx.variances_of(id.owner_id);
|
||||
|
||||
res = Err(tcx.dcx().emit_err(errors::VariancesOf {
|
||||
span: tcx.def_span(id.owner_id),
|
||||
variances_of: format!("{variances_of:?}"),
|
||||
}));
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
|
@ -847,7 +847,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.fcx.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ struct Canonicalizer<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
@ -773,7 +773,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
) -> ty::Region<'tcx> {
|
||||
let var = self.canonical_var(info, r.into());
|
||||
let br = ty::BoundRegion { var, kind: ty::BrAnon };
|
||||
ty::Region::new_bound(self.interner(), self.binder_index, br)
|
||||
ty::Region::new_bound(self.cx(), self.binder_index, br)
|
||||
}
|
||||
|
||||
/// Given a type variable `ty_var` of the given kind, first check
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ struct ClosureEraser<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
|
|||
| ty::RePlaceholder(..)
|
||||
| ty::ReStatic
|
||||
| ty::ReError(_)
|
||||
| ty::ReErased => self.interner().lifetimes.re_erased,
|
||||
| ty::ReErased => self.cx().lifetimes.re_erased,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1719,7 +1719,7 @@ struct InferenceLiteralEraser<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceLiteralEraser<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
@ -1859,7 +1859,7 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceParamAndInferWithPlaceholder<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ impl<'a, 'tcx> OpportunisticVarResolver<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticVarResolver<'a, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ impl<'a, 'tcx> OpportunisticRegionResolver<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticRegionResolver<'a, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticRegionResolver<'a, 'tcx
|
|||
.inner
|
||||
.borrow_mut()
|
||||
.unwrap_region_constraints()
|
||||
.opportunistic_resolve_var(TypeFolder::interner(self), vid),
|
||||
.opportunistic_resolve_var(TypeFolder::cx(self), vid),
|
||||
_ => r,
|
||||
}
|
||||
}
|
||||
|
|
@ -121,7 +121,7 @@ struct FullTypeResolver<'a, 'tcx> {
|
|||
impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> {
|
||||
type Error = FixupError;
|
||||
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ pub struct InferenceFudger<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceFudger<'a, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ lint_builtin_deprecated_attr_default_suggestion = remove this attribute
|
|||
lint_builtin_deprecated_attr_link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
|
||||
.msg_suggestion = {$msg}
|
||||
.default_suggestion = remove this attribute
|
||||
lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used.
|
||||
lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used
|
||||
lint_builtin_deref_nullptr = dereferencing a null pointer
|
||||
.label = this code causes undefined behavior when executed
|
||||
|
||||
|
|
@ -213,7 +213,7 @@ lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better pe
|
|||
lint_default_source = `forbid` lint level is the default for {$id}
|
||||
|
||||
lint_deprecated_lint_name =
|
||||
lint name `{$name}` is deprecated and may not have an effect in the future.
|
||||
lint name `{$name}` is deprecated and may not have an effect in the future
|
||||
.suggestion = change it to
|
||||
.help = change it to {$replace}
|
||||
|
||||
|
|
@ -244,11 +244,11 @@ lint_duplicate_matcher_binding = duplicate matcher binding
|
|||
|
||||
lint_enum_intrinsics_mem_discriminant =
|
||||
the return value of `mem::discriminant` is unspecified when called with a non-enum type
|
||||
.note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum.
|
||||
.note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum
|
||||
|
||||
lint_enum_intrinsics_mem_variant =
|
||||
the return value of `mem::variant_count` is unspecified when called with a non-enum type
|
||||
.note = the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum.
|
||||
.note = the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum
|
||||
|
||||
lint_expectation = this lint expectation is unfulfilled
|
||||
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
|
||||
|
|
|
|||
|
|
@ -390,7 +390,7 @@ struct ReplaceLocalTypesWithInfer<'a, 'tcx, F: FnMut(DefId) -> bool> {
|
|||
impl<'a, 'tcx, F: FnMut(DefId) -> bool> TypeFolder<TyCtxt<'tcx>>
|
||||
for ReplaceLocalTypesWithInfer<'a, 'tcx, F>
|
||||
{
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -248,13 +248,13 @@ metadata_rustc_lib_required =
|
|||
.help = try adding `extern crate rustc_driver;` at the top level of this crate
|
||||
|
||||
metadata_stable_crate_id_collision =
|
||||
found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values.
|
||||
found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values
|
||||
|
||||
metadata_std_required =
|
||||
`std` is required by `{$current_crate}` because it does not declare `#![no_std]`
|
||||
|
||||
metadata_symbol_conflicts_current =
|
||||
the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments. This will result in symbol conflicts between the two.
|
||||
the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments, so this will result in symbol conflicts between the two
|
||||
|
||||
metadata_target_no_std_support =
|
||||
the `{$locator_triple}` target may not support the standard library
|
||||
|
|
|
|||
|
|
@ -40,9 +40,16 @@ pub trait AllocBytes: Clone + fmt::Debug + Deref<Target = [u8]> + DerefMut<Targe
|
|||
/// Gives direct access to the raw underlying storage.
|
||||
///
|
||||
/// Crucially this pointer is compatible with:
|
||||
/// - other pointers retunred by this method, and
|
||||
/// - other pointers returned by this method, and
|
||||
/// - references returned from `deref()`, as long as there was no write.
|
||||
fn as_mut_ptr(&mut self) -> *mut u8;
|
||||
|
||||
/// Gives direct access to the raw underlying storage.
|
||||
///
|
||||
/// Crucially this pointer is compatible with:
|
||||
/// - other pointers returned by this method, and
|
||||
/// - references returned from `deref()`, as long as there was no write.
|
||||
fn as_ptr(&self) -> *const u8;
|
||||
}
|
||||
|
||||
/// Default `bytes` for `Allocation` is a `Box<u8>`.
|
||||
|
|
@ -62,6 +69,11 @@ impl AllocBytes for Box<[u8]> {
|
|||
// Carefully avoiding any intermediate references.
|
||||
ptr::addr_of_mut!(**self).cast()
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const u8 {
|
||||
// Carefully avoiding any intermediate references.
|
||||
ptr::addr_of!(**self).cast()
|
||||
}
|
||||
}
|
||||
|
||||
/// This type represents an Allocation in the Miri/CTFE core engine.
|
||||
|
|
@ -490,19 +502,27 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
|
|||
self.provenance.clear(range, cx)?;
|
||||
|
||||
assert!(range.end().bytes_usize() <= self.bytes.len()); // need to do our own bounds-check
|
||||
// Cruciall, we go via `AllocBytes::as_mut_ptr`, not `AllocBytes::deref_mut`.
|
||||
// Crucially, we go via `AllocBytes::as_mut_ptr`, not `AllocBytes::deref_mut`.
|
||||
let begin_ptr = self.bytes.as_mut_ptr().wrapping_add(range.start.bytes_usize());
|
||||
let len = range.end().bytes_usize() - range.start.bytes_usize();
|
||||
Ok(ptr::slice_from_raw_parts_mut(begin_ptr, len))
|
||||
}
|
||||
|
||||
/// This gives direct mutable access to the entire buffer, just exposing their internal state
|
||||
/// without reseting anything. Directly exposes `AllocBytes::as_mut_ptr`. Only works if
|
||||
/// without resetting anything. Directly exposes `AllocBytes::as_mut_ptr`. Only works if
|
||||
/// `OFFSET_IS_ADDR` is true.
|
||||
pub fn get_bytes_unchecked_raw_mut(&mut self) -> *mut u8 {
|
||||
assert!(Prov::OFFSET_IS_ADDR);
|
||||
self.bytes.as_mut_ptr()
|
||||
}
|
||||
|
||||
/// This gives direct immutable access to the entire buffer, just exposing their internal state
|
||||
/// without resetting anything. Directly exposes `AllocBytes::as_ptr`. Only works if
|
||||
/// `OFFSET_IS_ADDR` is true.
|
||||
pub fn get_bytes_unchecked_raw(&self) -> *const u8 {
|
||||
assert!(Prov::OFFSET_IS_ADDR);
|
||||
self.bytes.as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
/// Reading and writing.
|
||||
|
|
|
|||
|
|
@ -289,19 +289,7 @@ impl<'tcx> UnOp {
|
|||
pub fn ty(&self, tcx: TyCtxt<'tcx>, arg_ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match self {
|
||||
UnOp::Not | UnOp::Neg => arg_ty,
|
||||
UnOp::PtrMetadata => {
|
||||
let pointee_ty = arg_ty
|
||||
.builtin_deref(true)
|
||||
.unwrap_or_else(|| bug!("PtrMetadata of non-dereferenceable ty {arg_ty:?}"));
|
||||
if pointee_ty.is_trivially_sized(tcx) {
|
||||
tcx.types.unit
|
||||
} else {
|
||||
let Some(metadata_def_id) = tcx.lang_items().metadata_type() else {
|
||||
bug!("No metadata_type lang item while looking at {arg_ty:?}")
|
||||
};
|
||||
Ty::new_projection(tcx, metadata_def_id, [pointee_ty])
|
||||
}
|
||||
}
|
||||
UnOp::PtrMetadata => arg_ty.pointee_metadata_ty_or_projection(tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
|
|||
self,
|
||||
folder: &mut F,
|
||||
) -> Result<Self, F::Error> {
|
||||
Ok(FallibleTypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData {
|
||||
Ok(FallibleTypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
|
||||
region_constraints: self.region_constraints.clone().try_fold_with(folder)?,
|
||||
opaque_types: self
|
||||
.opaque_types
|
||||
|
|
@ -68,7 +68,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
|
|||
}
|
||||
|
||||
fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
|
||||
TypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData {
|
||||
TypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
|
||||
region_constraints: self.region_constraints.clone().fold_with(folder),
|
||||
opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
|
||||
normalization_nested_goals: self.normalization_nested_goals.clone().fold_with(folder),
|
||||
|
|
@ -94,19 +94,17 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
|
|||
self,
|
||||
folder: &mut F,
|
||||
) -> Result<Self, F::Error> {
|
||||
Ok(FallibleTypeFolder::interner(folder).mk_predefined_opaques_in_body(
|
||||
PredefinedOpaquesData {
|
||||
opaque_types: self
|
||||
.opaque_types
|
||||
.iter()
|
||||
.map(|opaque| opaque.try_fold_with(folder))
|
||||
.collect::<Result<_, F::Error>>()?,
|
||||
},
|
||||
))
|
||||
Ok(FallibleTypeFolder::cx(folder).mk_predefined_opaques_in_body(PredefinedOpaquesData {
|
||||
opaque_types: self
|
||||
.opaque_types
|
||||
.iter()
|
||||
.map(|opaque| opaque.try_fold_with(folder))
|
||||
.collect::<Result<_, F::Error>>()?,
|
||||
}))
|
||||
}
|
||||
|
||||
fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
|
||||
TypeFolder::interner(folder).mk_predefined_opaques_in_body(PredefinedOpaquesData {
|
||||
TypeFolder::cx(folder).mk_predefined_opaques_in_body(PredefinedOpaquesData {
|
||||
opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Expander<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
|
|
|
|||
|
|
@ -579,7 +579,7 @@ pub struct MakeSuggestableFolder<'tcx> {
|
|||
impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> {
|
||||
type Error = ();
|
||||
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ struct RegionEraserVisitor<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ where
|
|||
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
|
||||
H: FnMut(ty::Const<'tcx>) -> ty::Const<'tcx>,
|
||||
{
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +176,7 @@ impl<'tcx, D> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'tcx, D>
|
|||
where
|
||||
D: BoundVarReplacerDelegate<'tcx>,
|
||||
{
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -591,7 +591,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArgsRef<'tcx> {
|
|||
match self.len() {
|
||||
1 => {
|
||||
let param0 = self[0].try_fold_with(folder)?;
|
||||
if param0 == self[0] { Ok(self) } else { Ok(folder.interner().mk_args(&[param0])) }
|
||||
if param0 == self[0] { Ok(self) } else { Ok(folder.cx().mk_args(&[param0])) }
|
||||
}
|
||||
2 => {
|
||||
let param0 = self[0].try_fold_with(folder)?;
|
||||
|
|
@ -599,7 +599,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArgsRef<'tcx> {
|
|||
if param0 == self[0] && param1 == self[1] {
|
||||
Ok(self)
|
||||
} else {
|
||||
Ok(folder.interner().mk_args(&[param0, param1]))
|
||||
Ok(folder.cx().mk_args(&[param0, param1]))
|
||||
}
|
||||
}
|
||||
0 => Ok(self),
|
||||
|
|
@ -635,7 +635,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
|
|||
if param0 == self[0] && param1 == self[1] {
|
||||
Ok(self)
|
||||
} else {
|
||||
Ok(folder.interner().mk_type_list(&[param0, param1]))
|
||||
Ok(folder.cx().mk_type_list(&[param0, param1]))
|
||||
}
|
||||
}
|
||||
_ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_type_list(v)),
|
||||
|
|
|
|||
|
|
@ -873,7 +873,7 @@ fn polymorphize<'tcx>(
|
|||
}
|
||||
|
||||
impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for PolymorphizationFolder<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for NormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ impl<'tcx> TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
|||
impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
type Error = NormalizationError<'tcx>;
|
||||
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ impl<'tcx> ReverseMapper<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
|
|||
)
|
||||
.emit();
|
||||
|
||||
ty::Region::new_error(self.interner(), e)
|
||||
ty::Region::new_error(self.cx(), e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2529,7 +2529,7 @@ struct RegionFolder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Pattern<'tcx> {
|
|||
folder: &mut F,
|
||||
) -> Result<Self, F::Error> {
|
||||
let pat = (*self).clone().try_fold_with(folder)?;
|
||||
Ok(if pat == *self { self } else { folder.interner().mk_pat(pat) })
|
||||
Ok(if pat == *self { self } else { folder.cx().mk_pat(pat) })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -407,7 +407,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||
| ty::Foreign(..) => return Ok(self),
|
||||
};
|
||||
|
||||
Ok(if *self.kind() == kind { self } else { folder.interner().mk_ty_from_kind(kind) })
|
||||
Ok(if *self.kind() == kind { self } else { folder.cx().mk_ty_from_kind(kind) })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -512,7 +512,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
|
|||
folder: &mut F,
|
||||
) -> Result<Self, F::Error> {
|
||||
let new = self.kind().try_fold_with(folder)?;
|
||||
Ok(folder.interner().reuse_or_mk_predicate(self, new))
|
||||
Ok(folder.cx().reuse_or_mk_predicate(self, new))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -577,7 +577,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
|
|||
ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?),
|
||||
ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?),
|
||||
};
|
||||
if kind != self.kind() { Ok(folder.interner().mk_ct_from_kind(kind)) } else { Ok(self) }
|
||||
if kind != self.kind() { Ok(folder.cx().mk_ct_from_kind(kind)) } else { Ok(self) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1638,6 +1638,34 @@ impl<'tcx> Ty<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Given a pointer or reference type, returns the type of the *pointee*'s
|
||||
/// metadata. If it can't be determined exactly (perhaps due to still
|
||||
/// being generic) then a projection through `ptr::Pointee` will be returned.
|
||||
///
|
||||
/// This is particularly useful for getting the type of the result of
|
||||
/// [`UnOp::PtrMetadata`](crate::mir::UnOp::PtrMetadata).
|
||||
///
|
||||
/// Panics if `self` is not dereferencable.
|
||||
#[track_caller]
|
||||
pub fn pointee_metadata_ty_or_projection(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
let Some(pointee_ty) = self.builtin_deref(true) else {
|
||||
bug!("Type {self:?} is not a pointer or reference type")
|
||||
};
|
||||
if pointee_ty.is_trivially_sized(tcx) {
|
||||
tcx.types.unit
|
||||
} else {
|
||||
match pointee_ty.ptr_metadata_ty_or_tail(tcx, |x| x) {
|
||||
Ok(metadata_ty) => metadata_ty,
|
||||
Err(tail_ty) => {
|
||||
let Some(metadata_def_id) = tcx.lang_items().metadata_type() else {
|
||||
bug!("No metadata_type lang item while looking at {self:?}")
|
||||
};
|
||||
Ty::new_projection(tcx, metadata_def_id, [tail_ty])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// When we create a closure, we record its kind (i.e., what trait
|
||||
/// it implements, constrained by how it uses its borrows) into its
|
||||
/// [`ty::ClosureArgs`] or [`ty::CoroutineClosureArgs`] using a type
|
||||
|
|
|
|||
|
|
@ -1083,7 +1083,7 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
@ -1130,7 +1130,7 @@ struct WeakAliasTypeExpander<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for WeakAliasTypeExpander<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
|
|
@ -1795,7 +1795,7 @@ where
|
|||
for t in iter {
|
||||
new_list.push(t.try_fold_with(folder)?)
|
||||
}
|
||||
Ok(intern(folder.interner(), &new_list))
|
||||
Ok(intern(folder.cx(), &new_list))
|
||||
}
|
||||
Some((_, Err(err))) => {
|
||||
return Err(err);
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
|
|||
.note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
.label = dereference of raw pointer
|
||||
|
||||
mir_build_exceeds_mcdc_condition_limit = Number of conditions in decision ({$num_conditions}) exceeds limit ({$max_conditions}). MC/DC analysis will not count this expression.
|
||||
mir_build_exceeds_mcdc_condition_limit = number of conditions in decision ({$num_conditions}) exceeds limit ({$max_conditions}), so MC/DC analysis will not count this expression
|
||||
|
||||
mir_build_extern_static_requires_unsafe =
|
||||
use of extern static is unsafe and requires unsafe block
|
||||
|
|
|
|||
|
|
@ -60,7 +60,15 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
|
|||
|
||||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, _location: Location) {
|
||||
match rvalue {
|
||||
Rvalue::NullaryOp(NullOp::UbChecks, ..) if !self.tcx.sess.ub_checks() => {
|
||||
Rvalue::NullaryOp(NullOp::UbChecks, ..)
|
||||
if !self
|
||||
.tcx
|
||||
.sess
|
||||
.opts
|
||||
.unstable_opts
|
||||
.inline_mir_preserve_debug
|
||||
.unwrap_or(self.tcx.sess.ub_checks()) =>
|
||||
{
|
||||
// If this is in optimized MIR it's because it's used later,
|
||||
// so if we don't need UB checks this session, give a bonus
|
||||
// here to offset the cost of the call later.
|
||||
|
|
@ -111,12 +119,19 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
TerminatorKind::Assert { unwind, msg, .. } => {
|
||||
self.penalty +=
|
||||
if msg.is_optional_overflow_check() && !self.tcx.sess.overflow_checks() {
|
||||
INSTR_COST
|
||||
} else {
|
||||
CALL_PENALTY
|
||||
};
|
||||
self.penalty += if msg.is_optional_overflow_check()
|
||||
&& !self
|
||||
.tcx
|
||||
.sess
|
||||
.opts
|
||||
.unstable_opts
|
||||
.inline_mir_preserve_debug
|
||||
.unwrap_or(self.tcx.sess.overflow_checks())
|
||||
{
|
||||
INSTR_COST
|
||||
} else {
|
||||
CALL_PENALTY
|
||||
};
|
||||
if let UnwindAction::Cleanup(_) = unwind {
|
||||
self.penalty += LANDINGPAD_PENALTY;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -823,18 +823,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
return self.simplify_cast(kind, value, to, location);
|
||||
}
|
||||
Rvalue::BinaryOp(op, box (ref mut lhs, ref mut rhs)) => {
|
||||
let ty = lhs.ty(self.local_decls, self.tcx);
|
||||
let lhs = self.simplify_operand(lhs, location);
|
||||
let rhs = self.simplify_operand(rhs, location);
|
||||
// Only short-circuit options after we called `simplify_operand`
|
||||
// on both operands for side effect.
|
||||
let lhs = lhs?;
|
||||
let rhs = rhs?;
|
||||
|
||||
if let Some(value) = self.simplify_binary(op, ty, lhs, rhs) {
|
||||
return Some(value);
|
||||
}
|
||||
Value::BinaryOp(op, lhs, rhs)
|
||||
return self.simplify_binary(op, lhs, rhs, location);
|
||||
}
|
||||
Rvalue::UnaryOp(op, ref mut arg_op) => {
|
||||
return self.simplify_unary(op, arg_op, location);
|
||||
|
|
@ -987,23 +976,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
// `*const [T]` -> `*const T` which remove metadata.
|
||||
// We run on potentially-generic MIR, though, so unlike codegen
|
||||
// we can't always know exactly what the metadata are.
|
||||
// Thankfully, equality on `ptr_metadata_ty_or_tail` gives us
|
||||
// what we need: `Ok(meta_ty)` if the metadata is known, or
|
||||
// `Err(tail_ty)` if not. Matching metadata is ok, but if
|
||||
// that's not known, then matching tail types is also ok,
|
||||
// allowing things like `*mut (?A, ?T)` <-> `*mut (?B, ?T)`.
|
||||
// FIXME: Would it be worth trying to normalize, rather than
|
||||
// passing the identity closure? Or are the types in the
|
||||
// Cast realistically about as normalized as we can get anyway?
|
||||
// To allow things like `*mut (?A, ?T)` <-> `*mut (?B, ?T)`,
|
||||
// it's fine to get a projection as the type.
|
||||
Value::Cast { kind: CastKind::PtrToPtr, value: inner, from, to }
|
||||
if from
|
||||
.builtin_deref(true)
|
||||
.unwrap()
|
||||
.ptr_metadata_ty_or_tail(self.tcx, |t| t)
|
||||
== to
|
||||
.builtin_deref(true)
|
||||
.unwrap()
|
||||
.ptr_metadata_ty_or_tail(self.tcx, |t| t) =>
|
||||
if self.pointers_have_same_metadata(*from, *to) =>
|
||||
{
|
||||
arg_index = *inner;
|
||||
was_updated = true;
|
||||
|
|
@ -1068,6 +1044,52 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn simplify_binary(
|
||||
&mut self,
|
||||
op: BinOp,
|
||||
lhs_operand: &mut Operand<'tcx>,
|
||||
rhs_operand: &mut Operand<'tcx>,
|
||||
location: Location,
|
||||
) -> Option<VnIndex> {
|
||||
let lhs = self.simplify_operand(lhs_operand, location);
|
||||
let rhs = self.simplify_operand(rhs_operand, location);
|
||||
// Only short-circuit options after we called `simplify_operand`
|
||||
// on both operands for side effect.
|
||||
let mut lhs = lhs?;
|
||||
let mut rhs = rhs?;
|
||||
|
||||
let lhs_ty = lhs_operand.ty(self.local_decls, self.tcx);
|
||||
|
||||
// If we're comparing pointers, remove `PtrToPtr` casts if the from
|
||||
// types of both casts and the metadata all match.
|
||||
if let BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge = op
|
||||
&& lhs_ty.is_any_ptr()
|
||||
&& let Value::Cast {
|
||||
kind: CastKind::PtrToPtr, value: lhs_value, from: lhs_from, ..
|
||||
} = self.get(lhs)
|
||||
&& let Value::Cast {
|
||||
kind: CastKind::PtrToPtr, value: rhs_value, from: rhs_from, ..
|
||||
} = self.get(rhs)
|
||||
&& lhs_from == rhs_from
|
||||
&& self.pointers_have_same_metadata(*lhs_from, lhs_ty)
|
||||
{
|
||||
lhs = *lhs_value;
|
||||
rhs = *rhs_value;
|
||||
if let Some(op) = self.try_as_operand(lhs, location) {
|
||||
*lhs_operand = op;
|
||||
}
|
||||
if let Some(op) = self.try_as_operand(rhs, location) {
|
||||
*rhs_operand = op;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(value) = self.simplify_binary_inner(op, lhs_ty, lhs, rhs) {
|
||||
return Some(value);
|
||||
}
|
||||
let value = Value::BinaryOp(op, lhs, rhs);
|
||||
Some(self.insert(value))
|
||||
}
|
||||
|
||||
fn simplify_binary_inner(
|
||||
&mut self,
|
||||
op: BinOp,
|
||||
lhs_ty: Ty<'tcx>,
|
||||
|
|
@ -1228,6 +1250,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// PtrToPtr-then-PtrToPtr can skip the intermediate step
|
||||
if let PtrToPtr = kind
|
||||
&& let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } =
|
||||
*self.get(value)
|
||||
|
|
@ -1235,7 +1258,25 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
{
|
||||
from = inner_from;
|
||||
value = inner_value;
|
||||
*kind = PtrToPtr;
|
||||
was_updated = true;
|
||||
if inner_from == to {
|
||||
return Some(inner_value);
|
||||
}
|
||||
}
|
||||
|
||||
// PtrToPtr-then-Transmute can just transmute the original, so long as the
|
||||
// PtrToPtr didn't change metadata (and thus the size of the pointer)
|
||||
if let Transmute = kind
|
||||
&& let Value::Cast {
|
||||
kind: PtrToPtr,
|
||||
value: inner_value,
|
||||
from: inner_from,
|
||||
to: inner_to,
|
||||
} = *self.get(value)
|
||||
&& self.pointers_have_same_metadata(inner_from, inner_to)
|
||||
{
|
||||
from = inner_from;
|
||||
value = inner_value;
|
||||
was_updated = true;
|
||||
if inner_from == to {
|
||||
return Some(inner_value);
|
||||
|
|
@ -1289,6 +1330,21 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
// Fallback: a symbolic `Len`.
|
||||
Some(self.insert(Value::Len(inner)))
|
||||
}
|
||||
|
||||
fn pointers_have_same_metadata(&self, left_ptr_ty: Ty<'tcx>, right_ptr_ty: Ty<'tcx>) -> bool {
|
||||
let left_meta_ty = left_ptr_ty.pointee_metadata_ty_or_projection(self.tcx);
|
||||
let right_meta_ty = right_ptr_ty.pointee_metadata_ty_or_projection(self.tcx);
|
||||
if left_meta_ty == right_meta_ty {
|
||||
true
|
||||
} else if let Ok(left) =
|
||||
self.tcx.try_normalize_erasing_regions(self.param_env, left_meta_ty)
|
||||
&& let Ok(right) = self.tcx.try_normalize_erasing_regions(self.param_env, right_meta_ty)
|
||||
{
|
||||
left == right
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn op_to_prop_const<'tcx>(
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
|
|||
let ccx = ConstCx::new(tcx, body);
|
||||
let (mut temps, all_candidates) = collect_temps_and_candidates(&ccx);
|
||||
|
||||
let promotable_candidates = validate_candidates(&ccx, &mut temps, &all_candidates);
|
||||
let promotable_candidates = validate_candidates(&ccx, &mut temps, all_candidates);
|
||||
|
||||
let promoted = promote_candidates(body, tcx, temps, promotable_candidates);
|
||||
self.promoted_fragments.set(promoted);
|
||||
|
|
@ -98,8 +98,8 @@ struct Collector<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn visit_local(&mut self, index: Local, context: PlaceContext, location: Location) {
|
||||
debug!("visit_local: index={:?} context={:?} location={:?}", index, context, location);
|
||||
// We're only interested in temporaries and the return place
|
||||
match self.ccx.body.local_kind(index) {
|
||||
LocalKind::Arg => return,
|
||||
|
|
@ -111,20 +111,15 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
|
|||
// then it's constant and thus drop is noop.
|
||||
// Non-uses are also irrelevant.
|
||||
if context.is_drop() || !context.is_use() {
|
||||
debug!(
|
||||
"visit_local: context.is_drop={:?} context.is_use={:?}",
|
||||
context.is_drop(),
|
||||
context.is_use(),
|
||||
);
|
||||
debug!(is_drop = context.is_drop(), is_use = context.is_use());
|
||||
return;
|
||||
}
|
||||
|
||||
let temp = &mut self.temps[index];
|
||||
debug!("visit_local: temp={:?}", temp);
|
||||
debug!(?temp);
|
||||
*temp = match *temp {
|
||||
TempState::Undefined => match context {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store)
|
||||
| PlaceContext::MutatingUse(MutatingUseContext::Call) => {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store | MutatingUseContext::Call) => {
|
||||
TempState::Defined { location, uses: 0, valid: Err(()) }
|
||||
}
|
||||
_ => TempState::Unpromotable,
|
||||
|
|
@ -137,7 +132,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
|
|||
| PlaceContext::NonMutatingUse(_) => true,
|
||||
PlaceContext::MutatingUse(_) | PlaceContext::NonUse(_) => false,
|
||||
};
|
||||
debug!("visit_local: allowed_use={:?}", allowed_use);
|
||||
debug!(?allowed_use);
|
||||
if allowed_use {
|
||||
*uses += 1;
|
||||
return;
|
||||
|
|
@ -146,6 +141,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
|
|||
}
|
||||
TempState::Unpromotable | TempState::PromotedOut => TempState::Unpromotable,
|
||||
};
|
||||
debug!(?temp);
|
||||
}
|
||||
|
||||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
|
|
@ -695,15 +691,12 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
fn validate_candidates(
|
||||
ccx: &ConstCx<'_, '_>,
|
||||
temps: &mut IndexSlice<Local, TempState>,
|
||||
candidates: &[Candidate],
|
||||
mut candidates: Vec<Candidate>,
|
||||
) -> Vec<Candidate> {
|
||||
let mut validator = Validator { ccx, temps, promotion_safe_blocks: None };
|
||||
|
||||
candidates.retain(|&candidate| validator.validate_candidate(candidate).is_ok());
|
||||
candidates
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|&candidate| validator.validate_candidate(candidate).is_ok())
|
||||
.collect()
|
||||
}
|
||||
|
||||
struct Promoter<'a, 'tcx> {
|
||||
|
|
@ -972,7 +965,12 @@ fn promote_candidates<'tcx>(
|
|||
candidates: Vec<Candidate>,
|
||||
) -> IndexVec<Promoted, Body<'tcx>> {
|
||||
// Visit candidates in reverse, in case they're nested.
|
||||
debug!("promote_candidates({:?})", candidates);
|
||||
debug!(promote_candidates = ?candidates);
|
||||
|
||||
// eagerly fail fast
|
||||
if candidates.is_empty() {
|
||||
return IndexVec::new();
|
||||
}
|
||||
|
||||
let mut promotions = IndexVec::new();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use rustc_type_ir::{
|
|||
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Interner,
|
||||
};
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
|
||||
/// Whether we're canonicalizing a query input or the query response.
|
||||
///
|
||||
|
|
@ -38,8 +38,8 @@ pub enum CanonicalizeMode {
|
|||
},
|
||||
}
|
||||
|
||||
pub struct Canonicalizer<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> {
|
||||
infcx: &'a Infcx,
|
||||
pub struct Canonicalizer<'a, D: SolverDelegate<Interner = I>, I: Interner> {
|
||||
delegate: &'a D,
|
||||
canonicalize_mode: CanonicalizeMode,
|
||||
|
||||
variables: &'a mut Vec<I::GenericArg>,
|
||||
|
|
@ -47,15 +47,15 @@ pub struct Canonicalizer<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> {
|
|||
binder_index: ty::DebruijnIndex,
|
||||
}
|
||||
|
||||
impl<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, Infcx, I> {
|
||||
impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
pub fn canonicalize<T: TypeFoldable<I>>(
|
||||
infcx: &'a Infcx,
|
||||
delegate: &'a D,
|
||||
canonicalize_mode: CanonicalizeMode,
|
||||
variables: &'a mut Vec<I::GenericArg>,
|
||||
value: T,
|
||||
) -> ty::Canonical<I, T> {
|
||||
let mut canonicalizer = Canonicalizer {
|
||||
infcx,
|
||||
delegate,
|
||||
canonicalize_mode,
|
||||
|
||||
variables,
|
||||
|
|
@ -70,7 +70,7 @@ impl<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, Inf
|
|||
|
||||
let (max_universe, variables) = canonicalizer.finalize();
|
||||
|
||||
let defining_opaque_types = infcx.defining_opaque_types();
|
||||
let defining_opaque_types = delegate.defining_opaque_types();
|
||||
Canonical { defining_opaque_types, max_universe, variables, value }
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ impl<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, Inf
|
|||
.max()
|
||||
.unwrap_or(ty::UniverseIndex::ROOT);
|
||||
|
||||
let var_infos = self.infcx.interner().mk_canonical_var_infos(&var_infos);
|
||||
let var_infos = self.delegate.cx().mk_canonical_var_infos(&var_infos);
|
||||
return (max_universe, var_infos);
|
||||
}
|
||||
}
|
||||
|
|
@ -206,16 +206,14 @@ impl<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, Inf
|
|||
}
|
||||
}
|
||||
|
||||
let var_infos = self.infcx.interner().mk_canonical_var_infos(&var_infos);
|
||||
let var_infos = self.delegate.cx().mk_canonical_var_infos(&var_infos);
|
||||
(curr_compressed_uv, var_infos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
||||
for Canonicalizer<'_, Infcx, I>
|
||||
{
|
||||
fn interner(&self) -> I {
|
||||
self.infcx.interner()
|
||||
impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicalizer<'_, D, I> {
|
||||
fn cx(&self) -> I {
|
||||
self.delegate.cx()
|
||||
}
|
||||
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T>
|
||||
|
|
@ -267,14 +265,14 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
|||
|
||||
ty::ReVar(vid) => {
|
||||
assert_eq!(
|
||||
self.infcx.opportunistic_resolve_lt_var(vid),
|
||||
self.delegate.opportunistic_resolve_lt_var(vid),
|
||||
r,
|
||||
"region vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
match self.canonicalize_mode {
|
||||
CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT),
|
||||
CanonicalizeMode::Response { .. } => {
|
||||
CanonicalVarKind::Region(self.infcx.universe_of_lt(vid).unwrap())
|
||||
CanonicalVarKind::Region(self.delegate.universe_of_lt(vid).unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -294,7 +292,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
|||
var
|
||||
});
|
||||
|
||||
Region::new_anon_bound(self.interner(), self.binder_index, var)
|
||||
Region::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||
|
|
@ -302,20 +300,20 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
|||
ty::Infer(i) => match i {
|
||||
ty::TyVar(vid) => {
|
||||
assert_eq!(
|
||||
self.infcx.opportunistic_resolve_ty_var(vid),
|
||||
self.delegate.opportunistic_resolve_ty_var(vid),
|
||||
t,
|
||||
"ty vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(
|
||||
self.infcx
|
||||
self.delegate
|
||||
.universe_of_ty(vid)
|
||||
.unwrap_or_else(|| panic!("ty var should have been resolved: {t:?}")),
|
||||
))
|
||||
}
|
||||
ty::IntVar(vid) => {
|
||||
assert_eq!(
|
||||
self.infcx.opportunistic_resolve_int_var(vid),
|
||||
self.delegate.opportunistic_resolve_int_var(vid),
|
||||
t,
|
||||
"ty vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
|
|
@ -323,7 +321,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
|||
}
|
||||
ty::FloatVar(vid) => {
|
||||
assert_eq!(
|
||||
self.infcx.opportunistic_resolve_float_var(vid),
|
||||
self.delegate.opportunistic_resolve_float_var(vid),
|
||||
t,
|
||||
"ty vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
|
|
@ -383,7 +381,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
|||
}),
|
||||
);
|
||||
|
||||
Ty::new_anon_bound(self.interner(), self.binder_index, var)
|
||||
Ty::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: I::Const) -> I::Const {
|
||||
|
|
@ -391,11 +389,11 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
|||
ty::ConstKind::Infer(i) => match i {
|
||||
ty::InferConst::Var(vid) => {
|
||||
assert_eq!(
|
||||
self.infcx.opportunistic_resolve_ct_var(vid),
|
||||
self.delegate.opportunistic_resolve_ct_var(vid),
|
||||
c,
|
||||
"const vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap())
|
||||
CanonicalVarKind::Const(self.delegate.universe_of_ct(vid).unwrap())
|
||||
}
|
||||
ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
|
||||
ty::InferConst::Fresh(_) => todo!(),
|
||||
|
|
@ -431,6 +429,6 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
|||
}),
|
||||
);
|
||||
|
||||
Const::new_anon_bound(self.interner(), self.binder_index, var)
|
||||
Const::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ use rustc_type_ir::{self as ty, Interner};
|
|||
|
||||
pub trait SolverDelegate: Sized {
|
||||
type Interner: Interner;
|
||||
fn interner(&self) -> Self::Interner;
|
||||
fn cx(&self) -> Self::Interner;
|
||||
|
||||
type Span: Copy;
|
||||
|
||||
fn solver_mode(&self) -> SolverMode;
|
||||
|
||||
fn build_with_canonical<V>(
|
||||
interner: Self::Interner,
|
||||
cx: Self::Interner,
|
||||
solver_mode: SolverMode,
|
||||
canonical: &ty::Canonical<Self::Interner, V>,
|
||||
) -> (Self, V, ty::CanonicalVarValues<Self::Interner>)
|
||||
|
|
@ -102,7 +102,7 @@ pub trait SolverDelegate: Sized {
|
|||
|
||||
// FIXME: This is only here because elaboration lives in `rustc_infer`!
|
||||
fn elaborate_supertraits(
|
||||
interner: Self::Interner,
|
||||
cx: Self::Interner,
|
||||
trait_ref: ty::Binder<Self::Interner, ty::TraitRef<Self::Interner>>,
|
||||
) -> impl Iterator<Item = ty::Binder<Self::Interner, ty::TraitRef<Self::Interner>>>;
|
||||
|
||||
|
|
@ -5,6 +5,6 @@
|
|||
//! So if you got to this crate from the old solver, it's totally normal.
|
||||
|
||||
pub mod canonicalizer;
|
||||
pub mod infcx;
|
||||
pub mod delegate;
|
||||
pub mod resolve;
|
||||
pub mod solve;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::visit::TypeVisitableExt;
|
||||
|
|
@ -8,37 +8,37 @@ use rustc_type_ir::{self as ty, Interner};
|
|||
// EAGER RESOLUTION
|
||||
|
||||
/// Resolves ty, region, and const vars to their inferred values or their root vars.
|
||||
pub struct EagerResolver<'a, Infcx, I = <Infcx as SolverDelegate>::Interner>
|
||||
pub struct EagerResolver<'a, D, I = <D as SolverDelegate>::Interner>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
infcx: &'a Infcx,
|
||||
delegate: &'a D,
|
||||
}
|
||||
|
||||
impl<'a, Infcx: SolverDelegate> EagerResolver<'a, Infcx> {
|
||||
pub fn new(infcx: &'a Infcx) -> Self {
|
||||
EagerResolver { infcx }
|
||||
impl<'a, D: SolverDelegate> EagerResolver<'a, D> {
|
||||
pub fn new(delegate: &'a D) -> Self {
|
||||
EagerResolver { delegate }
|
||||
}
|
||||
}
|
||||
|
||||
impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for EagerResolver<'_, Infcx> {
|
||||
fn interner(&self) -> I {
|
||||
self.infcx.interner()
|
||||
impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for EagerResolver<'_, D> {
|
||||
fn cx(&self) -> I {
|
||||
self.delegate.cx()
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||
match t.kind() {
|
||||
ty::Infer(ty::TyVar(vid)) => {
|
||||
let resolved = self.infcx.opportunistic_resolve_ty_var(vid);
|
||||
let resolved = self.delegate.opportunistic_resolve_ty_var(vid);
|
||||
if t != resolved && resolved.has_infer() {
|
||||
resolved.fold_with(self)
|
||||
} else {
|
||||
resolved
|
||||
}
|
||||
}
|
||||
ty::Infer(ty::IntVar(vid)) => self.infcx.opportunistic_resolve_int_var(vid),
|
||||
ty::Infer(ty::FloatVar(vid)) => self.infcx.opportunistic_resolve_float_var(vid),
|
||||
ty::Infer(ty::IntVar(vid)) => self.delegate.opportunistic_resolve_int_var(vid),
|
||||
ty::Infer(ty::FloatVar(vid)) => self.delegate.opportunistic_resolve_float_var(vid),
|
||||
_ => {
|
||||
if t.has_infer() {
|
||||
t.super_fold_with(self)
|
||||
|
|
@ -51,7 +51,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for EagerRe
|
|||
|
||||
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||
match r.kind() {
|
||||
ty::ReVar(vid) => self.infcx.opportunistic_resolve_lt_var(vid),
|
||||
ty::ReVar(vid) => self.delegate.opportunistic_resolve_lt_var(vid),
|
||||
_ => r,
|
||||
}
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for EagerRe
|
|||
fn fold_const(&mut self, c: I::Const) -> I::Const {
|
||||
match c.kind() {
|
||||
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
|
||||
let resolved = self.infcx.opportunistic_resolve_ct_var(vid);
|
||||
let resolved = self.delegate.opportunistic_resolve_ct_var(vid);
|
||||
if c != resolved && resolved.has_infer() {
|
||||
resolved.fold_with(self)
|
||||
} else {
|
||||
|
|
@ -67,7 +67,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for EagerRe
|
|||
}
|
||||
}
|
||||
ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => {
|
||||
self.infcx.opportunistic_resolve_effect_var(vid)
|
||||
self.delegate.opportunistic_resolve_effect_var(vid)
|
||||
}
|
||||
_ => {
|
||||
if c.has_infer() {
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@ use rustc_type_ir::inherent::*;
|
|||
use rustc_type_ir::{self as ty, Interner};
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::{Certainty, EvalCtxt, Goal, QueryResult};
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
|
|
@ -32,7 +32,7 @@ where
|
|||
&mut self,
|
||||
goal: Goal<I, (I::Term, I::Term, ty::AliasRelationDirection)>,
|
||||
) -> QueryResult<I> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let Goal { param_env, predicate: (lhs, rhs, direction) } = goal;
|
||||
debug_assert!(lhs.to_alias_term().is_some() || rhs.to_alias_term().is_some());
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use rustc_type_ir::visit::TypeVisitableExt as _;
|
|||
use rustc_type_ir::{self as ty, Interner, Upcast as _};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::inspect::ProbeKind;
|
||||
use crate::solve::{
|
||||
BuiltinImplSource, CandidateSource, CanonicalResponse, Certainty, EvalCtxt, Goal, GoalSource,
|
||||
|
|
@ -28,10 +28,10 @@ pub(super) struct Candidate<I: Interner> {
|
|||
}
|
||||
|
||||
/// Methods used to assemble candidates for either trait or projection goals.
|
||||
pub(super) trait GoalKind<Infcx, I = <Infcx as SolverDelegate>::Interner>:
|
||||
pub(super) trait GoalKind<D, I = <D as SolverDelegate>::Interner>:
|
||||
TypeFoldable<I> + Copy + Eq + std::fmt::Display
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
fn self_ty(self) -> I::Ty;
|
||||
|
|
@ -47,18 +47,18 @@ where
|
|||
/// work, then produce a response (typically by executing
|
||||
/// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
|
||||
fn probe_and_match_goal_against_assumption(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
source: CandidateSource<I>,
|
||||
goal: Goal<I, Self>,
|
||||
assumption: I::Clause,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> QueryResult<I>,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
/// Consider a clause, which consists of a "assumption" and some "requirements",
|
||||
/// to satisfy a goal. If the requirements hold, then attempt to satisfy our
|
||||
/// goal by equating it with the assumption.
|
||||
fn probe_and_consider_implied_clause(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
parent_source: CandidateSource<I>,
|
||||
goal: Goal<I, Self>,
|
||||
assumption: I::Clause,
|
||||
|
|
@ -76,13 +76,13 @@ where
|
|||
/// additionally checking all of the supertraits and object bounds to hold,
|
||||
/// since they're not implied by the well-formedness of the object type.
|
||||
fn probe_and_consider_object_bound_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
source: CandidateSource<I>,
|
||||
goal: Goal<I, Self>,
|
||||
assumption: I::Clause,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
let ty::Dynamic(bounds, _, _) = goal.predicate.self_ty().kind() else {
|
||||
panic!("expected object type in `probe_and_consider_object_bound_candidate`");
|
||||
};
|
||||
|
|
@ -100,7 +100,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_impl_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
impl_def_id: I::DefId,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
|
@ -112,7 +112,7 @@ where
|
|||
/// Trait goals always hold while projection goals never do. This is a bit arbitrary
|
||||
/// but prevents incorrect normalization while hiding any trait errors.
|
||||
fn consider_error_guaranteed_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
guar: I::ErrorGuaranteed,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
|
|
@ -121,13 +121,13 @@ where
|
|||
/// These components are given by built-in rules from
|
||||
/// [`structural_traits::instantiate_constituent_tys_for_auto_trait`].
|
||||
fn consider_auto_trait_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
/// A trait alias holds if the RHS traits and `where` clauses hold.
|
||||
fn consider_trait_alias_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ where
|
|||
/// These components are given by built-in rules from
|
||||
/// [`structural_traits::instantiate_constituent_tys_for_sized_trait`].
|
||||
fn consider_builtin_sized_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
|
|
@ -145,27 +145,27 @@ where
|
|||
/// These components are given by built-in rules from
|
||||
/// [`structural_traits::instantiate_constituent_tys_for_copy_clone_trait`].
|
||||
fn consider_builtin_copy_clone_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
/// A type is `PointerLike` if we can compute its layout, and that layout
|
||||
/// matches the layout of `usize`.
|
||||
fn consider_builtin_pointer_like_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
/// A type is a `FnPtr` if it is of `FnPtr` type.
|
||||
fn consider_builtin_fn_ptr_trait_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
/// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn<A>`
|
||||
/// family of traits where `A` is given by the signature of the type.
|
||||
fn consider_builtin_fn_trait_candidates(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
|
@ -173,7 +173,7 @@ where
|
|||
/// An async closure is known to implement the `AsyncFn<A>` family of traits
|
||||
/// where `A` is given by the signature of the type.
|
||||
fn consider_builtin_async_fn_trait_candidates(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
|
@ -182,13 +182,13 @@ where
|
|||
/// is used internally to delay computation for async closures until after
|
||||
/// upvar analysis is performed in HIR typeck.
|
||||
fn consider_builtin_async_fn_kind_helper_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
/// `Tuple` is implemented if the `Self` type is a tuple.
|
||||
fn consider_builtin_tuple_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ where
|
|||
/// the built-in types. For structs, the metadata type is given by the struct
|
||||
/// tail.
|
||||
fn consider_builtin_pointee_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
|
|
@ -206,7 +206,7 @@ where
|
|||
/// `Future<Output = O>`, where `O` is given by the coroutine's return type
|
||||
/// that was computed during type-checking.
|
||||
fn consider_builtin_future_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
|
|
@ -214,19 +214,19 @@ where
|
|||
/// `Iterator<Item = O>`, where `O` is given by the generator's yield type
|
||||
/// that was computed during type-checking.
|
||||
fn consider_builtin_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
/// A coroutine (that comes from a `gen` desugaring) is known to implement
|
||||
/// `FusedIterator`
|
||||
fn consider_builtin_fused_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
fn consider_builtin_async_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
|
|
@ -234,27 +234,27 @@ where
|
|||
/// implement `Coroutine<R, Yield = Y, Return = O>`, given the resume, yield,
|
||||
/// and return types of the coroutine computed during type-checking.
|
||||
fn consider_builtin_coroutine_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
fn consider_builtin_discriminant_kind_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
fn consider_builtin_async_destruct_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
fn consider_builtin_destruct_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
fn consider_builtin_transmute_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution>;
|
||||
|
||||
|
|
@ -266,17 +266,17 @@ where
|
|||
/// otherwise recompute this for codegen. This is a bit of a mess but the
|
||||
/// easiest way to maintain the existing behavior for now.
|
||||
fn consider_structural_builtin_unsize_candidates(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Vec<Candidate<I>>;
|
||||
}
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<Infcx>>(
|
||||
pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<D>>(
|
||||
&mut self,
|
||||
goal: Goal<I, G>,
|
||||
) -> Vec<Candidate<I>> {
|
||||
|
|
@ -291,10 +291,8 @@ where
|
|||
return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
|
||||
}
|
||||
|
||||
let goal: Goal<I, G> = goal.with(
|
||||
self.interner(),
|
||||
goal.predicate.with_self_ty(self.interner(), normalized_self_ty),
|
||||
);
|
||||
let goal: Goal<I, G> =
|
||||
goal.with(self.cx(), goal.predicate.with_self_ty(self.cx(), normalized_self_ty));
|
||||
// Vars that show up in the rest of the goal substs may have been constrained by
|
||||
// normalizing the self type as well, since type variables are not uniquified.
|
||||
let goal = self.resolve_vars_if_possible(goal);
|
||||
|
|
@ -337,12 +335,12 @@ where
|
|||
}
|
||||
|
||||
#[instrument(level = "trace", skip_all)]
|
||||
fn assemble_impl_candidates<G: GoalKind<Infcx>>(
|
||||
fn assemble_impl_candidates<G: GoalKind<D>>(
|
||||
&mut self,
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
tcx.for_each_relevant_impl(
|
||||
goal.predicate.trait_def_id(tcx),
|
||||
goal.predicate.self_ty(),
|
||||
|
|
@ -363,12 +361,12 @@ where
|
|||
}
|
||||
|
||||
#[instrument(level = "trace", skip_all)]
|
||||
fn assemble_builtin_impl_candidates<G: GoalKind<Infcx>>(
|
||||
fn assemble_builtin_impl_candidates<G: GoalKind<D>>(
|
||||
&mut self,
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let trait_def_id = goal.predicate.trait_def_id(tcx);
|
||||
|
||||
// N.B. When assembling built-in candidates for lang items that are also
|
||||
|
|
@ -394,9 +392,9 @@ where
|
|||
G::consider_builtin_pointer_like_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::FnPtrTrait) {
|
||||
G::consider_builtin_fn_ptr_trait_candidate(self, goal)
|
||||
} else if let Some(kind) = self.interner().fn_trait_kind_from_def_id(trait_def_id) {
|
||||
} else if let Some(kind) = self.cx().fn_trait_kind_from_def_id(trait_def_id) {
|
||||
G::consider_builtin_fn_trait_candidates(self, goal, kind)
|
||||
} else if let Some(kind) = self.interner().async_fn_trait_kind_from_def_id(trait_def_id) {
|
||||
} else if let Some(kind) = self.cx().async_fn_trait_kind_from_def_id(trait_def_id) {
|
||||
G::consider_builtin_async_fn_trait_candidates(self, goal, kind)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncFnKindHelper) {
|
||||
G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
|
||||
|
|
@ -436,7 +434,7 @@ where
|
|||
}
|
||||
|
||||
#[instrument(level = "trace", skip_all)]
|
||||
fn assemble_param_env_candidates<G: GoalKind<Infcx>>(
|
||||
fn assemble_param_env_candidates<G: GoalKind<D>>(
|
||||
&mut self,
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
|
|
@ -453,7 +451,7 @@ where
|
|||
}
|
||||
|
||||
#[instrument(level = "trace", skip_all)]
|
||||
fn assemble_alias_bound_candidates<G: GoalKind<Infcx>>(
|
||||
fn assemble_alias_bound_candidates<G: GoalKind<D>>(
|
||||
&mut self,
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
|
|
@ -472,7 +470,7 @@ where
|
|||
/// If so, continue searching by recursively calling after normalization.
|
||||
// FIXME: This may recurse infinitely, but I can't seem to trigger it without
|
||||
// hitting another overflow error something. Add a depth parameter needed later.
|
||||
fn assemble_alias_bound_candidates_recur<G: GoalKind<Infcx>>(
|
||||
fn assemble_alias_bound_candidates_recur<G: GoalKind<D>>(
|
||||
&mut self,
|
||||
self_ty: I::Ty,
|
||||
goal: Goal<I, G>,
|
||||
|
|
@ -523,15 +521,13 @@ where
|
|||
|
||||
ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
|
||||
ty::Alias(ty::Inherent | ty::Weak, _) => {
|
||||
self.interner().delay_bug(format!("could not normalize {self_ty:?}, it is not WF"));
|
||||
self.cx().delay_bug(format!("could not normalize {self_ty:?}, it is not WF"));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
for assumption in self
|
||||
.interner()
|
||||
.item_bounds(alias_ty.def_id)
|
||||
.iter_instantiated(self.interner(), &alias_ty.args)
|
||||
for assumption in
|
||||
self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), &alias_ty.args)
|
||||
{
|
||||
candidates.extend(G::probe_and_consider_implied_clause(
|
||||
self,
|
||||
|
|
@ -556,12 +552,12 @@ where
|
|||
}
|
||||
|
||||
#[instrument(level = "trace", skip_all)]
|
||||
fn assemble_object_bound_candidates<G: GoalKind<Infcx>>(
|
||||
fn assemble_object_bound_candidates<G: GoalKind<D>>(
|
||||
&mut self,
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
if !tcx.trait_may_be_implemented_via_object(goal.predicate.trait_def_id(tcx)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -629,8 +625,7 @@ where
|
|||
// a projection goal.
|
||||
if let Some(principal) = bounds.principal() {
|
||||
let principal_trait_ref = principal.with_self_ty(tcx, self_ty);
|
||||
for (idx, assumption) in
|
||||
Infcx::elaborate_supertraits(tcx, principal_trait_ref).enumerate()
|
||||
for (idx, assumption) in D::elaborate_supertraits(tcx, principal_trait_ref).enumerate()
|
||||
{
|
||||
candidates.extend(G::probe_and_consider_object_bound_candidate(
|
||||
self,
|
||||
|
|
@ -649,12 +644,12 @@ where
|
|||
/// To do so we add an ambiguous candidate in case such an unknown impl could
|
||||
/// apply to the current goal.
|
||||
#[instrument(level = "trace", skip_all)]
|
||||
fn assemble_coherence_unknowable_candidates<G: GoalKind<Infcx>>(
|
||||
fn assemble_coherence_unknowable_candidates<G: GoalKind<D>>(
|
||||
&mut self,
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
|
||||
candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter(
|
||||
|ecx| {
|
||||
|
|
@ -678,12 +673,12 @@ where
|
|||
// to improve this however. However, this should make it fairly straightforward to refine
|
||||
// the filtering going forward, so it seems alright-ish for now.
|
||||
#[instrument(level = "debug", skip(self, goal))]
|
||||
fn discard_impls_shadowed_by_env<G: GoalKind<Infcx>>(
|
||||
fn discard_impls_shadowed_by_env<G: GoalKind<D>>(
|
||||
&mut self,
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let trait_goal: Goal<I, ty::TraitPredicate<I>> =
|
||||
goal.with(tcx, goal.predicate.trait_ref(tcx));
|
||||
|
||||
|
|
|
|||
|
|
@ -10,20 +10,20 @@ use rustc_type_ir::{self as ty, Interner, Upcast as _};
|
|||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::{EvalCtxt, Goal, NoSolution};
|
||||
|
||||
// Calculates the constituent types of a type for `auto trait` purposes.
|
||||
#[instrument(level = "trace", skip(ecx), ret)]
|
||||
pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<Infcx, I>(
|
||||
ecx: &EvalCtxt<'_, Infcx>,
|
||||
pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<D, I>(
|
||||
ecx: &EvalCtxt<'_, D>,
|
||||
ty: I::Ty,
|
||||
) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
match ty.kind() {
|
||||
ty::Uint(_)
|
||||
| ty::Int(_)
|
||||
|
|
@ -76,7 +76,7 @@ where
|
|||
}
|
||||
|
||||
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
||||
.interner()
|
||||
.cx()
|
||||
.bound_coroutine_hidden_types(def_id)
|
||||
.into_iter()
|
||||
.map(|bty| bty.instantiate(tcx, &args))
|
||||
|
|
@ -101,12 +101,12 @@ where
|
|||
}
|
||||
|
||||
#[instrument(level = "trace", skip(ecx), ret)]
|
||||
pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<Infcx, I>(
|
||||
ecx: &EvalCtxt<'_, Infcx>,
|
||||
pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<D, I>(
|
||||
ecx: &EvalCtxt<'_, D>,
|
||||
ty: I::Ty,
|
||||
) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
match ty.kind() {
|
||||
|
|
@ -159,8 +159,8 @@ where
|
|||
// "best effort" optimization and `sized_constraint` may return `Some`, even
|
||||
// if the ADT is sized for all possible args.
|
||||
ty::Adt(def, args) => {
|
||||
if let Some(sized_crit) = def.sized_constraint(ecx.interner()) {
|
||||
Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.interner(), &args))])
|
||||
if let Some(sized_crit) = def.sized_constraint(ecx.cx()) {
|
||||
Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), &args))])
|
||||
} else {
|
||||
Ok(vec![])
|
||||
}
|
||||
|
|
@ -169,12 +169,12 @@ where
|
|||
}
|
||||
|
||||
#[instrument(level = "trace", skip(ecx), ret)]
|
||||
pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<Infcx, I>(
|
||||
ecx: &EvalCtxt<'_, Infcx>,
|
||||
pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<D, I>(
|
||||
ecx: &EvalCtxt<'_, D>,
|
||||
ty: I::Ty,
|
||||
) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
match ty.kind() {
|
||||
|
|
@ -222,10 +222,10 @@ where
|
|||
|
||||
// only when `coroutine_clone` is enabled and the coroutine is movable
|
||||
// impl Copy/Clone for Coroutine where T: Copy/Clone forall T in (upvars, witnesses)
|
||||
ty::Coroutine(def_id, args) => match ecx.interner().coroutine_movability(def_id) {
|
||||
ty::Coroutine(def_id, args) => match ecx.cx().coroutine_movability(def_id) {
|
||||
Movability::Static => Err(NoSolution),
|
||||
Movability::Movable => {
|
||||
if ecx.interner().features().coroutine_clone() {
|
||||
if ecx.cx().features().coroutine_clone() {
|
||||
let coroutine = args.as_coroutine();
|
||||
Ok(vec![
|
||||
ty::Binder::dummy(coroutine.tupled_upvars_ty()),
|
||||
|
|
@ -239,10 +239,10 @@ where
|
|||
|
||||
// impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types
|
||||
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
||||
.interner()
|
||||
.cx()
|
||||
.bound_coroutine_hidden_types(def_id)
|
||||
.into_iter()
|
||||
.map(|bty| bty.instantiate(ecx.interner(), &args))
|
||||
.map(|bty| bty.instantiate(ecx.cx(), &args))
|
||||
.collect()),
|
||||
}
|
||||
}
|
||||
|
|
@ -656,17 +656,17 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
|
|||
// This is unsound in general and once that is fixed, we don't need to
|
||||
// normalize eagerly here. See https://github.com/lcnr/solver-woes/issues/9
|
||||
// for more details.
|
||||
pub(in crate::solve) fn predicates_for_object_candidate<Infcx, I>(
|
||||
ecx: &EvalCtxt<'_, Infcx>,
|
||||
pub(in crate::solve) fn predicates_for_object_candidate<D, I>(
|
||||
ecx: &EvalCtxt<'_, D>,
|
||||
param_env: I::ParamEnv,
|
||||
trait_ref: ty::TraitRef<I>,
|
||||
object_bounds: I::BoundExistentialPredicates,
|
||||
) -> Vec<Goal<I, I::Predicate>>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
let mut requirements = vec![];
|
||||
requirements
|
||||
.extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, &trait_ref.args));
|
||||
|
|
@ -712,18 +712,18 @@ where
|
|||
.collect()
|
||||
}
|
||||
|
||||
struct ReplaceProjectionWith<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> {
|
||||
ecx: &'a EvalCtxt<'a, Infcx>,
|
||||
struct ReplaceProjectionWith<'a, D: SolverDelegate<Interner = I>, I: Interner> {
|
||||
ecx: &'a EvalCtxt<'a, D>,
|
||||
param_env: I::ParamEnv,
|
||||
mapping: HashMap<I::DefId, ty::Binder<I, ty::ProjectionPredicate<I>>>,
|
||||
nested: Vec<Goal<I, I::Predicate>>,
|
||||
}
|
||||
|
||||
impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
||||
for ReplaceProjectionWith<'_, Infcx, I>
|
||||
impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
||||
for ReplaceProjectionWith<'_, D, I>
|
||||
{
|
||||
fn interner(&self) -> I {
|
||||
self.ecx.interner()
|
||||
fn cx(&self) -> I {
|
||||
self.ecx.cx()
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
|
||||
|
|
@ -739,7 +739,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
|
|||
.eq_and_get_goals(
|
||||
self.param_env,
|
||||
alias_ty,
|
||||
proj.projection_term.expect_ty(self.ecx.interner()),
|
||||
proj.projection_term.expect_ty(self.ecx.cx()),
|
||||
)
|
||||
.expect(
|
||||
"expected to be able to unify goal projection with dyn's projection",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use rustc_type_ir::{self as ty, Canonical, CanonicalVarValues, Interner};
|
|||
use tracing::{instrument, trace};
|
||||
|
||||
use crate::canonicalizer::{CanonicalizeMode, Canonicalizer};
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::resolve::EagerResolver;
|
||||
use crate::solve::eval_ctxt::NestedGoals;
|
||||
use crate::solve::inspect;
|
||||
|
|
@ -44,9 +44,9 @@ impl<I: Interner, T> ResponseT<I> for inspect::State<I, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
/// Canonicalizes the goal remembering the original values
|
||||
|
|
@ -55,19 +55,19 @@ where
|
|||
&self,
|
||||
goal: Goal<I, T>,
|
||||
) -> (Vec<I::GenericArg>, CanonicalInput<I, T>) {
|
||||
let opaque_types = self.infcx.clone_opaque_types_for_query_response();
|
||||
let opaque_types = self.delegate.clone_opaque_types_for_query_response();
|
||||
let (goal, opaque_types) =
|
||||
(goal, opaque_types).fold_with(&mut EagerResolver::new(self.infcx));
|
||||
(goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate));
|
||||
|
||||
let mut orig_values = Default::default();
|
||||
let canonical_goal = Canonicalizer::canonicalize(
|
||||
self.infcx,
|
||||
self.delegate,
|
||||
CanonicalizeMode::Input,
|
||||
&mut orig_values,
|
||||
QueryInput {
|
||||
goal,
|
||||
predefined_opaques_in_body: self
|
||||
.interner()
|
||||
.cx()
|
||||
.mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }),
|
||||
},
|
||||
);
|
||||
|
|
@ -97,7 +97,7 @@ where
|
|||
|
||||
// We only check for leaks from universes which were entered inside
|
||||
// of the query.
|
||||
self.infcx.leak_check(self.max_input_universe).map_err(|NoSolution| {
|
||||
self.delegate.leak_check(self.max_input_universe).map_err(|NoSolution| {
|
||||
trace!("failed the leak check");
|
||||
NoSolution
|
||||
})?;
|
||||
|
|
@ -125,21 +125,21 @@ where
|
|||
|
||||
let external_constraints =
|
||||
self.compute_external_query_constraints(certainty, normalization_nested_goals);
|
||||
let (var_values, mut external_constraints) =
|
||||
(self.var_values, external_constraints).fold_with(&mut EagerResolver::new(self.infcx));
|
||||
let (var_values, mut external_constraints) = (self.var_values, external_constraints)
|
||||
.fold_with(&mut EagerResolver::new(self.delegate));
|
||||
// Remove any trivial region constraints once we've resolved regions
|
||||
external_constraints
|
||||
.region_constraints
|
||||
.retain(|outlives| outlives.0.as_region().map_or(true, |re| re != outlives.1));
|
||||
|
||||
let canonical = Canonicalizer::canonicalize(
|
||||
self.infcx,
|
||||
self.delegate,
|
||||
CanonicalizeMode::Response { max_input_universe: self.max_input_universe },
|
||||
&mut Default::default(),
|
||||
Response {
|
||||
var_values,
|
||||
certainty,
|
||||
external_constraints: self.interner().mk_external_constraints(external_constraints),
|
||||
external_constraints: self.cx().mk_external_constraints(external_constraints),
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ where
|
|||
maybe_cause: MaybeCause,
|
||||
) -> CanonicalResponse<I> {
|
||||
response_no_constraints_raw(
|
||||
self.interner(),
|
||||
self.cx(),
|
||||
self.max_input_universe,
|
||||
self.variables,
|
||||
Certainty::Maybe(maybe_cause),
|
||||
|
|
@ -184,7 +184,7 @@ where
|
|||
// `tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs` and
|
||||
// `tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.rs`.
|
||||
let region_constraints = if certainty == Certainty::Yes {
|
||||
self.infcx.make_deduplicated_outlives_constraints()
|
||||
self.delegate.make_deduplicated_outlives_constraints()
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
|
|
@ -192,7 +192,7 @@ where
|
|||
ExternalConstraintsData {
|
||||
region_constraints,
|
||||
opaque_types: self
|
||||
.infcx
|
||||
.delegate
|
||||
.clone_opaque_types_for_query_response()
|
||||
.into_iter()
|
||||
// Only return *newly defined* opaque types.
|
||||
|
|
@ -219,15 +219,15 @@ where
|
|||
response: CanonicalResponse<I>,
|
||||
) -> (NestedNormalizationGoals<I>, Certainty) {
|
||||
let instantiation = Self::compute_query_response_instantiation_values(
|
||||
self.infcx,
|
||||
self.delegate,
|
||||
&original_values,
|
||||
&response,
|
||||
);
|
||||
|
||||
let Response { var_values, external_constraints, certainty } =
|
||||
self.infcx.instantiate_canonical(response, instantiation);
|
||||
self.delegate.instantiate_canonical(response, instantiation);
|
||||
|
||||
Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values);
|
||||
Self::unify_query_var_values(self.delegate, param_env, &original_values, var_values);
|
||||
|
||||
let ExternalConstraintsData {
|
||||
region_constraints,
|
||||
|
|
@ -243,17 +243,17 @@ where
|
|||
/// the canonical response. This depends on the `original_values` for the
|
||||
/// bound variables.
|
||||
fn compute_query_response_instantiation_values<T: ResponseT<I>>(
|
||||
infcx: &Infcx,
|
||||
delegate: &D,
|
||||
original_values: &[I::GenericArg],
|
||||
response: &Canonical<I, T>,
|
||||
) -> CanonicalVarValues<I> {
|
||||
// FIXME: Longterm canonical queries should deal with all placeholders
|
||||
// created inside of the query directly instead of returning them to the
|
||||
// caller.
|
||||
let prev_universe = infcx.universe();
|
||||
let prev_universe = delegate.universe();
|
||||
let universes_created_in_query = response.max_universe.index();
|
||||
for _ in 0..universes_created_in_query {
|
||||
infcx.create_next_universe();
|
||||
delegate.create_next_universe();
|
||||
}
|
||||
|
||||
let var_values = response.value.var_values();
|
||||
|
|
@ -290,13 +290,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
let var_values = infcx.interner().mk_args_from_iter(
|
||||
let var_values = delegate.cx().mk_args_from_iter(
|
||||
response.variables.into_iter().enumerate().map(|(index, info)| {
|
||||
if info.universe() != ty::UniverseIndex::ROOT {
|
||||
// A variable from inside a binder of the query. While ideally these shouldn't
|
||||
// exist at all (see the FIXME at the start of this method), we have to deal with
|
||||
// them for now.
|
||||
infcx.instantiate_canonical_var_with_infer(info, |idx| {
|
||||
delegate.instantiate_canonical_var_with_infer(info, |idx| {
|
||||
ty::UniverseIndex::from(prev_universe.index() + idx.index())
|
||||
})
|
||||
} else if info.is_existential() {
|
||||
|
|
@ -310,7 +310,7 @@ where
|
|||
if let Some(v) = opt_values[ty::BoundVar::from_usize(index)] {
|
||||
v
|
||||
} else {
|
||||
infcx.instantiate_canonical_var_with_infer(info, |_| prev_universe)
|
||||
delegate.instantiate_canonical_var_with_infer(info, |_| prev_universe)
|
||||
}
|
||||
} else {
|
||||
// For placeholders which were already part of the input, we simply map this
|
||||
|
|
@ -335,9 +335,9 @@ where
|
|||
/// whether an alias is rigid by using the trait solver. When instantiating a response
|
||||
/// from the solver we assume that the solver correctly handled aliases and therefore
|
||||
/// always relate them structurally here.
|
||||
#[instrument(level = "trace", skip(infcx))]
|
||||
#[instrument(level = "trace", skip(delegate))]
|
||||
fn unify_query_var_values(
|
||||
infcx: &Infcx,
|
||||
delegate: &D,
|
||||
param_env: I::ParamEnv,
|
||||
original_values: &[I::GenericArg],
|
||||
var_values: CanonicalVarValues<I>,
|
||||
|
|
@ -345,7 +345,8 @@ where
|
|||
assert_eq!(original_values.len(), var_values.len());
|
||||
|
||||
for (&orig, response) in iter::zip(original_values, var_values.var_values) {
|
||||
let goals = infcx.eq_structurally_relating_aliases(param_env, orig, response).unwrap();
|
||||
let goals =
|
||||
delegate.eq_structurally_relating_aliases(param_env, orig, response).unwrap();
|
||||
assert!(goals.is_empty());
|
||||
}
|
||||
}
|
||||
|
|
@ -365,7 +366,7 @@ where
|
|||
|
||||
fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)]) {
|
||||
for &(key, ty) in opaque_types {
|
||||
self.infcx.inject_new_hidden_type_unchecked(key, ty);
|
||||
self.delegate.inject_new_hidden_type_unchecked(key, ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -374,22 +375,22 @@ where
|
|||
/// evaluating a goal. The `var_values` not only include the bound variables
|
||||
/// of the query input, but also contain all unconstrained inference vars
|
||||
/// created while evaluating this goal.
|
||||
pub(in crate::solve) fn make_canonical_state<Infcx, T, I>(
|
||||
infcx: &Infcx,
|
||||
pub(in crate::solve) fn make_canonical_state<D, T, I>(
|
||||
delegate: &D,
|
||||
var_values: &[I::GenericArg],
|
||||
max_input_universe: ty::UniverseIndex,
|
||||
data: T,
|
||||
) -> inspect::CanonicalState<I, T>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
T: TypeFoldable<I>,
|
||||
{
|
||||
let var_values = CanonicalVarValues { var_values: infcx.interner().mk_args(var_values) };
|
||||
let var_values = CanonicalVarValues { var_values: delegate.cx().mk_args(var_values) };
|
||||
let state = inspect::State { var_values, data };
|
||||
let state = state.fold_with(&mut EagerResolver::new(infcx));
|
||||
let state = state.fold_with(&mut EagerResolver::new(delegate));
|
||||
Canonicalizer::canonicalize(
|
||||
infcx,
|
||||
delegate,
|
||||
CanonicalizeMode::Response { max_input_universe },
|
||||
&mut vec![],
|
||||
state,
|
||||
|
|
@ -398,15 +399,15 @@ where
|
|||
|
||||
// FIXME: needs to be pub to be accessed by downstream
|
||||
// `rustc_trait_selection::solve::inspect::analyse`.
|
||||
pub fn instantiate_canonical_state<Infcx, I, T: TypeFoldable<I>>(
|
||||
infcx: &Infcx,
|
||||
span: Infcx::Span,
|
||||
pub fn instantiate_canonical_state<D, I, T: TypeFoldable<I>>(
|
||||
delegate: &D,
|
||||
span: D::Span,
|
||||
param_env: I::ParamEnv,
|
||||
orig_values: &mut Vec<I::GenericArg>,
|
||||
state: inspect::CanonicalState<I, T>,
|
||||
) -> T
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
// In case any fresh inference variables have been created between `state`
|
||||
|
|
@ -415,15 +416,15 @@ where
|
|||
for &arg in &state.value.var_values.var_values[orig_values.len()..state.value.var_values.len()]
|
||||
{
|
||||
// FIXME: This is so ugly.
|
||||
let unconstrained = infcx.fresh_var_for_kind_with_span(arg, span);
|
||||
let unconstrained = delegate.fresh_var_for_kind_with_span(arg, span);
|
||||
orig_values.push(unconstrained);
|
||||
}
|
||||
|
||||
let instantiation =
|
||||
EvalCtxt::compute_query_response_instantiation_values(infcx, orig_values, &state);
|
||||
EvalCtxt::compute_query_response_instantiation_values(delegate, orig_values, &state);
|
||||
|
||||
let inspect::State { var_values, data } = infcx.instantiate_canonical(state, instantiation);
|
||||
let inspect::State { var_values, data } = delegate.instantiate_canonical(state, instantiation);
|
||||
|
||||
EvalCtxt::unify_query_var_values(infcx, param_env, orig_values, var_values);
|
||||
EvalCtxt::unify_query_var_values(delegate, param_env, orig_values, var_values);
|
||||
data
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use rustc_type_ir::{self as ty, CanonicalVarValues, Interner};
|
|||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::inspect::{self, ProofTreeBuilder};
|
||||
use crate::solve::search_graph::SearchGraph;
|
||||
use crate::solve::{
|
||||
|
|
@ -23,9 +23,9 @@ use crate::solve::{
|
|||
pub(super) mod canonical;
|
||||
mod probe;
|
||||
|
||||
pub struct EvalCtxt<'a, Infcx, I = <Infcx as SolverDelegate>::Interner>
|
||||
pub struct EvalCtxt<'a, D, I = <D as SolverDelegate>::Interner>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
/// The inference context that backs (mostly) inference and placeholder terms
|
||||
|
|
@ -43,7 +43,7 @@ where
|
|||
/// If some `InferCtxt` method is missing, please first think defensively about
|
||||
/// the method's compatibility with this solver, or if an existing one does
|
||||
/// the job already.
|
||||
infcx: &'a Infcx,
|
||||
delegate: &'a D,
|
||||
|
||||
/// The variable info for the `var_values`, only used to make an ambiguous response
|
||||
/// with no constraints.
|
||||
|
|
@ -83,7 +83,7 @@ where
|
|||
// evaluation code.
|
||||
tainted: Result<(), NoSolution>,
|
||||
|
||||
pub(super) inspect: ProofTreeBuilder<Infcx>,
|
||||
pub(super) inspect: ProofTreeBuilder<D>,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
|
|
@ -143,9 +143,9 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
|
|||
);
|
||||
}
|
||||
|
||||
impl<Infcx, I> SolverDelegateEvalExt for Infcx
|
||||
impl<D, I> SolverDelegateEvalExt for D
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
/// Evaluates a goal from **outside** of the trait solver.
|
||||
|
|
@ -178,9 +178,9 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, Infcx, I> EvalCtxt<'a, Infcx>
|
||||
impl<'a, D, I> EvalCtxt<'a, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
pub(super) fn solver_mode(&self) -> SolverMode {
|
||||
|
|
@ -195,22 +195,22 @@ where
|
|||
/// used from outside of any evaluation, and other methods should be preferred
|
||||
/// over using this manually (such as [`SolverDelegateEvalExt::evaluate_root_goal`]).
|
||||
pub(super) fn enter_root<R>(
|
||||
infcx: &Infcx,
|
||||
delegate: &D,
|
||||
generate_proof_tree: GenerateProofTree,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> R,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, D>) -> R,
|
||||
) -> (R, Option<inspect::GoalEvaluation<I>>) {
|
||||
let mut search_graph = search_graph::SearchGraph::new(infcx.solver_mode());
|
||||
let mut search_graph = search_graph::SearchGraph::new(delegate.solver_mode());
|
||||
|
||||
let mut ecx = EvalCtxt {
|
||||
infcx,
|
||||
delegate,
|
||||
search_graph: &mut search_graph,
|
||||
nested_goals: NestedGoals::new(),
|
||||
inspect: ProofTreeBuilder::new_maybe_root(generate_proof_tree),
|
||||
|
||||
// Only relevant when canonicalizing the response,
|
||||
// which we don't do within this evaluation context.
|
||||
predefined_opaques_in_body: infcx
|
||||
.interner()
|
||||
predefined_opaques_in_body: delegate
|
||||
.cx()
|
||||
.mk_predefined_opaques_in_body(PredefinedOpaquesData::default()),
|
||||
max_input_universe: ty::UniverseIndex::ROOT,
|
||||
variables: Default::default(),
|
||||
|
|
@ -242,14 +242,14 @@ where
|
|||
tcx: I,
|
||||
search_graph: &'a mut search_graph::SearchGraph<I>,
|
||||
canonical_input: CanonicalInput<I>,
|
||||
canonical_goal_evaluation: &mut ProofTreeBuilder<Infcx>,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, Infcx>, Goal<I, I::Predicate>) -> R,
|
||||
canonical_goal_evaluation: &mut ProofTreeBuilder<D>,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, D>, Goal<I, I::Predicate>) -> R,
|
||||
) -> R {
|
||||
let (ref infcx, input, var_values) =
|
||||
let (ref delegate, input, var_values) =
|
||||
SolverDelegate::build_with_canonical(tcx, search_graph.solver_mode(), &canonical_input);
|
||||
|
||||
let mut ecx = EvalCtxt {
|
||||
infcx,
|
||||
delegate,
|
||||
variables: canonical_input.variables,
|
||||
var_values,
|
||||
is_normalizes_to_goal: false,
|
||||
|
|
@ -262,7 +262,7 @@ where
|
|||
};
|
||||
|
||||
for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
|
||||
ecx.infcx.inject_new_hidden_type_unchecked(key, ty);
|
||||
ecx.delegate.inject_new_hidden_type_unchecked(key, ty);
|
||||
}
|
||||
|
||||
if !ecx.nested_goals.is_empty() {
|
||||
|
|
@ -270,7 +270,7 @@ where
|
|||
}
|
||||
|
||||
let result = f(&mut ecx, input.goal);
|
||||
ecx.inspect.probe_final_state(ecx.infcx, ecx.max_input_universe);
|
||||
ecx.inspect.probe_final_state(ecx.delegate, ecx.max_input_universe);
|
||||
canonical_goal_evaluation.goal_evaluation_step(ecx.inspect);
|
||||
|
||||
// When creating a query response we clone the opaque type constraints
|
||||
|
|
@ -278,7 +278,7 @@ where
|
|||
// assertions against dropping an `InferCtxt` without taking opaques.
|
||||
// FIXME: Once we remove support for the old impl we can remove this.
|
||||
// FIXME: Could we make `build_with_canonical` into `enter_with_canonical` and call this at the end?
|
||||
infcx.reset_opaque_types();
|
||||
delegate.reset_opaque_types();
|
||||
|
||||
result
|
||||
}
|
||||
|
|
@ -297,7 +297,7 @@ where
|
|||
tcx: I,
|
||||
search_graph: &'a mut search_graph::SearchGraph<I>,
|
||||
canonical_input: CanonicalInput<I>,
|
||||
goal_evaluation: &mut ProofTreeBuilder<Infcx>,
|
||||
goal_evaluation: &mut ProofTreeBuilder<D>,
|
||||
) -> QueryResult<I> {
|
||||
let mut canonical_goal_evaluation =
|
||||
goal_evaluation.new_canonical_goal_evaluation(canonical_input);
|
||||
|
|
@ -364,7 +364,7 @@ where
|
|||
let mut goal_evaluation =
|
||||
self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
|
||||
let canonical_response = EvalCtxt::evaluate_canonical_goal(
|
||||
self.interner(),
|
||||
self.cx(),
|
||||
self.search_graph,
|
||||
canonical_goal,
|
||||
&mut goal_evaluation,
|
||||
|
|
@ -466,8 +466,8 @@ where
|
|||
}
|
||||
}
|
||||
} else {
|
||||
self.infcx.enter_forall(kind, |kind| {
|
||||
let goal = goal.with(self.interner(), ty::Binder::dummy(kind));
|
||||
self.delegate.enter_forall(kind, |kind| {
|
||||
let goal = goal.with(self.cx(), ty::Binder::dummy(kind));
|
||||
self.add_goal(GoalSource::InstantiateHigherRanked, goal);
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
})
|
||||
|
|
@ -506,7 +506,7 @@ where
|
|||
///
|
||||
/// Goals for the next step get directly added to the nested goals of the `EvalCtxt`.
|
||||
fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let mut goals = core::mem::take(&mut self.nested_goals);
|
||||
|
||||
// If this loop did not result in any progress, what's our final certainty.
|
||||
|
|
@ -588,11 +588,11 @@ where
|
|||
|
||||
/// Record impl args in the proof tree for later access by `InspectCandidate`.
|
||||
pub(crate) fn record_impl_args(&mut self, impl_args: I::GenericArgs) {
|
||||
self.inspect.record_impl_args(self.infcx, self.max_input_universe, impl_args)
|
||||
self.inspect.record_impl_args(self.delegate, self.max_input_universe, impl_args)
|
||||
}
|
||||
|
||||
pub(super) fn interner(&self) -> I {
|
||||
self.infcx.interner()
|
||||
pub(super) fn cx(&self) -> I {
|
||||
self.delegate.cx()
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
|
|
@ -600,7 +600,7 @@ where
|
|||
goal.predicate = goal
|
||||
.predicate
|
||||
.fold_with(&mut ReplaceAliasWithInfer { ecx: self, param_env: goal.param_env });
|
||||
self.inspect.add_normalizes_to_goal(self.infcx, self.max_input_universe, goal);
|
||||
self.inspect.add_normalizes_to_goal(self.delegate, self.max_input_universe, goal);
|
||||
self.nested_goals.normalizes_to_goals.push(goal);
|
||||
}
|
||||
|
||||
|
|
@ -609,7 +609,7 @@ where
|
|||
goal.predicate = goal
|
||||
.predicate
|
||||
.fold_with(&mut ReplaceAliasWithInfer { ecx: self, param_env: goal.param_env });
|
||||
self.inspect.add_goal(self.infcx, self.max_input_universe, source, goal);
|
||||
self.inspect.add_goal(self.delegate, self.max_input_universe, source, goal);
|
||||
self.nested_goals.goals.push((source, goal));
|
||||
}
|
||||
|
||||
|
|
@ -625,13 +625,13 @@ where
|
|||
}
|
||||
|
||||
pub(super) fn next_ty_infer(&mut self) -> I::Ty {
|
||||
let ty = self.infcx.next_ty_infer();
|
||||
let ty = self.delegate.next_ty_infer();
|
||||
self.inspect.add_var_value(ty);
|
||||
ty
|
||||
}
|
||||
|
||||
pub(super) fn next_const_infer(&mut self) -> I::Const {
|
||||
let ct = self.infcx.next_const_infer();
|
||||
let ct = self.delegate.next_const_infer();
|
||||
self.inspect.add_var_value(ct);
|
||||
ct
|
||||
}
|
||||
|
|
@ -654,27 +654,27 @@ where
|
|||
let universe_of_term = match goal.predicate.term.kind() {
|
||||
ty::TermKind::Ty(ty) => {
|
||||
if let ty::Infer(ty::TyVar(vid)) = ty.kind() {
|
||||
self.infcx.universe_of_ty(vid).unwrap()
|
||||
self.delegate.universe_of_ty(vid).unwrap()
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ty::TermKind::Const(ct) => {
|
||||
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
|
||||
self.infcx.universe_of_ct(vid).unwrap()
|
||||
self.delegate.universe_of_ct(vid).unwrap()
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ContainsTermOrNotNameable<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> {
|
||||
struct ContainsTermOrNotNameable<'a, D: SolverDelegate<Interner = I>, I: Interner> {
|
||||
term: I::Term,
|
||||
universe_of_term: ty::UniverseIndex,
|
||||
infcx: &'a Infcx,
|
||||
delegate: &'a D,
|
||||
}
|
||||
|
||||
impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ContainsTermOrNotNameable<'_, Infcx, I> {
|
||||
impl<D: SolverDelegate<Interner = I>, I: Interner> ContainsTermOrNotNameable<'_, D, I> {
|
||||
fn check_nameable(&self, universe: ty::UniverseIndex) -> ControlFlow<()> {
|
||||
if self.universe_of_term.can_name(universe) {
|
||||
ControlFlow::Continue(())
|
||||
|
|
@ -684,8 +684,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeVisitor<I>
|
||||
for ContainsTermOrNotNameable<'_, Infcx, I>
|
||||
impl<D: SolverDelegate<Interner = I>, I: Interner> TypeVisitor<I>
|
||||
for ContainsTermOrNotNameable<'_, D, I>
|
||||
{
|
||||
type Result = ControlFlow<()>;
|
||||
fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
|
||||
|
|
@ -693,13 +693,15 @@ where
|
|||
ty::Infer(ty::TyVar(vid)) => {
|
||||
if let ty::TermKind::Ty(term) = self.term.kind() {
|
||||
if let ty::Infer(ty::TyVar(term_vid)) = term.kind() {
|
||||
if self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid) {
|
||||
if self.delegate.root_ty_var(vid)
|
||||
== self.delegate.root_ty_var(term_vid)
|
||||
{
|
||||
return ControlFlow::Break(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
|
||||
self.check_nameable(self.delegate.universe_of_ty(vid).unwrap())
|
||||
}
|
||||
ty::Placeholder(p) => self.check_nameable(p.universe()),
|
||||
_ => {
|
||||
|
|
@ -718,15 +720,15 @@ where
|
|||
if let ty::TermKind::Const(term) = self.term.kind() {
|
||||
if let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
|
||||
{
|
||||
if self.infcx.root_const_var(vid)
|
||||
== self.infcx.root_const_var(term_vid)
|
||||
if self.delegate.root_const_var(vid)
|
||||
== self.delegate.root_const_var(term_vid)
|
||||
{
|
||||
return ControlFlow::Break(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
|
||||
self.check_nameable(self.delegate.universe_of_ct(vid).unwrap())
|
||||
}
|
||||
ty::ConstKind::Placeholder(p) => self.check_nameable(p.universe()),
|
||||
_ => {
|
||||
|
|
@ -741,7 +743,7 @@ where
|
|||
}
|
||||
|
||||
let mut visitor = ContainsTermOrNotNameable {
|
||||
infcx: self.infcx,
|
||||
delegate: self.delegate,
|
||||
universe_of_term,
|
||||
term: goal.predicate.term,
|
||||
};
|
||||
|
|
@ -775,7 +777,7 @@ where
|
|||
// NOTE: this check is purely an optimization, the structural eq would
|
||||
// always fail if the term is not an inference variable.
|
||||
if term.is_infer() {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
// We need to relate `alias` to `term` treating only the outermost
|
||||
// constructor as rigid, relating any contained generic arguments as
|
||||
// normal. We do this by first structurally equating the `term`
|
||||
|
|
@ -788,7 +790,7 @@ where
|
|||
let rigid_ctor = ty::AliasTerm::new(tcx, alias.def_id, identity_args);
|
||||
let ctor_term = rigid_ctor.to_term(tcx);
|
||||
let obligations =
|
||||
self.infcx.eq_structurally_relating_aliases(param_env, term, ctor_term)?;
|
||||
self.delegate.eq_structurally_relating_aliases(param_env, term, ctor_term)?;
|
||||
debug_assert!(obligations.is_empty());
|
||||
self.relate(param_env, alias, variance, rigid_ctor)
|
||||
} else {
|
||||
|
|
@ -806,7 +808,7 @@ where
|
|||
lhs: T,
|
||||
rhs: T,
|
||||
) -> Result<(), NoSolution> {
|
||||
let result = self.infcx.eq_structurally_relating_aliases(param_env, lhs, rhs)?;
|
||||
let result = self.delegate.eq_structurally_relating_aliases(param_env, lhs, rhs)?;
|
||||
assert_eq!(result, vec![]);
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -829,7 +831,7 @@ where
|
|||
variance: ty::Variance,
|
||||
rhs: T,
|
||||
) -> Result<(), NoSolution> {
|
||||
let goals = self.infcx.relate(param_env, lhs, variance, rhs)?;
|
||||
let goals = self.delegate.relate(param_env, lhs, variance, rhs)?;
|
||||
self.add_goals(GoalSource::Misc, goals);
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -846,14 +848,14 @@ where
|
|||
lhs: T,
|
||||
rhs: T,
|
||||
) -> Result<Vec<Goal<I, I::Predicate>>, NoSolution> {
|
||||
self.infcx.relate(param_env, lhs, ty::Variance::Invariant, rhs)
|
||||
self.delegate.relate(param_env, lhs, ty::Variance::Invariant, rhs)
|
||||
}
|
||||
|
||||
pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<I> + Copy>(
|
||||
&self,
|
||||
value: ty::Binder<I, T>,
|
||||
) -> T {
|
||||
self.infcx.instantiate_binder_with_infer(value)
|
||||
self.delegate.instantiate_binder_with_infer(value)
|
||||
}
|
||||
|
||||
pub(super) fn enter_forall<T: TypeFoldable<I> + Copy, U>(
|
||||
|
|
@ -861,18 +863,18 @@ where
|
|||
value: ty::Binder<I, T>,
|
||||
f: impl FnOnce(T) -> U,
|
||||
) -> U {
|
||||
self.infcx.enter_forall(value, f)
|
||||
self.delegate.enter_forall(value, f)
|
||||
}
|
||||
|
||||
pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T
|
||||
where
|
||||
T: TypeFoldable<I>,
|
||||
{
|
||||
self.infcx.resolve_vars_if_possible(value)
|
||||
self.delegate.resolve_vars_if_possible(value)
|
||||
}
|
||||
|
||||
pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs {
|
||||
let args = self.infcx.fresh_args_for_item(def_id);
|
||||
let args = self.delegate.fresh_args_for_item(def_id);
|
||||
for arg in args {
|
||||
self.inspect.add_var_value(arg);
|
||||
}
|
||||
|
|
@ -880,12 +882,12 @@ where
|
|||
}
|
||||
|
||||
pub(super) fn register_ty_outlives(&self, ty: I::Ty, lt: I::Region) {
|
||||
self.infcx.register_ty_outlives(ty, lt);
|
||||
self.delegate.register_ty_outlives(ty, lt);
|
||||
}
|
||||
|
||||
pub(super) fn register_region_outlives(&self, a: I::Region, b: I::Region) {
|
||||
// `b : a` ==> `a <= b`
|
||||
self.infcx.sub_regions(b, a);
|
||||
self.delegate.sub_regions(b, a);
|
||||
}
|
||||
|
||||
/// Computes the list of goals required for `arg` to be well-formed
|
||||
|
|
@ -894,7 +896,7 @@ where
|
|||
param_env: I::ParamEnv,
|
||||
arg: I::GenericArg,
|
||||
) -> Option<Vec<Goal<I, I::Predicate>>> {
|
||||
self.infcx.well_formed_goals(param_env, arg)
|
||||
self.delegate.well_formed_goals(param_env, arg)
|
||||
}
|
||||
|
||||
pub(super) fn trait_ref_is_knowable(
|
||||
|
|
@ -902,9 +904,9 @@ where
|
|||
param_env: I::ParamEnv,
|
||||
trait_ref: ty::TraitRef<I>,
|
||||
) -> Result<bool, NoSolution> {
|
||||
let infcx = self.infcx;
|
||||
let delegate = self.delegate;
|
||||
let lazily_normalize_ty = |ty| self.structurally_normalize_ty(param_env, ty);
|
||||
infcx.trait_ref_is_knowable(trait_ref, lazily_normalize_ty)
|
||||
delegate.trait_ref_is_knowable(trait_ref, lazily_normalize_ty)
|
||||
}
|
||||
|
||||
pub(super) fn fetch_eligible_assoc_item(
|
||||
|
|
@ -914,7 +916,7 @@ where
|
|||
trait_assoc_def_id: I::DefId,
|
||||
impl_def_id: I::DefId,
|
||||
) -> Result<Option<I::DefId>, NoSolution> {
|
||||
self.infcx.fetch_eligible_assoc_item(
|
||||
self.delegate.fetch_eligible_assoc_item(
|
||||
param_env,
|
||||
goal_trait_ref,
|
||||
trait_assoc_def_id,
|
||||
|
|
@ -923,7 +925,7 @@ where
|
|||
}
|
||||
|
||||
pub(super) fn can_define_opaque_ty(&self, def_id: I::LocalDefId) -> bool {
|
||||
self.infcx.defining_opaque_types().contains(&def_id)
|
||||
self.delegate.defining_opaque_types().contains(&def_id)
|
||||
}
|
||||
|
||||
pub(super) fn insert_hidden_type(
|
||||
|
|
@ -933,7 +935,7 @@ where
|
|||
hidden_ty: I::Ty,
|
||||
) -> Result<(), NoSolution> {
|
||||
let mut goals = Vec::new();
|
||||
self.infcx.insert_hidden_type(opaque_type_key, param_env, hidden_ty, &mut goals)?;
|
||||
self.delegate.insert_hidden_type(opaque_type_key, param_env, hidden_ty, &mut goals)?;
|
||||
self.add_goals(GoalSource::Misc, goals);
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -946,7 +948,7 @@ where
|
|||
hidden_ty: I::Ty,
|
||||
) {
|
||||
let mut goals = Vec::new();
|
||||
self.infcx.add_item_bounds_for_hidden_type(
|
||||
self.delegate.add_item_bounds_for_hidden_type(
|
||||
opaque_def_id,
|
||||
opaque_args,
|
||||
param_env,
|
||||
|
|
@ -965,7 +967,7 @@ where
|
|||
ty: I::Ty,
|
||||
) -> Vec<CanonicalResponse<I>> {
|
||||
// FIXME: Super inefficient to be cloning this...
|
||||
let opaques = self.infcx.clone_opaque_types_for_query_response();
|
||||
let opaques = self.delegate.clone_opaque_types_for_query_response();
|
||||
|
||||
let mut values = vec![];
|
||||
for (candidate_key, candidate_ty) in opaques {
|
||||
|
|
@ -1002,7 +1004,7 @@ where
|
|||
param_env: I::ParamEnv,
|
||||
unevaluated: ty::UnevaluatedConst<I>,
|
||||
) -> Option<I::Const> {
|
||||
self.infcx.try_const_eval_resolve(param_env, unevaluated)
|
||||
self.delegate.try_const_eval_resolve(param_env, unevaluated)
|
||||
}
|
||||
|
||||
pub(super) fn is_transmutable(
|
||||
|
|
@ -1012,7 +1014,7 @@ where
|
|||
src: I::Ty,
|
||||
assume: I::Const,
|
||||
) -> Result<Certainty, NoSolution> {
|
||||
self.infcx.is_transmutable(param_env, dst, src, assume)
|
||||
self.delegate.is_transmutable(param_env, dst, src, assume)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1023,22 +1025,22 @@ where
|
|||
///
|
||||
/// This is a performance optimization to more eagerly detect cycles during trait
|
||||
/// solving. See tests/ui/traits/next-solver/cycles/cycle-modulo-ambig-aliases.rs.
|
||||
struct ReplaceAliasWithInfer<'me, 'a, Infcx, I>
|
||||
struct ReplaceAliasWithInfer<'me, 'a, D, I>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
ecx: &'me mut EvalCtxt<'a, Infcx>,
|
||||
ecx: &'me mut EvalCtxt<'a, D>,
|
||||
param_env: I::ParamEnv,
|
||||
}
|
||||
|
||||
impl<Infcx, I> TypeFolder<I> for ReplaceAliasWithInfer<'_, '_, Infcx, I>
|
||||
impl<D, I> TypeFolder<I> for ReplaceAliasWithInfer<'_, '_, D, I>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
fn interner(&self) -> I {
|
||||
self.ecx.interner()
|
||||
fn cx(&self) -> I {
|
||||
self.ecx.cx()
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
|
||||
|
|
@ -1052,7 +1054,7 @@ where
|
|||
);
|
||||
self.ecx.add_goal(
|
||||
GoalSource::Misc,
|
||||
Goal::new(self.interner(), self.param_env, normalizes_to),
|
||||
Goal::new(self.cx(), self.param_env, normalizes_to),
|
||||
);
|
||||
infer_ty
|
||||
}
|
||||
|
|
@ -1071,7 +1073,7 @@ where
|
|||
);
|
||||
self.ecx.add_goal(
|
||||
GoalSource::Misc,
|
||||
Goal::new(self.interner(), self.param_env, normalizes_to),
|
||||
Goal::new(self.cx(), self.param_env, normalizes_to),
|
||||
);
|
||||
infer_ct
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,34 +3,34 @@ use std::marker::PhantomData;
|
|||
use rustc_type_ir::Interner;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::assembly::Candidate;
|
||||
use crate::solve::inspect;
|
||||
use crate::solve::{BuiltinImplSource, CandidateSource, EvalCtxt, NoSolution, QueryResult};
|
||||
|
||||
pub(in crate::solve) struct ProbeCtxt<'me, 'a, Infcx, I, F, T>
|
||||
pub(in crate::solve) struct ProbeCtxt<'me, 'a, D, I, F, T>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
ecx: &'me mut EvalCtxt<'a, Infcx, I>,
|
||||
ecx: &'me mut EvalCtxt<'a, D, I>,
|
||||
probe_kind: F,
|
||||
_result: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<Infcx, I, F, T> ProbeCtxt<'_, '_, Infcx, I, F, T>
|
||||
impl<D, I, F, T> ProbeCtxt<'_, '_, D, I, F, T>
|
||||
where
|
||||
F: FnOnce(&T) -> inspect::ProbeKind<I>,
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> T) -> T {
|
||||
pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, D>) -> T) -> T {
|
||||
let ProbeCtxt { ecx: outer_ecx, probe_kind, _result } = self;
|
||||
|
||||
let infcx = outer_ecx.infcx;
|
||||
let delegate = outer_ecx.delegate;
|
||||
let max_input_universe = outer_ecx.max_input_universe;
|
||||
let mut nested_ecx = EvalCtxt {
|
||||
infcx,
|
||||
delegate,
|
||||
variables: outer_ecx.variables,
|
||||
var_values: outer_ecx.var_values,
|
||||
is_normalizes_to_goal: outer_ecx.is_normalizes_to_goal,
|
||||
|
|
@ -41,9 +41,9 @@ where
|
|||
tainted: outer_ecx.tainted,
|
||||
inspect: outer_ecx.inspect.take_and_enter_probe(),
|
||||
};
|
||||
let r = nested_ecx.infcx.probe(|| {
|
||||
let r = nested_ecx.delegate.probe(|| {
|
||||
let r = f(&mut nested_ecx);
|
||||
nested_ecx.inspect.probe_final_state(infcx, max_input_universe);
|
||||
nested_ecx.inspect.probe_final_state(delegate, max_input_universe);
|
||||
r
|
||||
});
|
||||
if !nested_ecx.inspect.is_noop() {
|
||||
|
|
@ -55,41 +55,38 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub(in crate::solve) struct TraitProbeCtxt<'me, 'a, Infcx, I, F>
|
||||
pub(in crate::solve) struct TraitProbeCtxt<'me, 'a, D, I, F>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
cx: ProbeCtxt<'me, 'a, Infcx, I, F, QueryResult<I>>,
|
||||
cx: ProbeCtxt<'me, 'a, D, I, F, QueryResult<I>>,
|
||||
source: CandidateSource<I>,
|
||||
}
|
||||
|
||||
impl<Infcx, I, F> TraitProbeCtxt<'_, '_, Infcx, I, F>
|
||||
impl<D, I, F> TraitProbeCtxt<'_, '_, D, I, F>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
F: FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>,
|
||||
{
|
||||
#[instrument(level = "debug", skip_all, fields(source = ?self.source))]
|
||||
pub(in crate::solve) fn enter(
|
||||
self,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> QueryResult<I>,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
self.cx.enter(|ecx| f(ecx)).map(|result| Candidate { source: self.source, result })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Infcx, I> EvalCtxt<'a, Infcx, I>
|
||||
impl<'a, D, I> EvalCtxt<'a, D, I>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
/// `probe_kind` is only called when proof tree building is enabled so it can be
|
||||
/// as expensive as necessary to output the desired information.
|
||||
pub(in crate::solve) fn probe<F, T>(
|
||||
&mut self,
|
||||
probe_kind: F,
|
||||
) -> ProbeCtxt<'_, 'a, Infcx, I, F, T>
|
||||
pub(in crate::solve) fn probe<F, T>(&mut self, probe_kind: F) -> ProbeCtxt<'_, 'a, D, I, F, T>
|
||||
where
|
||||
F: FnOnce(&T) -> inspect::ProbeKind<I>,
|
||||
{
|
||||
|
|
@ -99,16 +96,14 @@ where
|
|||
pub(in crate::solve) fn probe_builtin_trait_candidate(
|
||||
&mut self,
|
||||
source: BuiltinImplSource,
|
||||
) -> TraitProbeCtxt<'_, 'a, Infcx, I, impl FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>>
|
||||
{
|
||||
) -> TraitProbeCtxt<'_, 'a, D, I, impl FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>> {
|
||||
self.probe_trait_candidate(CandidateSource::BuiltinImpl(source))
|
||||
}
|
||||
|
||||
pub(in crate::solve) fn probe_trait_candidate(
|
||||
&mut self,
|
||||
source: CandidateSource<I>,
|
||||
) -> TraitProbeCtxt<'_, 'a, Infcx, I, impl FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>>
|
||||
{
|
||||
) -> TraitProbeCtxt<'_, 'a, D, I, impl FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>> {
|
||||
TraitProbeCtxt {
|
||||
cx: ProbeCtxt {
|
||||
ecx: self,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use std::mem;
|
|||
|
||||
use rustc_type_ir::{self as ty, Interner};
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::eval_ctxt::canonical;
|
||||
use crate::solve::inspect;
|
||||
use crate::solve::{
|
||||
|
|
@ -37,12 +37,12 @@ use crate::solve::{
|
|||
/// trees. At the end of trait solving `ProofTreeBuilder::finalize`
|
||||
/// is called to recursively convert the whole structure to a
|
||||
/// finished proof tree.
|
||||
pub(in crate::solve) struct ProofTreeBuilder<Infcx, I = <Infcx as SolverDelegate>::Interner>
|
||||
pub(in crate::solve) struct ProofTreeBuilder<D, I = <D as SolverDelegate>::Interner>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
_infcx: PhantomData<Infcx>,
|
||||
_infcx: PhantomData<D>,
|
||||
state: Option<Box<DebugSolver<I>>>,
|
||||
}
|
||||
|
||||
|
|
@ -235,8 +235,8 @@ impl<I: Interner> WipProbeStep<I> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
||||
fn new(state: impl Into<DebugSolver<I>>) -> ProofTreeBuilder<Infcx> {
|
||||
impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
|
||||
fn new(state: impl Into<DebugSolver<I>>) -> ProofTreeBuilder<D> {
|
||||
ProofTreeBuilder { state: Some(Box::new(state.into())), _infcx: PhantomData }
|
||||
}
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
self.state.as_deref_mut()
|
||||
}
|
||||
|
||||
pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder<Infcx> {
|
||||
pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder<D> {
|
||||
let mut nested = ProofTreeBuilder { state: self.state.take(), _infcx: PhantomData };
|
||||
nested.enter_probe();
|
||||
nested
|
||||
|
|
@ -273,18 +273,18 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_maybe_root(generate_proof_tree: GenerateProofTree) -> ProofTreeBuilder<Infcx> {
|
||||
pub fn new_maybe_root(generate_proof_tree: GenerateProofTree) -> ProofTreeBuilder<D> {
|
||||
match generate_proof_tree {
|
||||
GenerateProofTree::No => ProofTreeBuilder::new_noop(),
|
||||
GenerateProofTree::Yes => ProofTreeBuilder::new_root(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_root() -> ProofTreeBuilder<Infcx> {
|
||||
pub fn new_root() -> ProofTreeBuilder<D> {
|
||||
ProofTreeBuilder::new(DebugSolver::Root)
|
||||
}
|
||||
|
||||
pub fn new_noop() -> ProofTreeBuilder<Infcx> {
|
||||
pub fn new_noop() -> ProofTreeBuilder<D> {
|
||||
ProofTreeBuilder { state: None, _infcx: PhantomData }
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
goal: Goal<I, I::Predicate>,
|
||||
orig_values: &[I::GenericArg],
|
||||
kind: GoalEvaluationKind,
|
||||
) -> ProofTreeBuilder<Infcx> {
|
||||
) -> ProofTreeBuilder<D> {
|
||||
self.opt_nested(|| match kind {
|
||||
GoalEvaluationKind::Root => Some(WipGoalEvaluation {
|
||||
uncanonicalized_goal: goal,
|
||||
|
|
@ -311,7 +311,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
pub fn new_canonical_goal_evaluation(
|
||||
&mut self,
|
||||
goal: CanonicalInput<I>,
|
||||
) -> ProofTreeBuilder<Infcx> {
|
||||
) -> ProofTreeBuilder<D> {
|
||||
self.nested(|| WipCanonicalGoalEvaluation {
|
||||
goal,
|
||||
kind: None,
|
||||
|
|
@ -337,10 +337,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn canonical_goal_evaluation(
|
||||
&mut self,
|
||||
canonical_goal_evaluation: ProofTreeBuilder<Infcx>,
|
||||
) {
|
||||
pub fn canonical_goal_evaluation(&mut self, canonical_goal_evaluation: ProofTreeBuilder<D>) {
|
||||
if let Some(this) = self.as_mut() {
|
||||
match (this, *canonical_goal_evaluation.state.unwrap()) {
|
||||
(
|
||||
|
|
@ -366,7 +363,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<Infcx>) {
|
||||
pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<D>) {
|
||||
if let Some(this) = self.as_mut() {
|
||||
match this {
|
||||
DebugSolver::Root => *this = *goal_evaluation.state.unwrap(),
|
||||
|
|
@ -382,7 +379,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
&mut self,
|
||||
var_values: ty::CanonicalVarValues<I>,
|
||||
instantiated_goal: QueryInput<I, I::Predicate>,
|
||||
) -> ProofTreeBuilder<Infcx> {
|
||||
) -> ProofTreeBuilder<D> {
|
||||
self.nested(|| WipCanonicalGoalEvaluationStep {
|
||||
var_values: var_values.var_values.to_vec(),
|
||||
instantiated_goal,
|
||||
|
|
@ -396,7 +393,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<Infcx>) {
|
||||
pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<D>) {
|
||||
if let Some(this) = self.as_mut() {
|
||||
match (this, *goal_evaluation_step.state.unwrap()) {
|
||||
(
|
||||
|
|
@ -448,12 +445,12 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn probe_final_state(&mut self, infcx: &Infcx, max_input_universe: ty::UniverseIndex) {
|
||||
pub fn probe_final_state(&mut self, delegate: &D, max_input_universe: ty::UniverseIndex) {
|
||||
match self.as_mut() {
|
||||
None => {}
|
||||
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
|
||||
let final_state = canonical::make_canonical_state(
|
||||
infcx,
|
||||
delegate,
|
||||
&state.var_values,
|
||||
max_input_universe,
|
||||
(),
|
||||
|
|
@ -467,21 +464,21 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
|
||||
pub fn add_normalizes_to_goal(
|
||||
&mut self,
|
||||
infcx: &Infcx,
|
||||
delegate: &D,
|
||||
max_input_universe: ty::UniverseIndex,
|
||||
goal: Goal<I, ty::NormalizesTo<I>>,
|
||||
) {
|
||||
self.add_goal(
|
||||
infcx,
|
||||
delegate,
|
||||
max_input_universe,
|
||||
GoalSource::Misc,
|
||||
goal.with(infcx.interner(), goal.predicate),
|
||||
goal.with(delegate.cx(), goal.predicate),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn add_goal(
|
||||
&mut self,
|
||||
infcx: &Infcx,
|
||||
delegate: &D,
|
||||
max_input_universe: ty::UniverseIndex,
|
||||
source: GoalSource,
|
||||
goal: Goal<I, I::Predicate>,
|
||||
|
|
@ -490,7 +487,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
None => {}
|
||||
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
|
||||
let goal = canonical::make_canonical_state(
|
||||
infcx,
|
||||
delegate,
|
||||
&state.var_values,
|
||||
max_input_universe,
|
||||
goal,
|
||||
|
|
@ -503,14 +500,14 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
|
||||
pub(crate) fn record_impl_args(
|
||||
&mut self,
|
||||
infcx: &Infcx,
|
||||
delegate: &D,
|
||||
max_input_universe: ty::UniverseIndex,
|
||||
impl_args: I::GenericArgs,
|
||||
) {
|
||||
match self.as_mut() {
|
||||
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
|
||||
let impl_args = canonical::make_canonical_state(
|
||||
infcx,
|
||||
delegate,
|
||||
&state.var_values,
|
||||
max_input_universe,
|
||||
impl_args,
|
||||
|
|
@ -538,7 +535,7 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn finish_probe(mut self) -> ProofTreeBuilder<Infcx> {
|
||||
pub fn finish_probe(mut self) -> ProofTreeBuilder<D> {
|
||||
match self.as_mut() {
|
||||
None => {}
|
||||
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ use rustc_type_ir::{self as ty, Interner};
|
|||
use tracing::instrument;
|
||||
|
||||
pub use self::eval_ctxt::{EvalCtxt, GenerateProofTree, SolverDelegateEvalExt};
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
|
||||
/// How many fixpoint iterations we should attempt inside of the solver before bailing
|
||||
/// with overflow.
|
||||
|
|
@ -56,9 +56,9 @@ fn has_no_inference_or_external_constraints<I: Interner>(
|
|||
&& response.value.external_constraints.opaque_types.is_empty()
|
||||
}
|
||||
|
||||
impl<'a, Infcx, I> EvalCtxt<'a, Infcx>
|
||||
impl<'a, D, I> EvalCtxt<'a, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
|
|
@ -104,7 +104,7 @@ where
|
|||
}
|
||||
|
||||
fn compute_object_safe_goal(&mut self, trait_def_id: I::DefId) -> QueryResult<I> {
|
||||
if self.interner().trait_is_object_safe(trait_def_id) {
|
||||
if self.cx().trait_is_object_safe(trait_def_id) {
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
|
|
@ -182,7 +182,7 @@ where
|
|||
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
|
||||
}
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
self.interner().type_of(uv.def).instantiate(self.interner(), &uv.args)
|
||||
self.cx().type_of(uv.def).instantiate(self.cx(), &uv.args)
|
||||
}
|
||||
ty::ConstKind::Expr(_) => unimplemented!(
|
||||
"`feature(generic_const_exprs)` is not supported in the new trait solver"
|
||||
|
|
@ -193,7 +193,7 @@ where
|
|||
ty::ConstKind::Bound(_, _) => panic!("escaping bound vars in {:?}", ct),
|
||||
ty::ConstKind::Value(ty, _) => ty,
|
||||
ty::ConstKind::Placeholder(placeholder) => {
|
||||
self.interner().find_const_ty_from_env(goal.param_env, placeholder)
|
||||
self.cx().find_const_ty_from_env(goal.param_env, placeholder)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -202,9 +202,9 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
/// Try to merge multiple possible ways to prove a goal, if that is not possible returns `None`.
|
||||
|
|
@ -267,7 +267,7 @@ where
|
|||
if let ty::Alias(..) = ty.kind() {
|
||||
let normalized_ty = self.next_ty_infer();
|
||||
let alias_relate_goal = Goal::new(
|
||||
self.interner(),
|
||||
self.cx(),
|
||||
param_env,
|
||||
ty::PredicateKind::AliasRelate(
|
||||
ty.into(),
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use rustc_type_ir::{self as ty, Interner};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::{Certainty, EvalCtxt, Goal, QueryResult};
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
|
|
|
|||
|
|
@ -7,19 +7,19 @@
|
|||
|
||||
use rustc_type_ir::{self as ty, Interner};
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::{Certainty, EvalCtxt, Goal, GoalSource, QueryResult};
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
pub(super) fn normalize_inherent_associated_type(
|
||||
&mut self,
|
||||
goal: Goal<I, ty::NormalizesTo<I>>,
|
||||
) -> QueryResult<I> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let inherent = goal.predicate.alias.expect_ty(tcx);
|
||||
|
||||
let impl_def_id = tcx.parent(inherent.def_id);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use rustc_type_ir::Upcast as _;
|
|||
use rustc_type_ir::{self as ty, Interner, NormalizesTo};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::assembly::structural_traits::{self, AsyncCallableRelevantTypes};
|
||||
use crate::solve::assembly::{self, Candidate};
|
||||
use crate::solve::inspect::ProbeKind;
|
||||
|
|
@ -18,9 +18,9 @@ use crate::solve::{
|
|||
NoSolution, QueryResult,
|
||||
};
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
|
|
@ -48,7 +48,7 @@ where
|
|||
/// returns `NoSolution`.
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn normalize_at_least_one_step(&mut self, goal: Goal<I, NormalizesTo<I>>) -> QueryResult<I> {
|
||||
match goal.predicate.alias.kind(self.interner()) {
|
||||
match goal.predicate.alias.kind(self.cx()) {
|
||||
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
|
||||
let candidates = self.assemble_and_evaluate_candidates(goal);
|
||||
self.merge_candidates(candidates)
|
||||
|
|
@ -75,9 +75,9 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Infcx, I> assembly::GoalKind<Infcx> for NormalizesTo<I>
|
||||
impl<D, I> assembly::GoalKind<D> for NormalizesTo<I>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
fn self_ty(self) -> I::Ty {
|
||||
|
|
@ -97,15 +97,15 @@ where
|
|||
}
|
||||
|
||||
fn probe_and_match_goal_against_assumption(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
source: CandidateSource<I>,
|
||||
goal: Goal<I, Self>,
|
||||
assumption: I::Clause,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> QueryResult<I>,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if let Some(projection_pred) = assumption.as_projection_clause() {
|
||||
if projection_pred.projection_def_id() == goal.predicate.def_id() {
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
ecx.probe_trait_candidate(source).enter(|ecx| {
|
||||
let assumption_projection_pred =
|
||||
ecx.instantiate_binder_with_infer(projection_pred);
|
||||
|
|
@ -136,15 +136,15 @@ where
|
|||
}
|
||||
|
||||
fn consider_impl_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, NormalizesTo<I>>,
|
||||
impl_def_id: I::DefId,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
|
||||
let goal_trait_ref = goal.predicate.alias.trait_ref(tcx);
|
||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
|
||||
if !ecx.interner().args_may_unify_deep(
|
||||
if !ecx.cx().args_may_unify_deep(
|
||||
goal.predicate.alias.trait_ref(tcx).args,
|
||||
impl_trait_ref.skip_binder().args,
|
||||
) {
|
||||
|
|
@ -194,7 +194,7 @@ where
|
|||
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
|
||||
};
|
||||
|
||||
let error_response = |ecx: &mut EvalCtxt<'_, Infcx>, msg: &str| {
|
||||
let error_response = |ecx: &mut EvalCtxt<'_, D>, msg: &str| {
|
||||
let guar = tcx.delay_bug(msg);
|
||||
let error_term = match goal.predicate.alias.kind(tcx) {
|
||||
ty::AliasTermKind::ProjectionTy => Ty::new_error(tcx, guar).into(),
|
||||
|
|
@ -262,61 +262,61 @@ where
|
|||
/// Fail to normalize if the predicate contains an error, alternatively, we could normalize to `ty::Error`
|
||||
/// and succeed. Can experiment with this to figure out what results in better error messages.
|
||||
fn consider_error_guaranteed_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
_guar: I::ErrorGuaranteed,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
Err(NoSolution)
|
||||
}
|
||||
|
||||
fn consider_auto_trait_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
_goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
ecx.interner().delay_bug("associated types not allowed on auto traits");
|
||||
ecx.cx().delay_bug("associated types not allowed on auto traits");
|
||||
Err(NoSolution)
|
||||
}
|
||||
|
||||
fn consider_trait_alias_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
panic!("trait aliases do not have associated types: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_sized_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
panic!("`Sized` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_copy_clone_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
panic!("`Copy`/`Clone` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_pointer_like_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
panic!("`PointerLike` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_fn_ptr_trait_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
panic!("`FnPtr` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_fn_trait_candidates(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
let tupled_inputs_and_output =
|
||||
match structural_traits::extract_tupled_inputs_and_output_from_callable(
|
||||
tcx,
|
||||
|
|
@ -355,11 +355,11 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_async_fn_trait_candidates(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
|
||||
let env_region = match goal_kind {
|
||||
ty::ClosureKind::Fn | ty::ClosureKind::FnMut => goal.predicate.alias.args.region_at(2),
|
||||
|
|
@ -457,7 +457,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_async_fn_kind_helper_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let [
|
||||
|
|
@ -489,7 +489,7 @@ where
|
|||
}
|
||||
|
||||
let upvars_ty = ty::CoroutineClosureSignature::tupled_upvars_by_closure_kind(
|
||||
ecx.interner(),
|
||||
ecx.cx(),
|
||||
goal_kind,
|
||||
tupled_inputs_ty.expect_ty(),
|
||||
tupled_upvars_ty.expect_ty(),
|
||||
|
|
@ -504,17 +504,17 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_tuple_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
panic!("`Tuple` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_pointee_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
let metadata_def_id = tcx.require_lang_item(TraitSolverLangItem::Metadata);
|
||||
assert_eq!(metadata_def_id, goal.predicate.def_id());
|
||||
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
|
||||
|
|
@ -592,7 +592,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_future_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
|
|
@ -601,7 +601,7 @@ where
|
|||
};
|
||||
|
||||
// Coroutines are not futures unless they come from `async` desugaring
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
if !tcx.coroutine_is_async(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
|
@ -613,11 +613,7 @@ where
|
|||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||
goal,
|
||||
ty::ProjectionPredicate {
|
||||
projection_term: ty::AliasTerm::new(
|
||||
ecx.interner(),
|
||||
goal.predicate.def_id(),
|
||||
[self_ty],
|
||||
),
|
||||
projection_term: ty::AliasTerm::new(ecx.cx(), goal.predicate.def_id(), [self_ty]),
|
||||
term,
|
||||
}
|
||||
.upcast(tcx),
|
||||
|
|
@ -628,7 +624,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
|
|
@ -637,7 +633,7 @@ where
|
|||
};
|
||||
|
||||
// Coroutines are not Iterators unless they come from `gen` desugaring
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
if !tcx.coroutine_is_gen(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
|
@ -649,11 +645,7 @@ where
|
|||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||
goal,
|
||||
ty::ProjectionPredicate {
|
||||
projection_term: ty::AliasTerm::new(
|
||||
ecx.interner(),
|
||||
goal.predicate.def_id(),
|
||||
[self_ty],
|
||||
),
|
||||
projection_term: ty::AliasTerm::new(ecx.cx(), goal.predicate.def_id(), [self_ty]),
|
||||
term,
|
||||
}
|
||||
.upcast(tcx),
|
||||
|
|
@ -664,14 +656,14 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_fused_iterator_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
panic!("`FusedIterator` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_async_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
|
|
@ -680,7 +672,7 @@ where
|
|||
};
|
||||
|
||||
// Coroutines are not AsyncIterators unless they come from `gen` desugaring
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
if !tcx.coroutine_is_async_gen(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
|
@ -707,7 +699,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_coroutine_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
|
|
@ -716,7 +708,7 @@ where
|
|||
};
|
||||
|
||||
// `async`-desugared coroutines do not implement the coroutine trait
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
if !tcx.is_general_coroutine(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
|
@ -739,7 +731,7 @@ where
|
|||
goal,
|
||||
ty::ProjectionPredicate {
|
||||
projection_term: ty::AliasTerm::new(
|
||||
ecx.interner(),
|
||||
ecx.cx(),
|
||||
goal.predicate.def_id(),
|
||||
[self_ty, coroutine.resume_ty()],
|
||||
),
|
||||
|
|
@ -753,14 +745,14 @@ where
|
|||
}
|
||||
|
||||
fn consider_structural_builtin_unsize_candidates(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Vec<Candidate<I>> {
|
||||
panic!("`Unsize` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_discriminant_kind_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
|
|
@ -788,7 +780,7 @@ where
|
|||
| ty::Slice(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Tuple(_)
|
||||
| ty::Error(_) => self_ty.discriminant_ty(ecx.interner()),
|
||||
| ty::Error(_) => self_ty.discriminant_ty(ecx.cx()),
|
||||
|
||||
// We do not call `Ty::discriminant_ty` on alias, param, or placeholder
|
||||
// types, which return `<self_ty as DiscriminantKind>::Discriminant`
|
||||
|
|
@ -812,7 +804,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_async_destruct_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
|
|
@ -835,7 +827,7 @@ where
|
|||
| ty::Str
|
||||
| ty::Slice(_)
|
||||
| ty::Tuple(_)
|
||||
| ty::Error(_) => self_ty.async_destructor_ty(ecx.interner()),
|
||||
| ty::Error(_) => self_ty.async_destructor_ty(ecx.cx()),
|
||||
|
||||
// We do not call `Ty::async_destructor_ty` on alias, param, or placeholder
|
||||
// types, which return `<self_ty as AsyncDestruct>::AsyncDestructor`
|
||||
|
|
@ -865,23 +857,23 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_destruct_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
panic!("`Destruct` does not have an associated type: {:?}", goal);
|
||||
}
|
||||
|
||||
fn consider_builtin_transmute_candidate(
|
||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
_ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
fn translate_args(
|
||||
|
|
@ -892,7 +884,7 @@ where
|
|||
impl_trait_ref: rustc_type_ir::TraitRef<I>,
|
||||
target_container_def_id: I::DefId,
|
||||
) -> Result<I::GenericArgs, NoSolution> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
Ok(if target_container_def_id == impl_trait_ref.def_id {
|
||||
// Default value from the trait definition. No need to rebase.
|
||||
goal.predicate.alias.args
|
||||
|
|
|
|||
|
|
@ -6,19 +6,19 @@ use rustc_index::bit_set::GrowableBitSet;
|
|||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::{self as ty, Interner};
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::{Certainty, EvalCtxt, Goal, NoSolution, QueryResult, Reveal, SolverMode};
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
pub(super) fn normalize_opaque_type(
|
||||
&mut self,
|
||||
goal: Goal<I, ty::NormalizesTo<I>>,
|
||||
) -> QueryResult<I> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let opaque_ty = goal.predicate.alias;
|
||||
let expected = goal.predicate.term.as_type().expect("no such thing as an opaque const");
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ where
|
|||
return Err(NoSolution);
|
||||
}
|
||||
// FIXME: This may have issues when the args contain aliases...
|
||||
match uses_unique_placeholders_ignoring_regions(self.interner(), opaque_ty.args) {
|
||||
match uses_unique_placeholders_ignoring_regions(self.cx(), opaque_ty.args) {
|
||||
Err(NotUniqueParam::NotParam(param)) if param.is_non_region_infer() => {
|
||||
return self.evaluate_added_goals_and_make_canonical_response(
|
||||
Certainty::AMBIGUOUS,
|
||||
|
|
|
|||
|
|
@ -6,19 +6,19 @@
|
|||
|
||||
use rustc_type_ir::{self as ty, Interner};
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::{Certainty, EvalCtxt, Goal, GoalSource, QueryResult};
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
pub(super) fn normalize_weak_type(
|
||||
&mut self,
|
||||
goal: Goal<I, ty::NormalizesTo<I>>,
|
||||
) -> QueryResult<I> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let weak_ty = goal.predicate.alias;
|
||||
|
||||
// Check where clauses
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use rustc_type_ir::{self as ty, Interner, ProjectionPredicate};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::{Certainty, EvalCtxt, Goal, GoalSource, QueryResult};
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
|
|
@ -14,7 +14,7 @@ where
|
|||
&mut self,
|
||||
goal: Goal<I, ProjectionPredicate<I>>,
|
||||
) -> QueryResult<I> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let projection_term = goal.predicate.projection_term.to_term(tcx);
|
||||
let goal = goal.with(
|
||||
tcx,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use rustc_type_ir::inherent::*;
|
|||
use rustc_type_ir::Interner;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::inspect::{self, ProofTreeBuilder};
|
||||
use crate::solve::{
|
||||
CacheData, CanonicalInput, Certainty, QueryResult, SolverMode, FIXPOINT_STEP_LIMIT,
|
||||
|
|
@ -255,12 +255,12 @@ impl<I: Interner> SearchGraph<I> {
|
|||
///
|
||||
/// Given some goal which is proven via the `prove_goal` closure, this
|
||||
/// handles caching, overflow, and coinductive cycles.
|
||||
pub(super) fn with_new_goal<Infcx: SolverDelegate<Interner = I>>(
|
||||
pub(super) fn with_new_goal<D: SolverDelegate<Interner = I>>(
|
||||
&mut self,
|
||||
tcx: I,
|
||||
input: CanonicalInput<I>,
|
||||
inspect: &mut ProofTreeBuilder<Infcx>,
|
||||
mut prove_goal: impl FnMut(&mut Self, &mut ProofTreeBuilder<Infcx>) -> QueryResult<I>,
|
||||
inspect: &mut ProofTreeBuilder<D>,
|
||||
mut prove_goal: impl FnMut(&mut Self, &mut ProofTreeBuilder<D>) -> QueryResult<I>,
|
||||
) -> QueryResult<I> {
|
||||
self.check_invariants();
|
||||
// Check for overflow.
|
||||
|
|
@ -416,12 +416,12 @@ impl<I: Interner> SearchGraph<I> {
|
|||
/// Try to fetch a previously computed result from the global cache,
|
||||
/// making sure to only do so if it would match the result of reevaluating
|
||||
/// this goal.
|
||||
fn lookup_global_cache<Infcx: SolverDelegate<Interner = I>>(
|
||||
fn lookup_global_cache<D: SolverDelegate<Interner = I>>(
|
||||
&mut self,
|
||||
tcx: I,
|
||||
input: CanonicalInput<I>,
|
||||
available_depth: SolverLimit,
|
||||
inspect: &mut ProofTreeBuilder<Infcx>,
|
||||
inspect: &mut ProofTreeBuilder<D>,
|
||||
) -> Option<QueryResult<I>> {
|
||||
let CacheData { result, proof_tree, additional_depth, encountered_overflow } = self
|
||||
.global_cache(tcx)
|
||||
|
|
@ -465,16 +465,16 @@ impl<I: Interner> SearchGraph<I> {
|
|||
/// of this we continuously recompute the cycle until the result
|
||||
/// of the previous iteration is equal to the final result, at which
|
||||
/// point we are done.
|
||||
fn fixpoint_step_in_task<Infcx, F>(
|
||||
fn fixpoint_step_in_task<D, F>(
|
||||
&mut self,
|
||||
tcx: I,
|
||||
input: CanonicalInput<I>,
|
||||
inspect: &mut ProofTreeBuilder<Infcx>,
|
||||
inspect: &mut ProofTreeBuilder<D>,
|
||||
prove_goal: &mut F,
|
||||
) -> StepResult<I>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
F: FnMut(&mut Self, &mut ProofTreeBuilder<Infcx>) -> QueryResult<I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
F: FnMut(&mut Self, &mut ProofTreeBuilder<D>) -> QueryResult<I>,
|
||||
{
|
||||
let result = prove_goal(self, inspect);
|
||||
let stack_entry = self.pop_stack();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc_type_ir::visit::TypeVisitableExt as _;
|
|||
use rustc_type_ir::{self as ty, Interner, TraitPredicate, Upcast as _};
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
use crate::infcx::SolverDelegate;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::assembly::structural_traits::{self, AsyncCallableRelevantTypes};
|
||||
use crate::solve::assembly::{self, Candidate};
|
||||
use crate::solve::inspect::ProbeKind;
|
||||
|
|
@ -17,9 +17,9 @@ use crate::solve::{
|
|||
NoSolution, QueryResult, Reveal, SolverMode,
|
||||
};
|
||||
|
||||
impl<Infcx, I> assembly::GoalKind<Infcx> for TraitPredicate<I>
|
||||
impl<D, I> assembly::GoalKind<D> for TraitPredicate<I>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
fn self_ty(self) -> I::Ty {
|
||||
|
|
@ -39,11 +39,11 @@ where
|
|||
}
|
||||
|
||||
fn consider_impl_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, TraitPredicate<I>>,
|
||||
impl_def_id: I::DefId,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
|
||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
|
||||
if !tcx
|
||||
|
|
@ -91,7 +91,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_error_guaranteed_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
_guar: I::ErrorGuaranteed,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
// FIXME: don't need to enter a probe here.
|
||||
|
|
@ -100,11 +100,11 @@ where
|
|||
}
|
||||
|
||||
fn probe_and_match_goal_against_assumption(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
source: CandidateSource<I>,
|
||||
goal: Goal<I, Self>,
|
||||
assumption: I::Clause,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> QueryResult<I>,
|
||||
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if let Some(trait_clause) = assumption.as_trait_clause() {
|
||||
if trait_clause.def_id() == goal.predicate.def_id()
|
||||
|
|
@ -128,7 +128,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_auto_trait_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -174,14 +174,14 @@ where
|
|||
}
|
||||
|
||||
fn consider_trait_alias_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
|
||||
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
|
||||
let nested_obligations = tcx
|
||||
|
|
@ -195,7 +195,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_sized_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -210,7 +210,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_copy_clone_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -225,14 +225,14 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_pointer_like_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
// But if there are inference variables, we have to wait until it's resolved.
|
||||
if (goal.param_env, goal.predicate.self_ty()).has_non_region_infer() {
|
||||
return ecx.forced_ambiguity(MaybeCause::Ambiguity);
|
||||
|
|
@ -247,7 +247,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_fn_ptr_trait_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let self_ty = goal.predicate.self_ty();
|
||||
|
|
@ -278,7 +278,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_fn_trait_candidates(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
|
|
@ -286,7 +286,7 @@ where
|
|||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
let tupled_inputs_and_output =
|
||||
match structural_traits::extract_tupled_inputs_and_output_from_callable(
|
||||
tcx,
|
||||
|
|
@ -319,7 +319,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_async_fn_trait_candidates(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
|
|
@ -327,7 +327,7 @@ where
|
|||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
let (tupled_inputs_and_output_and_coroutine, nested_preds) =
|
||||
structural_traits::extract_tupled_inputs_and_output_from_async_callable(
|
||||
tcx,
|
||||
|
|
@ -370,7 +370,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_async_fn_kind_helper_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let [closure_fn_kind_ty, goal_kind_ty] = **goal.predicate.trait_ref.args else {
|
||||
|
|
@ -397,7 +397,7 @@ where
|
|||
/// impl Tuple for (T1, .., Tn) {}
|
||||
/// ```
|
||||
fn consider_builtin_tuple_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -413,7 +413,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_pointee_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -425,7 +425,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_future_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -437,7 +437,7 @@ where
|
|||
};
|
||||
|
||||
// Coroutines are not futures unless they come from `async` desugaring
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
if !tcx.coroutine_is_async(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
|
@ -451,7 +451,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -463,7 +463,7 @@ where
|
|||
};
|
||||
|
||||
// Coroutines are not iterators unless they come from `gen` desugaring
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
if !tcx.coroutine_is_gen(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
|
@ -477,7 +477,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_fused_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -489,7 +489,7 @@ where
|
|||
};
|
||||
|
||||
// Coroutines are not iterators unless they come from `gen` desugaring
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
if !tcx.coroutine_is_gen(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
|
@ -501,7 +501,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_async_iterator_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -513,7 +513,7 @@ where
|
|||
};
|
||||
|
||||
// Coroutines are not iterators unless they come from `gen` desugaring
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
if !tcx.coroutine_is_async_gen(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
|
@ -527,7 +527,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_coroutine_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -540,7 +540,7 @@ where
|
|||
};
|
||||
|
||||
// `async`-desugared coroutines do not implement the coroutine trait
|
||||
let tcx = ecx.interner();
|
||||
let tcx = ecx.cx();
|
||||
if !tcx.is_general_coroutine(def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
|
@ -559,7 +559,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_discriminant_kind_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -572,7 +572,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_async_destruct_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -585,7 +585,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_destruct_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -601,7 +601,7 @@ where
|
|||
}
|
||||
|
||||
fn consider_builtin_transmute_candidate(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -634,7 +634,7 @@ where
|
|||
/// impl<'a, T: Trait + 'a> Unsize<dyn Trait + 'a> for T {}
|
||||
/// ```
|
||||
fn consider_structural_builtin_unsize_candidates(
|
||||
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
) -> Vec<Candidate<I>> {
|
||||
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||
|
|
@ -657,7 +657,7 @@ where
|
|||
return vec![];
|
||||
};
|
||||
|
||||
let goal = goal.with(ecx.interner(), (a_ty, b_ty));
|
||||
let goal = goal.with(ecx.cx(), (a_ty, b_ty));
|
||||
match (a_ty.kind(), b_ty.kind()) {
|
||||
(ty::Infer(ty::TyVar(..)), ..) => panic!("unexpected infer {a_ty:?} {b_ty:?}"),
|
||||
|
||||
|
|
@ -705,9 +705,9 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Infcx, I> EvalCtxt<'_, Infcx>
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
where
|
||||
Infcx: SolverDelegate<Interner = I>,
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
/// Trait upcasting allows for coercions between trait objects:
|
||||
|
|
@ -727,7 +727,7 @@ where
|
|||
b_data: I::BoundExistentialPredicates,
|
||||
b_region: I::Region,
|
||||
) -> Vec<Candidate<I>> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let Goal { predicate: (a_ty, _b_ty), .. } = goal;
|
||||
|
||||
let mut responses = vec![];
|
||||
|
|
@ -745,8 +745,7 @@ where
|
|||
));
|
||||
} else if let Some(a_principal) = a_data.principal() {
|
||||
for new_a_principal in
|
||||
Infcx::elaborate_supertraits(self.interner(), a_principal.with_self_ty(tcx, a_ty))
|
||||
.skip(1)
|
||||
D::elaborate_supertraits(self.cx(), a_principal.with_self_ty(tcx, a_ty)).skip(1)
|
||||
{
|
||||
responses.extend(self.consider_builtin_upcast_to_principal(
|
||||
goal,
|
||||
|
|
@ -771,7 +770,7 @@ where
|
|||
b_data: I::BoundExistentialPredicates,
|
||||
b_region: I::Region,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let Goal { predicate: (a_ty, _), .. } = goal;
|
||||
|
||||
// Can only unsize to an object-safe trait.
|
||||
|
|
@ -825,10 +824,10 @@ where
|
|||
.auto_traits()
|
||||
.into_iter()
|
||||
.chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
|
||||
self.interner()
|
||||
self.cx()
|
||||
.supertrait_def_ids(principal_def_id)
|
||||
.into_iter()
|
||||
.filter(|def_id| self.interner().trait_is_auto(*def_id))
|
||||
.filter(|def_id| self.cx().trait_is_auto(*def_id))
|
||||
}))
|
||||
.collect();
|
||||
|
||||
|
|
@ -837,7 +836,7 @@ where
|
|||
// having any inference side-effects. We process obligations because
|
||||
// unification may initially succeed due to deferred projection equality.
|
||||
let projection_may_match =
|
||||
|ecx: &mut EvalCtxt<'_, Infcx>,
|
||||
|ecx: &mut EvalCtxt<'_, D>,
|
||||
source_projection: ty::Binder<I, ty::ExistentialProjection<I>>,
|
||||
target_projection: ty::Binder<I, ty::ExistentialProjection<I>>| {
|
||||
source_projection.item_def_id() == target_projection.item_def_id()
|
||||
|
|
@ -896,7 +895,7 @@ where
|
|||
// Also require that a_ty's lifetime outlives b_ty's lifetime.
|
||||
ecx.add_goal(
|
||||
GoalSource::ImplWhereBound,
|
||||
Goal::new(ecx.interner(), param_env, ty::OutlivesPredicate(a_region, b_region)),
|
||||
Goal::new(ecx.cx(), param_env, ty::OutlivesPredicate(a_region, b_region)),
|
||||
);
|
||||
|
||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
|
|
@ -942,7 +941,7 @@ where
|
|||
a_args: I::GenericArgs,
|
||||
b_args: I::GenericArgs,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let Goal { predicate: (_a_ty, b_ty), .. } = goal;
|
||||
|
||||
let unsizing_params = tcx.unsizing_params_for_adt(def.def_id());
|
||||
|
|
@ -1002,7 +1001,7 @@ where
|
|||
a_tys: I::Tys,
|
||||
b_tys: I::Tys,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
let tcx = self.interner();
|
||||
let tcx = self.cx();
|
||||
let Goal { predicate: (_a_ty, b_ty), .. } = goal;
|
||||
|
||||
let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap();
|
||||
|
|
@ -1062,11 +1061,9 @@ where
|
|||
// takes precedence over the structural auto trait candidate being
|
||||
// assembled.
|
||||
ty::Coroutine(def_id, _)
|
||||
if self
|
||||
.interner()
|
||||
.is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::Unpin) =>
|
||||
if self.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::Unpin) =>
|
||||
{
|
||||
match self.interner().coroutine_movability(def_id) {
|
||||
match self.cx().coroutine_movability(def_id) {
|
||||
Movability::Static => Some(Err(NoSolution)),
|
||||
Movability::Movable => Some(
|
||||
self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
|
||||
|
|
@ -1111,7 +1108,7 @@ where
|
|||
| ty::Tuple(_)
|
||||
| ty::Adt(_, _) => {
|
||||
let mut disqualifying_impl = None;
|
||||
self.interner().for_each_relevant_impl(
|
||||
self.cx().for_each_relevant_impl(
|
||||
goal.predicate.def_id(),
|
||||
goal.predicate.self_ty(),
|
||||
|impl_def_id| {
|
||||
|
|
@ -1140,7 +1137,7 @@ where
|
|||
source: CandidateSource<I>,
|
||||
goal: Goal<I, TraitPredicate<I>>,
|
||||
constituent_tys: impl Fn(
|
||||
&EvalCtxt<'_, Infcx>,
|
||||
&EvalCtxt<'_, D>,
|
||||
I::Ty,
|
||||
) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
|
|
@ -1151,10 +1148,7 @@ where
|
|||
.into_iter()
|
||||
.map(|ty| {
|
||||
ecx.enter_forall(ty, |ty| {
|
||||
goal.with(
|
||||
ecx.interner(),
|
||||
goal.predicate.with_self_ty(ecx.interner(), ty),
|
||||
)
|
||||
goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty))
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ passes_abi_of =
|
|||
fn_abi_of({$fn_name}) = {$fn_abi}
|
||||
|
||||
passes_allow_incoherent_impl =
|
||||
`rustc_allow_incoherent_impl` attribute should be applied to impl items.
|
||||
`rustc_allow_incoherent_impl` attribute should be applied to impl items
|
||||
.label = the only currently supported targets are inherent methods
|
||||
|
||||
passes_allow_internal_unstable =
|
||||
|
|
@ -253,8 +253,8 @@ passes_doc_test_unknown_spotlight =
|
|||
.no_op_note = `doc(spotlight)` is now a no-op
|
||||
|
||||
passes_duplicate_diagnostic_item_in_crate =
|
||||
duplicate diagnostic item in crate `{$crate_name}`: `{$name}`.
|
||||
.note = the diagnostic item is first defined in crate `{$orig_crate_name}`.
|
||||
duplicate diagnostic item in crate `{$crate_name}`: `{$name}`
|
||||
.note = the diagnostic item is first defined in crate `{$orig_crate_name}`
|
||||
|
||||
passes_duplicate_feature_err =
|
||||
the feature `{$feature}` has already been declared
|
||||
|
|
@ -263,27 +263,27 @@ passes_duplicate_lang_item =
|
|||
found duplicate lang item `{$lang_item_name}`
|
||||
.first_defined_span = the lang item is first defined here
|
||||
.first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on)
|
||||
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`.
|
||||
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`
|
||||
.first_definition_local = first definition in the local crate (`{$orig_crate_name}`)
|
||||
.second_definition_local = second definition in the local crate (`{$crate_name}`)
|
||||
.first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path}
|
||||
.second_definition_path = second definition in `{$crate_name}` loaded from {$path}
|
||||
|
||||
passes_duplicate_lang_item_crate =
|
||||
duplicate lang item in crate `{$crate_name}`: `{$lang_item_name}`.
|
||||
duplicate lang item in crate `{$crate_name}`: `{$lang_item_name}`
|
||||
.first_defined_span = the lang item is first defined here
|
||||
.first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on)
|
||||
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`.
|
||||
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`
|
||||
.first_definition_local = first definition in the local crate (`{$orig_crate_name}`)
|
||||
.second_definition_local = second definition in the local crate (`{$crate_name}`)
|
||||
.first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path}
|
||||
.second_definition_path = second definition in `{$crate_name}` loaded from {$path}
|
||||
|
||||
passes_duplicate_lang_item_crate_depends =
|
||||
duplicate lang item in crate `{$crate_name}` (which `{$dependency_of}` depends on): `{$lang_item_name}`.
|
||||
duplicate lang item in crate `{$crate_name}` (which `{$dependency_of}` depends on): `{$lang_item_name}`
|
||||
.first_defined_span = the lang item is first defined here
|
||||
.first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on)
|
||||
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`.
|
||||
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`
|
||||
.first_definition_local = first definition in the local crate (`{$orig_crate_name}`)
|
||||
.second_definition_local = second definition in the local crate (`{$crate_name}`)
|
||||
.first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path}
|
||||
|
|
@ -315,7 +315,7 @@ passes_ffi_pure_invalid_target =
|
|||
`#[ffi_pure]` may only be used on foreign functions
|
||||
|
||||
passes_has_incoherent_inherent_impl =
|
||||
`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
|
||||
`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits
|
||||
.label = only adts, extern types and traits are supported
|
||||
|
||||
passes_ignored_attr =
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ resolve_label_with_similar_name_reachable =
|
|||
|
||||
resolve_lending_iterator_report_error =
|
||||
associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
|
||||
.note = you can't create an `Iterator` that borrows each `Item` from itself, but you can instead create a new type that borrows your existing type and implement `Iterator` for that new type.
|
||||
.note = you can't create an `Iterator` that borrows each `Item` from itself, but you can instead create a new type that borrows your existing type and implement `Iterator` for that new type
|
||||
|
||||
resolve_lifetime_param_in_enum_discriminant =
|
||||
lifetime parameters may not be used in enum discriminant values
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for TransformTy<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,9 +82,9 @@ session_octal_float_literal_not_supported = octal float literal is not supported
|
|||
|
||||
session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg}
|
||||
|
||||
session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist.
|
||||
session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist
|
||||
|
||||
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist.
|
||||
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist
|
||||
|
||||
session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi`
|
||||
|
||||
|
|
|
|||
|
|
@ -533,6 +533,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
|||
Ok(tables.fn_abi_of_instance(instance, List::empty())?.stable(&mut *tables))
|
||||
}
|
||||
|
||||
fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
let sig = fn_ptr.internal(&mut *tables, tcx);
|
||||
Ok(tables.fn_abi_of_fn_ptr(sig, List::empty())?.stable(&mut *tables))
|
||||
}
|
||||
|
||||
fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = tables.instances[def].def_id();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
derivative = "2.2.0"
|
||||
indexmap = { version = "2.0.0" }
|
||||
itoa = "1.0"
|
||||
md5 = { package = "md-5", version = "0.10.0" }
|
||||
|
|
|
|||
|
|
@ -43,9 +43,15 @@ use std::hash::Hash;
|
|||
use tracing::{debug, trace};
|
||||
|
||||
/// A `SyntaxContext` represents a chain of pairs `(ExpnId, Transparency)` named "marks".
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct SyntaxContext(u32);
|
||||
|
||||
// To ensure correctness of incremental compilation,
|
||||
// `SyntaxContext` must not implement `Ord` or `PartialOrd`.
|
||||
// See https://github.com/rust-lang/rust/issues/90317.
|
||||
impl !Ord for SyntaxContext {}
|
||||
impl !PartialOrd for SyntaxContext {}
|
||||
|
||||
#[derive(Debug, Encodable, Decodable, Clone)]
|
||||
pub struct SyntaxContextData {
|
||||
outer_expn: ExpnId,
|
||||
|
|
|
|||
|
|
@ -467,46 +467,23 @@ impl FileName {
|
|||
/// `SpanData` is public because `Span` uses a thread-local interner and can't be
|
||||
/// sent to other threads, but some pieces of performance infra run in a separate thread.
|
||||
/// Using `Span` is generally preferred.
|
||||
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Hash, PartialEq, Eq, derivative::Derivative)]
|
||||
#[derivative(PartialOrd, Ord)]
|
||||
pub struct SpanData {
|
||||
pub lo: BytePos,
|
||||
pub hi: BytePos,
|
||||
/// Information about where the macro came from, if this piece of
|
||||
/// code was created by a macro expansion.
|
||||
#[derivative(PartialOrd = "ignore", Ord = "ignore")]
|
||||
// `SyntaxContext` does not implement `Ord`.
|
||||
// The other fields are enough to determine in-file order.
|
||||
pub ctxt: SyntaxContext,
|
||||
#[derivative(PartialOrd = "ignore", Ord = "ignore")]
|
||||
// `LocalDefId` does not implement `Ord`.
|
||||
// The other fields are enough to determine in-file order.
|
||||
pub parent: Option<LocalDefId>,
|
||||
}
|
||||
|
||||
// Order spans by position in the file.
|
||||
impl Ord for SpanData {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
let SpanData {
|
||||
lo: s_lo,
|
||||
hi: s_hi,
|
||||
ctxt: s_ctxt,
|
||||
// `LocalDefId` does not implement `Ord`.
|
||||
// The other fields are enough to determine in-file order.
|
||||
parent: _,
|
||||
} = self;
|
||||
let SpanData {
|
||||
lo: o_lo,
|
||||
hi: o_hi,
|
||||
ctxt: o_ctxt,
|
||||
// `LocalDefId` does not implement `Ord`.
|
||||
// The other fields are enough to determine in-file order.
|
||||
parent: _,
|
||||
} = other;
|
||||
|
||||
(s_lo, s_hi, s_ctxt).cmp(&(o_lo, o_hi, o_ctxt))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for SpanData {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl SpanData {
|
||||
#[inline]
|
||||
pub fn span(&self) -> Span {
|
||||
|
|
|
|||
|
|
@ -1593,6 +1593,8 @@ symbols! {
|
|||
rustc_do_not_const_check,
|
||||
rustc_doc_primitive,
|
||||
rustc_dummy,
|
||||
rustc_dump_item_bounds,
|
||||
rustc_dump_predicates,
|
||||
rustc_dump_user_args,
|
||||
rustc_dump_vtable,
|
||||
rustc_effective_visibility,
|
||||
|
|
@ -2054,6 +2056,8 @@ symbols! {
|
|||
yes,
|
||||
yield_expr,
|
||||
ymm_reg,
|
||||
zfh,
|
||||
zfhmin,
|
||||
zmm_reg,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,16 +47,18 @@ impl ArmInlineAsmRegClass {
|
|||
_arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match self {
|
||||
Self::reg => types! { _: I8, I16, I32, F32; },
|
||||
Self::sreg | Self::sreg_low16 => types! { vfp2: I32, F32; },
|
||||
Self::reg => types! { _: I8, I16, I32, F16, F32; },
|
||||
Self::sreg | Self::sreg_low16 => types! { vfp2: I32, F16, F32; },
|
||||
Self::dreg_low16 | Self::dreg_low8 => types! {
|
||||
vfp2: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
|
||||
vfp2: I64, F64;
|
||||
neon: VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2);
|
||||
},
|
||||
Self::dreg => types! {
|
||||
d32: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
|
||||
d32: I64, F64;
|
||||
neon: VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2);
|
||||
},
|
||||
Self::qreg | Self::qreg_low8 | Self::qreg_low4 => types! {
|
||||
neon: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4);
|
||||
neon: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,12 +40,13 @@ impl RiscVInlineAsmRegClass {
|
|||
match self {
|
||||
Self::reg => {
|
||||
if arch == InlineAsmArch::RiscV64 {
|
||||
types! { _: I8, I16, I32, I64, F32, F64; }
|
||||
types! { _: I8, I16, I32, I64, F16, F32, F64; }
|
||||
} else {
|
||||
types! { _: I8, I16, I32, F32; }
|
||||
types! { _: I8, I16, I32, F16, F32; }
|
||||
}
|
||||
}
|
||||
Self::freg => types! { f: F32; d: F64; },
|
||||
// FIXME(f16_f128): Add `q: F128;` once LLVM support the `Q` extension.
|
||||
Self::freg => types! { f: F16, F32; d: F64; },
|
||||
Self::vreg => &[],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
pub use rustc_next_trait_solver::solve::*;
|
||||
|
||||
mod delegate;
|
||||
mod fulfill;
|
||||
mod infcx;
|
||||
pub mod inspect;
|
||||
mod normalize;
|
||||
mod select;
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@ impl<'tcx> Deref for SolverDelegate<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tcx> {
|
||||
impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<'tcx> {
|
||||
type Interner = TyCtxt<'tcx>;
|
||||
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.0.tcx
|
||||
}
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ use rustc_span::symbol::sym;
|
|||
|
||||
use crate::traits::{FulfillmentError, FulfillmentErrorCode, ScrubbedTraitError};
|
||||
|
||||
use super::infcx::SolverDelegate;
|
||||
use super::delegate::SolverDelegate;
|
||||
use super::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor};
|
||||
use super::Certainty;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use rustc_next_trait_solver::solve::inspect::{self, instantiate_canonical_state}
|
|||
use rustc_next_trait_solver::solve::{GenerateProofTree, MaybeCause, SolverDelegateEvalExt as _};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use crate::solve::infcx::SolverDelegate;
|
||||
use crate::solve::delegate::SolverDelegate;
|
||||
use crate::traits::ObligationCtxt;
|
||||
|
||||
pub struct InspectConfig {
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ where
|
|||
{
|
||||
type Error = Vec<E>;
|
||||
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.at.infcx.tcx
|
||||
}
|
||||
|
||||
|
|
@ -244,7 +244,7 @@ struct DeeplyNormalizeForDiagnosticsFolder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.at.infcx.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4936,7 +4936,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceImplTraitFolder<'tcx> {
|
|||
t.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2840,7 +2840,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ParamToVarFolder<'a, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
|||
struct ConstNormalizer<'tcx>(TyCtxt<'tcx>);
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ConstNormalizer<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.0
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.selcx.tcx()
|
||||
}
|
||||
|
||||
|
|
@ -217,7 +217,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
|||
Reveal::UserFacing => ty.super_fold_with(self),
|
||||
|
||||
Reveal::All => {
|
||||
let recursion_limit = self.interner().recursion_limit();
|
||||
let recursion_limit = self.cx().recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.depth) {
|
||||
self.selcx.infcx.err_ctxt().report_overflow_error(
|
||||
OverflowCause::DeeplyNormalize(data.into()),
|
||||
|
|
@ -228,8 +228,8 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
|||
}
|
||||
|
||||
let args = data.args.fold_with(self);
|
||||
let generic_ty = self.interner().type_of(data.def_id);
|
||||
let concrete_ty = generic_ty.instantiate(self.interner(), args);
|
||||
let generic_ty = self.cx().type_of(data.def_id);
|
||||
let concrete_ty = generic_ty.instantiate(self.cx(), args);
|
||||
self.depth += 1;
|
||||
let folded_ty = self.fold_ty(concrete_ty);
|
||||
self.depth -= 1;
|
||||
|
|
@ -313,7 +313,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
|||
normalized_ty
|
||||
}
|
||||
ty::Weak => {
|
||||
let recursion_limit = self.interner().recursion_limit();
|
||||
let recursion_limit = self.cx().recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.depth) {
|
||||
self.selcx.infcx.err_ctxt().report_overflow_error(
|
||||
OverflowCause::DeeplyNormalize(data.into()),
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue