Auto merge of #103991 - matthiaskrgr:rollup-tj53nte, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #103868 (Use `TraitEngine` (by itself) less) - #103878 (Fix artifact version/channel detection for stable) - #103946 (Cleanup bind_pattern args) - #103956 (Make mir opt unused file check blessable) - #103977 (LLVM 16: Switch to using MemoryEffects) - #103980 (rustdoc: simplify search results CSS and DOM) - #103984 (Refactor tcx mk_const parameters.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
aebf7c4a0e
43 changed files with 284 additions and 295 deletions
|
@ -23,7 +23,6 @@ use rustc_span::hygiene::DesugaringKind;
|
|||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{BytePos, Span, Symbol};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::TraitEngineExt as _;
|
||||
|
||||
use crate::borrow_set::TwoPhaseActivation;
|
||||
use crate::borrowck_errors;
|
||||
|
@ -613,24 +612,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
else { return; };
|
||||
// Try to find predicates on *generic params* that would allow copying `ty`
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let mut fulfill_cx = <dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx);
|
||||
|
||||
let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
self.mir_hir_id(),
|
||||
rustc_infer::traits::ObligationCauseCode::MiscObligation,
|
||||
);
|
||||
fulfill_cx.register_bound(
|
||||
let errors = rustc_trait_selection::traits::fully_solve_bound(
|
||||
&infcx,
|
||||
cause,
|
||||
self.param_env,
|
||||
// Erase any region vids from the type, which may not be resolved
|
||||
infcx.tcx.erase_regions(ty),
|
||||
copy_did,
|
||||
cause,
|
||||
);
|
||||
// Select all, including ambiguous predicates
|
||||
let errors = fulfill_cx.select_all_or_error(&infcx);
|
||||
|
||||
// Only emit suggestion if all required predicates are on generic
|
||||
let predicates: Result<Vec<_>, _> = errors
|
||||
|
|
|
@ -4,7 +4,7 @@ use rustc_hir::def_id::LocalDefId;
|
|||
use rustc_hir::OpaqueTyOrigin;
|
||||
use rustc_infer::infer::TyCtxtInferExt as _;
|
||||
use rustc_infer::infer::{DefiningAnchor, InferCtxt};
|
||||
use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine};
|
||||
use rustc_infer::traits::{Obligation, ObligationCause};
|
||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{
|
||||
|
@ -12,7 +12,7 @@ use rustc_middle::ty::{
|
|||
};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::TraitEngineExt as _;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
|
||||
use super::RegionInferenceContext;
|
||||
|
||||
|
@ -252,48 +252,45 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
// type-alias-impl-trait/issue-67844-nested-opaque.rs
|
||||
let infcx =
|
||||
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build();
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
// Require the hidden type to be well-formed with only the generics of the opaque type.
|
||||
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
|
||||
// hidden type is well formed even without those bounds.
|
||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
|
||||
.to_predicate(infcx.tcx);
|
||||
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
|
||||
|
||||
let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id());
|
||||
|
||||
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
|
||||
// the bounds that the function supplies.
|
||||
let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs);
|
||||
match infcx
|
||||
.at(&ObligationCause::misc(instantiated_ty.span, body_id), param_env)
|
||||
.eq(opaque_ty, definition_ty)
|
||||
{
|
||||
Ok(infer_ok) => {
|
||||
for obligation in infer_ok.obligations {
|
||||
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
infcx
|
||||
.err_ctxt()
|
||||
.report_mismatched_types(
|
||||
&ObligationCause::misc(instantiated_ty.span, body_id),
|
||||
opaque_ty,
|
||||
definition_ty,
|
||||
err,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
if let Err(err) = ocx.eq(
|
||||
&ObligationCause::misc(instantiated_ty.span, body_id),
|
||||
param_env,
|
||||
opaque_ty,
|
||||
definition_ty,
|
||||
) {
|
||||
infcx
|
||||
.err_ctxt()
|
||||
.report_mismatched_types(
|
||||
&ObligationCause::misc(instantiated_ty.span, body_id),
|
||||
opaque_ty,
|
||||
definition_ty,
|
||||
err,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
||||
fulfillment_cx.register_predicate_obligation(
|
||||
&infcx,
|
||||
Obligation::misc(instantiated_ty.span, body_id, param_env, predicate),
|
||||
);
|
||||
ocx.register_obligation(Obligation::misc(
|
||||
instantiated_ty.span,
|
||||
body_id,
|
||||
param_env,
|
||||
predicate,
|
||||
));
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// version.
|
||||
let errors = fulfillment_cx.select_all_or_error(&infcx);
|
||||
let errors = ocx.select_all_or_error();
|
||||
|
||||
// This is still required for many(half of the tests in ui/type-alias-impl-trait)
|
||||
// tests to pass
|
||||
|
|
|
@ -285,13 +285,13 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
let mut attrs = SmallVec::<[_; 2]>::new();
|
||||
if options.contains(InlineAsmOptions::PURE) {
|
||||
if options.contains(InlineAsmOptions::NOMEM) {
|
||||
attrs.push(llvm::AttributeKind::ReadNone.create_attr(self.cx.llcx));
|
||||
attrs.push(llvm::MemoryEffects::None.create_attr(self.cx.llcx));
|
||||
} else if options.contains(InlineAsmOptions::READONLY) {
|
||||
attrs.push(llvm::AttributeKind::ReadOnly.create_attr(self.cx.llcx));
|
||||
attrs.push(llvm::MemoryEffects::ReadOnly.create_attr(self.cx.llcx));
|
||||
}
|
||||
attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx));
|
||||
} else if options.contains(InlineAsmOptions::NOMEM) {
|
||||
attrs.push(llvm::AttributeKind::InaccessibleMemOnly.create_attr(self.cx.llcx));
|
||||
attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx));
|
||||
} else {
|
||||
// LLVM doesn't have an attribute to represent ReadOnly + SideEffect
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use smallvec::SmallVec;
|
|||
|
||||
use crate::attributes;
|
||||
use crate::llvm::AttributePlace::Function;
|
||||
use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace};
|
||||
use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects};
|
||||
use crate::llvm_util;
|
||||
pub use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
|
||||
|
||||
|
@ -303,10 +303,10 @@ pub fn from_fn_attrs<'ll, 'tcx>(
|
|||
to_add.push(AttributeKind::ReturnsTwice.create_attr(cx.llcx));
|
||||
}
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_PURE) {
|
||||
to_add.push(AttributeKind::ReadOnly.create_attr(cx.llcx));
|
||||
to_add.push(MemoryEffects::ReadOnly.create_attr(cx.llcx));
|
||||
}
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_CONST) {
|
||||
to_add.push(AttributeKind::ReadNone.create_attr(cx.llcx));
|
||||
to_add.push(MemoryEffects::None.create_attr(cx.llcx));
|
||||
}
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
|
||||
to_add.push(AttributeKind::Naked.create_attr(cx.llcx));
|
||||
|
|
|
@ -183,7 +183,6 @@ pub enum AttributeKind {
|
|||
OptimizeNone = 24,
|
||||
ReturnsTwice = 25,
|
||||
ReadNone = 26,
|
||||
InaccessibleMemOnly = 27,
|
||||
SanitizeHWAddress = 28,
|
||||
WillReturn = 29,
|
||||
StackProtectReq = 30,
|
||||
|
@ -590,6 +589,15 @@ pub enum ChecksumKind {
|
|||
SHA256,
|
||||
}
|
||||
|
||||
/// LLVMRustMemoryEffects
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub enum MemoryEffects {
|
||||
None,
|
||||
ReadOnly,
|
||||
InaccessibleMemOnly,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
type Opaque;
|
||||
}
|
||||
|
@ -1175,6 +1183,7 @@ extern "C" {
|
|||
pub fn LLVMRustCreateUWTableAttr(C: &Context, async_: bool) -> &Attribute;
|
||||
pub fn LLVMRustCreateAllocSizeAttr(C: &Context, size_arg: u32) -> &Attribute;
|
||||
pub fn LLVMRustCreateAllocKindAttr(C: &Context, size_arg: u64) -> &Attribute;
|
||||
pub fn LLVMRustCreateMemoryEffectsAttr(C: &Context, effects: MemoryEffects) -> &Attribute;
|
||||
|
||||
// Operations on functions
|
||||
pub fn LLVMRustGetOrInsertFunction<'a>(
|
||||
|
|
|
@ -185,6 +185,13 @@ impl AttributeKind {
|
|||
}
|
||||
}
|
||||
|
||||
impl MemoryEffects {
|
||||
/// Create an LLVM Attribute with these memory effects.
|
||||
pub fn create_attr(self, llcx: &Context) -> &Attribute {
|
||||
unsafe { LLVMRustCreateMemoryEffectsAttr(llcx, self) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_section(llglobal: &Value, section_name: &str) {
|
||||
let section_name_cstr = CString::new(section_name).expect("unexpected CString error");
|
||||
unsafe {
|
||||
|
|
|
@ -13,11 +13,8 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty,
|
|||
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef, TypeVisitable};
|
||||
use rustc_mir_dataflow::{self, Analysis};
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{
|
||||
self, ObligationCauseCode, SelectionContext, TraitEngine, TraitEngineExt,
|
||||
};
|
||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext};
|
||||
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
|
@ -747,35 +744,26 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
// "non-const" check. This is required for correctness here.
|
||||
{
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
|
||||
let predicates = tcx.predicates_of(callee).instantiate(tcx, substs);
|
||||
let hir_id = tcx
|
||||
.hir()
|
||||
.local_def_id_to_hir_id(self.body.source.def_id().expect_local());
|
||||
let cause = || {
|
||||
ObligationCause::new(
|
||||
terminator.source_info.span,
|
||||
hir_id,
|
||||
ObligationCauseCode::ItemObligation(callee),
|
||||
)
|
||||
};
|
||||
let normalized = infcx.partially_normalize_associated_types_in(
|
||||
cause(),
|
||||
param_env,
|
||||
predicates,
|
||||
let cause = ObligationCause::new(
|
||||
terminator.source_info.span,
|
||||
hir_id,
|
||||
ObligationCauseCode::ItemObligation(callee),
|
||||
);
|
||||
|
||||
for p in normalized.obligations {
|
||||
fulfill_cx.register_predicate_obligation(&infcx, p);
|
||||
}
|
||||
for obligation in traits::predicates_for_generics(
|
||||
|_, _| cause(),
|
||||
let normalized_predicates =
|
||||
ocx.normalize(cause.clone(), param_env, predicates);
|
||||
ocx.register_obligations(traits::predicates_for_generics(
|
||||
|_, _| cause.clone(),
|
||||
self.param_env,
|
||||
normalized.value,
|
||||
) {
|
||||
fulfill_cx.register_predicate_obligation(&infcx, obligation);
|
||||
}
|
||||
let errors = fulfill_cx.select_all_or_error(&infcx);
|
||||
normalized_predicates,
|
||||
));
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
|
||||
}
|
||||
|
|
|
@ -1655,13 +1655,10 @@ pub fn check_type_bounds<'tcx>(
|
|||
GenericParamDefKind::Const { .. } => {
|
||||
let bound_var = ty::BoundVariableKind::Const;
|
||||
bound_vars.push(bound_var);
|
||||
tcx.mk_const(ty::ConstS {
|
||||
ty: tcx.type_of(param.def_id),
|
||||
kind: ty::ConstKind::Bound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||
),
|
||||
})
|
||||
tcx.mk_const(
|
||||
ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_usize(bound_vars.len() - 1)),
|
||||
tcx.type_of(param.def_id),
|
||||
)
|
||||
.into()
|
||||
}
|
||||
});
|
||||
|
|
|
@ -19,7 +19,7 @@ use rustc_span::symbol::{sym, Ident};
|
|||
use rustc_span::Span;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{FulfillmentError, TraitEngine, TraitEngineExt};
|
||||
use rustc_trait_selection::traits::FulfillmentError;
|
||||
use rustc_type_ir::sty::TyKind::*;
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
@ -785,9 +785,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
other_ty_expr,
|
||||
expected,
|
||||
);
|
||||
let mut fulfill = <dyn TraitEngine<'_>>::new(self.tcx);
|
||||
fulfill.register_predicate_obligation(self, obligation);
|
||||
Err(fulfill.select_where_possible(&self.infcx))
|
||||
Err(rustc_trait_selection::traits::fully_solve_obligation(self, obligation))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -773,10 +773,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
self.fold_const(bound_to)
|
||||
} else {
|
||||
let var = self.canonical_var(info, const_var.into());
|
||||
self.tcx().mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Bound(self.binder_index, var),
|
||||
ty: self.fold_ty(const_var.ty()),
|
||||
})
|
||||
self.tcx().mk_const(
|
||||
ty::ConstKind::Bound(self.binder_index, var),
|
||||
self.fold_ty(const_var.ty()),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,12 +147,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, name }, ty) => {
|
||||
let universe_mapped = universe_map(universe);
|
||||
let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, name };
|
||||
self.tcx
|
||||
.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Placeholder(placeholder_mapped),
|
||||
ty,
|
||||
})
|
||||
.into()
|
||||
self.tcx.mk_const(ty::ConstKind::Placeholder(placeholder_mapped), ty).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -741,10 +741,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||
substs,
|
||||
substs,
|
||||
)?;
|
||||
Ok(self.tcx().mk_const(ty::ConstS {
|
||||
ty: c.ty(),
|
||||
kind: ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }),
|
||||
}))
|
||||
Ok(self.tcx().mk_const(
|
||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }),
|
||||
c.ty(),
|
||||
))
|
||||
}
|
||||
_ => relate::super_relate_consts(self, c, c),
|
||||
}
|
||||
|
@ -955,10 +955,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
|
|||
substs,
|
||||
)?;
|
||||
|
||||
Ok(self.tcx().mk_const(ty::ConstS {
|
||||
ty: c.ty(),
|
||||
kind: ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }),
|
||||
}))
|
||||
Ok(self.tcx().mk_const(
|
||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }),
|
||||
c.ty(),
|
||||
))
|
||||
}
|
||||
_ => relate::super_relate_consts(self, c, c),
|
||||
}
|
||||
|
|
|
@ -94,13 +94,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
}))
|
||||
},
|
||||
consts: &mut |bound_var: ty::BoundVar, ty| {
|
||||
self.tcx.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Placeholder(ty::PlaceholderConst {
|
||||
self.tcx.mk_const(
|
||||
ty::ConstKind::Placeholder(ty::PlaceholderConst {
|
||||
universe: next_universe,
|
||||
name: bound_var,
|
||||
}),
|
||||
ty,
|
||||
})
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -2065,13 +2065,13 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
|
|||
if ty.has_non_region_param() || ty.has_non_region_infer() {
|
||||
bug!("const `{ct}`'s type should not reference params or types");
|
||||
}
|
||||
tcx.mk_const(ty::ConstS {
|
||||
ty,
|
||||
kind: ty::ConstKind::Placeholder(ty::PlaceholderConst {
|
||||
tcx.mk_const(
|
||||
ty::ConstKind::Placeholder(ty::PlaceholderConst {
|
||||
universe: ty::UniverseIndex::ROOT,
|
||||
name: ty::BoundVar::from_usize(idx),
|
||||
}),
|
||||
})
|
||||
ty,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
_ => arg,
|
||||
|
|
|
@ -3,11 +3,9 @@ use crate::{LateContext, LateLintPass, LintContext};
|
|||
use hir::{Expr, Pat};
|
||||
use rustc_errors::{Applicability, DelayDm};
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::TraitEngine;
|
||||
use rustc_infer::{infer::TyCtxtInferExt, traits::ObligationCause};
|
||||
use rustc_middle::ty::{self, List};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_trait_selection::traits::TraitEngineExt;
|
||||
|
||||
declare_lint! {
|
||||
/// The `for_loops_over_fallibles` lint checks for `for` loops over `Option` or `Result` values.
|
||||
|
@ -160,24 +158,19 @@ fn suggest_question_mark<'tcx>(
|
|||
|
||||
let ty = substs.type_at(0);
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
||||
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
body_id.hir_id,
|
||||
rustc_infer::traits::ObligationCauseCode::MiscObligation,
|
||||
);
|
||||
fulfill_cx.register_bound(
|
||||
let errors = rustc_trait_selection::traits::fully_solve_bound(
|
||||
&infcx,
|
||||
cause,
|
||||
ty::ParamEnv::empty(),
|
||||
// Erase any region vids from the type, which may not be resolved
|
||||
infcx.tcx.erase_regions(ty),
|
||||
into_iterator_did,
|
||||
cause,
|
||||
);
|
||||
|
||||
// Select all, including ambiguous predicates
|
||||
let errors = fulfill_cx.select_all_or_error(&infcx);
|
||||
|
||||
errors.is_empty()
|
||||
}
|
||||
|
|
|
@ -76,7 +76,6 @@ enum LLVMRustAttribute {
|
|||
OptimizeNone = 24,
|
||||
ReturnsTwice = 25,
|
||||
ReadNone = 26,
|
||||
InaccessibleMemOnly = 27,
|
||||
SanitizeHWAddress = 28,
|
||||
WillReturn = 29,
|
||||
StackProtectReq = 30,
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/IntrinsicsARM.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#if LLVM_VERSION_GE(16, 0)
|
||||
#include "llvm/IR/ModRef.h"
|
||||
#endif
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/COFFImportFile.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
|
@ -213,8 +216,6 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
|
|||
return Attribute::ReturnsTwice;
|
||||
case ReadNone:
|
||||
return Attribute::ReadNone;
|
||||
case InaccessibleMemOnly:
|
||||
return Attribute::InaccessibleMemOnly;
|
||||
case SanitizeHWAddress:
|
||||
return Attribute::SanitizeHWAddress;
|
||||
case WillReturn:
|
||||
|
@ -379,6 +380,43 @@ extern "C" LLVMAttributeRef LLVMRustCreateAllocKindAttr(LLVMContextRef C, uint64
|
|||
#endif
|
||||
}
|
||||
|
||||
// Simplified representation of `MemoryEffects` across the FFI boundary.
|
||||
//
|
||||
// Each variant corresponds to one of the static factory methods on `MemoryEffects`.
|
||||
enum class LLVMRustMemoryEffects {
|
||||
None,
|
||||
ReadOnly,
|
||||
InaccessibleMemOnly,
|
||||
};
|
||||
|
||||
extern "C" LLVMAttributeRef LLVMRustCreateMemoryEffectsAttr(LLVMContextRef C,
|
||||
LLVMRustMemoryEffects Effects) {
|
||||
#if LLVM_VERSION_GE(16, 0)
|
||||
switch (Effects) {
|
||||
case LLVMRustMemoryEffects::None:
|
||||
return wrap(Attribute::getWithMemoryEffects(*unwrap(C), MemoryEffects::none()));
|
||||
case LLVMRustMemoryEffects::ReadOnly:
|
||||
return wrap(Attribute::getWithMemoryEffects(*unwrap(C), MemoryEffects::readOnly()));
|
||||
case LLVMRustMemoryEffects::InaccessibleMemOnly:
|
||||
return wrap(Attribute::getWithMemoryEffects(*unwrap(C),
|
||||
MemoryEffects::inaccessibleMemOnly()));
|
||||
default:
|
||||
report_fatal_error("bad MemoryEffects.");
|
||||
}
|
||||
#else
|
||||
switch (Effects) {
|
||||
case LLVMRustMemoryEffects::None:
|
||||
return wrap(Attribute::get(*unwrap(C), Attribute::ReadNone));
|
||||
case LLVMRustMemoryEffects::ReadOnly:
|
||||
return wrap(Attribute::get(*unwrap(C), Attribute::ReadOnly));
|
||||
case LLVMRustMemoryEffects::InaccessibleMemOnly:
|
||||
return wrap(Attribute::get(*unwrap(C), Attribute::InaccessibleMemOnly));
|
||||
default:
|
||||
report_fatal_error("bad MemoryEffects.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Enable a fast-math flag
|
||||
//
|
||||
// https://llvm.org/docs/LangRef.html#fast-math-flags
|
||||
|
|
|
@ -341,10 +341,10 @@ impl<'tcx> CanonicalVarValues<'tcx> {
|
|||
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into()
|
||||
}
|
||||
GenericArgKind::Const(ct) => tcx
|
||||
.mk_const(ty::ConstS {
|
||||
ty: ct.ty(),
|
||||
kind: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
|
||||
})
|
||||
.mk_const(
|
||||
ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
|
||||
ct.ty(),
|
||||
)
|
||||
.into(),
|
||||
})
|
||||
.collect(),
|
||||
|
|
|
@ -2414,10 +2414,8 @@ impl<'tcx> ConstantKind<'tcx> {
|
|||
let generics = tcx.generics_of(item_def_id.to_def_id());
|
||||
let index = generics.param_def_id_to_index[&def_id];
|
||||
let name = tcx.hir().name(hir_id);
|
||||
let ty_const = tcx.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Param(ty::ParamConst::new(index, name)),
|
||||
ty,
|
||||
});
|
||||
let ty_const =
|
||||
tcx.mk_const(ty::ConstKind::Param(ty::ParamConst::new(index, name)), ty);
|
||||
debug!(?ty_const);
|
||||
|
||||
return Self::Ty(ty_const);
|
||||
|
|
|
@ -310,7 +310,8 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
|
|||
|
||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Const<'tcx> {
|
||||
fn decode(decoder: &mut D) -> Self {
|
||||
decoder.interner().mk_const(Decodable::decode(decoder))
|
||||
let consts: ty::ConstS<'tcx> = Decodable::decode(decoder);
|
||||
decoder.interner().mk_const(consts.kind, consts.ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,13 +77,13 @@ impl<'tcx> Const<'tcx> {
|
|||
|
||||
match Self::try_eval_lit_or_param(tcx, ty, expr) {
|
||||
Some(v) => v,
|
||||
None => tcx.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Unevaluated(ty::UnevaluatedConst {
|
||||
None => tcx.mk_const(
|
||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst {
|
||||
def: def.to_global(),
|
||||
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
||||
}),
|
||||
ty,
|
||||
}),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,10 +138,7 @@ impl<'tcx> Const<'tcx> {
|
|||
let generics = tcx.generics_of(item_def_id.to_def_id());
|
||||
let index = generics.param_def_id_to_index[&def_id];
|
||||
let name = tcx.hir().name(hir_id);
|
||||
Some(tcx.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Param(ty::ParamConst::new(index, name)),
|
||||
ty,
|
||||
}))
|
||||
Some(tcx.mk_const(ty::ConstKind::Param(ty::ParamConst::new(index, name)), ty))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
@ -150,7 +147,7 @@ impl<'tcx> Const<'tcx> {
|
|||
/// Interns the given value as a constant.
|
||||
#[inline]
|
||||
pub fn from_value(tcx: TyCtxt<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Self {
|
||||
tcx.mk_const(ConstS { kind: ConstKind::Value(val), ty })
|
||||
tcx.mk_const(ConstKind::Value(val), ty)
|
||||
}
|
||||
|
||||
/// Panics if self.kind != ty::ConstKind::Value
|
||||
|
|
|
@ -1316,7 +1316,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
msg: &str,
|
||||
) -> Const<'tcx> {
|
||||
let reported = self.sess.delay_span_bug(span, msg);
|
||||
self.mk_const(ty::ConstS { kind: ty::ConstKind::Error(reported), ty })
|
||||
self.mk_const(ty::ConstKind::Error(reported), ty)
|
||||
}
|
||||
|
||||
pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
|
||||
|
@ -2231,7 +2231,7 @@ macro_rules! direct_interners {
|
|||
|
||||
direct_interners! {
|
||||
region: mk_region(RegionKind<'tcx>): Region -> Region<'tcx>,
|
||||
const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
|
||||
const_: mk_const_internal(ConstS<'tcx>): Const -> Const<'tcx>,
|
||||
const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
|
||||
layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>,
|
||||
adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
|
||||
|
@ -2569,9 +2569,14 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
self.mk_ty_infer(TyVar(v))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mk_const(self, kind: ty::ConstKind<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
|
||||
self.mk_const_internal(ty::ConstS { kind, ty })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
|
||||
self.mk_const(ty::ConstS { kind: ty::ConstKind::Infer(InferConst::Var(v)), ty })
|
||||
self.mk_const(ty::ConstKind::Infer(InferConst::Var(v)), ty)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -2591,7 +2596,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
#[inline]
|
||||
pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
|
||||
self.mk_const(ty::ConstS { kind: ty::ConstKind::Infer(ic), ty })
|
||||
self.mk_const(ty::ConstKind::Infer(ic), ty)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -2601,7 +2606,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
#[inline]
|
||||
pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> Const<'tcx> {
|
||||
self.mk_const(ty::ConstS { kind: ty::ConstKind::Param(ParamConst { index, name }), ty })
|
||||
self.mk_const(ty::ConstKind::Param(ParamConst { index, name }), ty)
|
||||
}
|
||||
|
||||
pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
|
||||
|
|
|
@ -566,10 +566,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
))
|
||||
},
|
||||
consts: &mut |c, ty: Ty<'tcx>| {
|
||||
self.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Bound(ty::INNERMOST, shift_bv(c)),
|
||||
ty,
|
||||
})
|
||||
self.mk_const(ty::ConstKind::Bound(ty::INNERMOST, shift_bv(c)), ty)
|
||||
},
|
||||
},
|
||||
)
|
||||
|
@ -648,7 +645,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
let index = entry.index();
|
||||
let var = ty::BoundVar::from_usize(index);
|
||||
let () = entry.or_insert_with(|| ty::BoundVariableKind::Const).expect_const();
|
||||
self.tcx.mk_const(ty::ConstS { ty, kind: ty::ConstKind::Bound(ty::INNERMOST, var) })
|
||||
self.tcx.mk_const(ty::ConstKind::Bound(ty::INNERMOST, var), ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -732,10 +729,7 @@ impl<'tcx> TypeFolder<'tcx> for Shifter<'tcx> {
|
|||
ct
|
||||
} else {
|
||||
let debruijn = debruijn.shifted_in(self.amount);
|
||||
self.tcx.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Bound(debruijn, bound_ct),
|
||||
ty: ct.ty(),
|
||||
})
|
||||
self.tcx.mk_const(ty::ConstKind::Bound(debruijn, bound_ct), ct.ty())
|
||||
}
|
||||
} else {
|
||||
ct.super_fold_with(self)
|
||||
|
|
|
@ -639,10 +639,10 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
|
|||
au.substs,
|
||||
bu.substs,
|
||||
)?;
|
||||
return Ok(tcx.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def: au.def, substs }),
|
||||
ty: a.ty(),
|
||||
}));
|
||||
return Ok(tcx.mk_const(
|
||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def: au.def, substs }),
|
||||
a.ty(),
|
||||
));
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
|
|
@ -805,7 +805,7 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> {
|
|||
let ty = self.ty().try_fold_with(folder)?;
|
||||
let kind = self.kind().try_fold_with(folder)?;
|
||||
if ty != self.ty() || kind != self.kind() {
|
||||
Ok(folder.tcx().mk_const(ty::ConstS { ty, kind }))
|
||||
Ok(folder.tcx().mk_const(kind, ty))
|
||||
} else {
|
||||
Ok(self)
|
||||
}
|
||||
|
|
|
@ -74,8 +74,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
Constant { user_ty, span, literal }
|
||||
}
|
||||
ExprKind::ConstParam { param, def_id: _ } => {
|
||||
let const_param =
|
||||
tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Param(param), ty: expr.ty });
|
||||
let const_param = tcx.mk_const(ty::ConstKind::Param(param), expr.ty);
|
||||
let literal = ConstantKind::Ty(const_param);
|
||||
|
||||
Constant { user_ty: None, span, literal }
|
||||
|
|
|
@ -364,12 +364,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let arm_block = this.bind_pattern(
|
||||
outer_source_info,
|
||||
candidate,
|
||||
arm.guard.as_ref(),
|
||||
&fake_borrow_temps,
|
||||
scrutinee_span,
|
||||
Some(arm.span),
|
||||
Some(arm.scope),
|
||||
Some(match_scope),
|
||||
Some((arm, match_scope)),
|
||||
false,
|
||||
);
|
||||
|
||||
|
@ -410,12 +407,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
&mut self,
|
||||
outer_source_info: SourceInfo,
|
||||
candidate: Candidate<'_, 'tcx>,
|
||||
guard: Option<&Guard<'tcx>>,
|
||||
fake_borrow_temps: &[(Place<'tcx>, Local)],
|
||||
scrutinee_span: Span,
|
||||
arm_span: Option<Span>,
|
||||
arm_scope: Option<region::Scope>,
|
||||
match_scope: Option<region::Scope>,
|
||||
arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>,
|
||||
storages_alive: bool,
|
||||
) -> BasicBlock {
|
||||
if candidate.subcandidates.is_empty() {
|
||||
|
@ -424,11 +418,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
self.bind_and_guard_matched_candidate(
|
||||
candidate,
|
||||
&[],
|
||||
guard,
|
||||
fake_borrow_temps,
|
||||
scrutinee_span,
|
||||
arm_span,
|
||||
match_scope,
|
||||
arm_match_scope,
|
||||
true,
|
||||
storages_alive,
|
||||
)
|
||||
|
@ -449,6 +441,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// we lower the guard.
|
||||
let target_block = self.cfg.start_new_block();
|
||||
let mut schedule_drops = true;
|
||||
let arm = arm_match_scope.unzip().0;
|
||||
// We keep a stack of all of the bindings and type ascriptions
|
||||
// from the parent candidates that we visit, that also need to
|
||||
// be bound for each candidate.
|
||||
|
@ -456,21 +449,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
candidate,
|
||||
&mut Vec::new(),
|
||||
&mut |leaf_candidate, parent_bindings| {
|
||||
if let Some(arm_scope) = arm_scope {
|
||||
self.clear_top_scope(arm_scope);
|
||||
if let Some(arm) = arm {
|
||||
self.clear_top_scope(arm.scope);
|
||||
}
|
||||
let binding_end = self.bind_and_guard_matched_candidate(
|
||||
leaf_candidate,
|
||||
parent_bindings,
|
||||
guard,
|
||||
&fake_borrow_temps,
|
||||
scrutinee_span,
|
||||
arm_span,
|
||||
match_scope,
|
||||
arm_match_scope,
|
||||
schedule_drops,
|
||||
storages_alive,
|
||||
);
|
||||
if arm_scope.is_none() {
|
||||
if arm.is_none() {
|
||||
schedule_drops = false;
|
||||
}
|
||||
self.cfg.goto(binding_end, outer_source_info, target_block);
|
||||
|
@ -636,12 +627,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
self.bind_pattern(
|
||||
self.source_info(irrefutable_pat.span),
|
||||
candidate,
|
||||
None,
|
||||
&fake_borrow_temps,
|
||||
irrefutable_pat.span,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
.unit()
|
||||
|
@ -1820,12 +1808,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let post_guard_block = self.bind_pattern(
|
||||
self.source_info(pat.span),
|
||||
guard_candidate,
|
||||
None,
|
||||
&fake_borrow_temps,
|
||||
expr.span,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
|
@ -1844,11 +1829,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
&mut self,
|
||||
candidate: Candidate<'pat, 'tcx>,
|
||||
parent_bindings: &[(Vec<Binding<'tcx>>, Vec<Ascription<'tcx>>)],
|
||||
guard: Option<&Guard<'tcx>>,
|
||||
fake_borrows: &[(Place<'tcx>, Local)],
|
||||
scrutinee_span: Span,
|
||||
arm_span: Option<Span>,
|
||||
match_scope: Option<region::Scope>,
|
||||
arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>,
|
||||
schedule_drops: bool,
|
||||
storages_alive: bool,
|
||||
) -> BasicBlock {
|
||||
|
@ -1960,7 +1943,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// the reference that we create for the arm.
|
||||
// * So we eagerly create the reference for the arm and then take a
|
||||
// reference to that.
|
||||
if let Some(guard) = guard {
|
||||
if let Some((arm, match_scope)) = arm_match_scope
|
||||
&& let Some(guard) = &arm.guard
|
||||
{
|
||||
let tcx = self.tcx;
|
||||
let bindings = parent_bindings
|
||||
.iter()
|
||||
|
@ -1981,8 +1966,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
self.cfg.push_assign(block, scrutinee_source_info, Place::from(temp), borrow);
|
||||
}
|
||||
|
||||
let arm_span = arm_span.unwrap();
|
||||
let match_scope = match_scope.unwrap();
|
||||
let mut guard_span = rustc_span::DUMMY_SP;
|
||||
|
||||
let (post_guard_block, otherwise_post_guard_block) =
|
||||
|
@ -1995,13 +1978,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
e,
|
||||
None,
|
||||
match_scope,
|
||||
this.source_info(arm_span),
|
||||
this.source_info(arm.span),
|
||||
)
|
||||
}
|
||||
Guard::IfLet(ref pat, scrutinee) => {
|
||||
let s = &this.thir[scrutinee];
|
||||
guard_span = s.span;
|
||||
this.lower_let_expr(block, s, pat, match_scope, None, arm_span)
|
||||
this.lower_let_expr(block, s, pat, match_scope, None, arm.span)
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2317,24 +2300,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let matching = this.bind_pattern(
|
||||
this.source_info(pattern.span),
|
||||
candidate,
|
||||
None,
|
||||
&fake_borrow_temps,
|
||||
initializer_span,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
);
|
||||
// This block is for the failure case
|
||||
let failure = this.bind_pattern(
|
||||
this.source_info(else_block_span),
|
||||
wildcard,
|
||||
None,
|
||||
&fake_borrow_temps,
|
||||
initializer_span,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
true,
|
||||
);
|
||||
this.break_for_else(failure, *let_else_scope, this.source_info(initializer_span));
|
||||
|
|
|
@ -654,8 +654,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
|
|||
.builtin_deref(true)
|
||||
.expect("tried to dereference on non-ptr type")
|
||||
.ty;
|
||||
let dereferenced_const =
|
||||
self.tcx.mk_const(ty::ConstS { kind: ct.kind(), ty: pointee_ty });
|
||||
let dereferenced_const = self.tcx.mk_const(ct.kind(), pointee_ty);
|
||||
self = dereferenced_const.print(self)?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::infer::InferCtxt;
|
||||
use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput};
|
||||
use crate::traits::query::NoSolution;
|
||||
use crate::traits::{ObligationCause, TraitEngine, TraitEngineExt};
|
||||
use crate::traits::ObligationCause;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::HirId;
|
||||
|
@ -74,20 +74,20 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
|
|||
debug!(?constraints);
|
||||
// Instantiation may have produced new inference variables and constraints on those
|
||||
// variables. Process these constraints.
|
||||
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self.tcx);
|
||||
let cause = ObligationCause::misc(span, body_id);
|
||||
for &constraint in &constraints.outlives {
|
||||
let obligation = self.query_outlives_constraint_to_obligation(
|
||||
constraint,
|
||||
cause.clone(),
|
||||
param_env,
|
||||
);
|
||||
fulfill_cx.register_predicate_obligation(self, obligation);
|
||||
}
|
||||
let errors = super::fully_solve_obligations(
|
||||
self,
|
||||
constraints.outlives.iter().map(|constraint| {
|
||||
self.query_outlives_constraint_to_obligation(
|
||||
*constraint,
|
||||
cause.clone(),
|
||||
param_env,
|
||||
)
|
||||
}),
|
||||
);
|
||||
if !constraints.member_constraints.is_empty() {
|
||||
span_bug!(span, "{:#?}", constraints.member_constraints);
|
||||
}
|
||||
let errors = fulfill_cx.select_all_or_error(self);
|
||||
if !errors.is_empty() {
|
||||
self.tcx.sess.delay_span_bug(
|
||||
span,
|
||||
|
|
|
@ -831,9 +831,7 @@ impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
|||
let universe = self.universe_for(debruijn);
|
||||
let p = ty::PlaceholderConst { universe, name: bound_const };
|
||||
self.mapped_consts.insert(p, bound_const);
|
||||
self.infcx
|
||||
.tcx
|
||||
.mk_const(ty::ConstS { kind: ty::ConstKind::Placeholder(p), ty: ct.ty() })
|
||||
self.infcx.tcx.mk_const(ty::ConstKind::Placeholder(p), ct.ty())
|
||||
}
|
||||
_ => ct.super_fold_with(self),
|
||||
}
|
||||
|
@ -968,10 +966,7 @@ impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
|||
let db = ty::DebruijnIndex::from_usize(
|
||||
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
||||
);
|
||||
self.tcx().mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Bound(db, *replace_var),
|
||||
ty: ct.ty(),
|
||||
})
|
||||
self.tcx().mk_const(ty::ConstKind::Bound(db, *replace_var), ct.ty())
|
||||
}
|
||||
None => ct,
|
||||
}
|
||||
|
@ -2173,7 +2168,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
|||
crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
|
||||
let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id);
|
||||
let kind = ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs));
|
||||
ty.map_bound(|ty| tcx.mk_const(ty::ConstS { ty, kind }).into())
|
||||
ty.map_bound(|ty| tcx.mk_const(kind, ty).into())
|
||||
} else {
|
||||
ty.map_bound(|ty| ty.into())
|
||||
};
|
||||
|
|
|
@ -555,13 +555,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
GenericParamDefKind::Const { .. } => {
|
||||
let bound_var = ty::BoundVariableKind::Const;
|
||||
bound_vars.push(bound_var);
|
||||
tcx.mk_const(ty::ConstS {
|
||||
ty: tcx.type_of(param.def_id),
|
||||
kind: ty::ConstKind::Bound(
|
||||
tcx.mk_const(
|
||||
ty::ConstKind::Bound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||
),
|
||||
})
|
||||
tcx.type_of(param.def_id),
|
||||
)
|
||||
.into()
|
||||
}
|
||||
});
|
||||
|
|
|
@ -734,10 +734,10 @@ fn bound_vars_for_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx
|
|||
}
|
||||
|
||||
ty::GenericParamDefKind::Const { .. } => tcx
|
||||
.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)),
|
||||
ty: tcx.type_of(param.def_id),
|
||||
})
|
||||
.mk_const(
|
||||
ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)),
|
||||
tcx.type_of(param.def_id),
|
||||
)
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -546,7 +546,7 @@ impl<'tcx> LowerInto<'tcx, ty::Const<'tcx>> for &chalk_ir::Const<RustInterner<'t
|
|||
chalk_ir::ConstValue::Placeholder(_p) => unimplemented!(),
|
||||
chalk_ir::ConstValue::Concrete(c) => ty::ConstKind::Value(c.interned),
|
||||
};
|
||||
interner.tcx.mk_const(ty::ConstS { ty, kind })
|
||||
interner.tcx.mk_const(kind, ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ pub(crate) fn destructure_const<'tcx>(
|
|||
// construct the consts for the elements of the array/slice
|
||||
let field_consts = branches
|
||||
.iter()
|
||||
.map(|b| tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Value(*b), ty: *inner_ty }))
|
||||
.map(|b| tcx.mk_const(ty::ConstKind::Value(*b), *inner_ty))
|
||||
.collect::<Vec<_>>();
|
||||
debug!(?field_consts);
|
||||
|
||||
|
@ -52,10 +52,7 @@ pub(crate) fn destructure_const<'tcx>(
|
|||
|
||||
for (field, field_valtree) in iter::zip(fields, branches) {
|
||||
let field_ty = field.ty(tcx, substs);
|
||||
let field_const = tcx.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Value(*field_valtree),
|
||||
ty: field_ty,
|
||||
});
|
||||
let field_const = tcx.mk_const(ty::ConstKind::Value(*field_valtree), field_ty);
|
||||
field_consts.push(field_const);
|
||||
}
|
||||
debug!(?field_consts);
|
||||
|
@ -65,10 +62,7 @@ pub(crate) fn destructure_const<'tcx>(
|
|||
ty::Tuple(elem_tys) => {
|
||||
let fields = iter::zip(*elem_tys, branches)
|
||||
.map(|(elem_ty, elem_valtree)| {
|
||||
tcx.mk_const(ty::ConstS {
|
||||
kind: ty::ConstKind::Value(*elem_valtree),
|
||||
ty: elem_ty,
|
||||
})
|
||||
tcx.mk_const(ty::ConstKind::Value(*elem_valtree), elem_ty)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -261,17 +255,13 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||
let uneval =
|
||||
ty::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
|
||||
|
||||
let constant = self
|
||||
.tcx
|
||||
.mk_const(ty::ConstS { kind: ty::ConstKind::Unevaluated(uneval), ty: node.ty });
|
||||
let constant = self.tcx.mk_const(ty::ConstKind::Unevaluated(uneval), node.ty);
|
||||
|
||||
self.nodes.push(Node::Leaf(constant))
|
||||
}
|
||||
|
||||
ExprKind::ConstParam { param, .. } => {
|
||||
let const_param = self
|
||||
.tcx
|
||||
.mk_const(ty::ConstS { kind: ty::ConstKind::Param(*param), ty: node.ty });
|
||||
let const_param = self.tcx.mk_const(ty::ConstKind::Param(*param), node.ty);
|
||||
self.nodes.push(Node::Leaf(const_param))
|
||||
}
|
||||
|
||||
|
|
|
@ -1380,21 +1380,46 @@ impl Config {
|
|||
git
|
||||
}
|
||||
|
||||
pub(crate) fn artifact_channel(&self, builder: &Builder<'_>, commit: &str) -> String {
|
||||
if builder.rust_info.is_managed_git_subrepository() {
|
||||
/// Bootstrap embeds a version number into the name of shared libraries it uploads in CI.
|
||||
/// Return the version it would have used for the given commit.
|
||||
pub(crate) fn artifact_version_part(&self, builder: &Builder<'_>, commit: &str) -> String {
|
||||
let (channel, version) = if builder.rust_info.is_managed_git_subrepository() {
|
||||
let mut channel = self.git();
|
||||
channel.arg("show").arg(format!("{}:src/ci/channel", commit));
|
||||
let channel = output(&mut channel);
|
||||
channel.trim().to_owned()
|
||||
} else if let Ok(channel) = fs::read_to_string(builder.src.join("src/ci/channel")) {
|
||||
channel.trim().to_owned()
|
||||
let mut version = self.git();
|
||||
version.arg("show").arg(format!("{}:src/version", commit));
|
||||
let version = output(&mut version);
|
||||
(channel.trim().to_owned(), version.trim().to_owned())
|
||||
} else {
|
||||
let src = builder.src.display();
|
||||
eprintln!("error: failed to determine artifact channel");
|
||||
eprintln!(
|
||||
"help: either use git or ensure that {src}/src/ci/channel contains the name of the channel to use"
|
||||
);
|
||||
panic!();
|
||||
let channel = fs::read_to_string(builder.src.join("src/ci/channel"));
|
||||
let version = fs::read_to_string(builder.src.join("src/version"));
|
||||
match (channel, version) {
|
||||
(Ok(channel), Ok(version)) => {
|
||||
(channel.trim().to_owned(), version.trim().to_owned())
|
||||
}
|
||||
(channel, version) => {
|
||||
let src = builder.src.display();
|
||||
eprintln!("error: failed to determine artifact channel and/or version");
|
||||
eprintln!(
|
||||
"help: consider using a git checkout or ensure these files are readable"
|
||||
);
|
||||
if let Err(channel) = channel {
|
||||
eprintln!("reading {}/src/ci/channel failed: {:?}", src, channel);
|
||||
}
|
||||
if let Err(version) = version {
|
||||
eprintln!("reading {}/src/version failed: {:?}", src, version);
|
||||
}
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
match channel.as_str() {
|
||||
"stable" => version,
|
||||
"beta" => channel,
|
||||
"nightly" => channel,
|
||||
other => unreachable!("{:?} is not recognized as a valid channel", other),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1637,7 +1662,7 @@ fn maybe_download_rustfmt(builder: &Builder<'_>) -> Option<PathBuf> {
|
|||
|
||||
fn download_ci_rustc(builder: &Builder<'_>, commit: &str) {
|
||||
builder.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})"));
|
||||
let channel = builder.config.artifact_channel(builder, commit);
|
||||
let version = builder.config.artifact_version_part(builder, commit);
|
||||
let host = builder.config.build.triple;
|
||||
let bin_root = builder.out.join(host).join("ci-rustc");
|
||||
let rustc_stamp = bin_root.join(".rustc-stamp");
|
||||
|
@ -1646,13 +1671,13 @@ fn download_ci_rustc(builder: &Builder<'_>, commit: &str) {
|
|||
if bin_root.exists() {
|
||||
t!(fs::remove_dir_all(&bin_root));
|
||||
}
|
||||
let filename = format!("rust-std-{channel}-{host}.tar.xz");
|
||||
let filename = format!("rust-std-{version}-{host}.tar.xz");
|
||||
let pattern = format!("rust-std-{host}");
|
||||
download_ci_component(builder, filename, &pattern, commit);
|
||||
let filename = format!("rustc-{channel}-{host}.tar.xz");
|
||||
let filename = format!("rustc-{version}-{host}.tar.xz");
|
||||
download_ci_component(builder, filename, "rustc", commit);
|
||||
// download-rustc doesn't need its own cargo, it can just use beta's.
|
||||
let filename = format!("rustc-dev-{channel}-{host}.tar.xz");
|
||||
let filename = format!("rustc-dev-{version}-{host}.tar.xz");
|
||||
download_ci_component(builder, filename, "rustc-dev", commit);
|
||||
|
||||
builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustc"));
|
||||
|
|
|
@ -269,8 +269,8 @@ fn download_ci_llvm(builder: &Builder<'_>, llvm_sha: &str) {
|
|||
} else {
|
||||
&builder.config.stage0_metadata.config.artifacts_server
|
||||
};
|
||||
let channel = builder.config.artifact_channel(builder, llvm_sha);
|
||||
let filename = format!("rust-dev-{}-{}.tar.xz", channel, builder.build.build.triple);
|
||||
let version = builder.config.artifact_version_part(builder, llvm_sha);
|
||||
let filename = format!("rust-dev-{}-{}.tar.xz", version, builder.build.build.triple);
|
||||
let tarball = rustc_cache.join(&filename);
|
||||
if !tarball.exists() {
|
||||
let help_on_error = "error: failed to download llvm from ci
|
||||
|
|
|
@ -881,31 +881,24 @@ so that we can apply CSS-filters to change the arrow color in themes */
|
|||
display: block;
|
||||
}
|
||||
|
||||
.search-results .desc > span {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.search-results > a {
|
||||
display: block;
|
||||
display: flex;
|
||||
/* A little margin ensures the browser's outlining of focused links has room to display. */
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
.search-results > a > div {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.search-results .result-name, .search-results div.desc {
|
||||
width: 50%;
|
||||
}
|
||||
.search-results .result-name {
|
||||
padding-right: 1em;
|
||||
.search-results > a > div.desc {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.search-results a:hover,
|
||||
|
@ -1867,7 +1860,8 @@ in storage.js
|
|||
}
|
||||
|
||||
/* Display an alternating layout on tablets and phones */
|
||||
.item-table, .item-row, .item-left, .item-right {
|
||||
.item-table, .item-row, .item-left, .item-right,
|
||||
.search-results > a, .search-results > a > div {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
@ -1875,10 +1869,7 @@ in storage.js
|
|||
.search-results > a {
|
||||
padding: 5px 0px;
|
||||
}
|
||||
.search-results .result-name, .search-results div.desc {
|
||||
width: 100%;
|
||||
}
|
||||
.search-results div.desc, .item-right {
|
||||
.search-results > a > div.desc, .item-right {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
|
|
|
@ -1593,7 +1593,6 @@ function initSearch(rawSearchIndex) {
|
|||
link.className = "result-" + type;
|
||||
link.href = item.href;
|
||||
|
||||
const wrapper = document.createElement("div");
|
||||
const resultName = document.createElement("div");
|
||||
resultName.className = "result-name";
|
||||
|
||||
|
@ -1614,16 +1613,13 @@ function initSearch(rawSearchIndex) {
|
|||
resultName.insertAdjacentHTML(
|
||||
"beforeend",
|
||||
item.displayPath + "<span class=\"" + type + "\">" + name + extra + "</span>");
|
||||
wrapper.appendChild(resultName);
|
||||
link.appendChild(resultName);
|
||||
|
||||
const description = document.createElement("div");
|
||||
description.className = "desc";
|
||||
const spanDesc = document.createElement("span");
|
||||
spanDesc.insertAdjacentHTML("beforeend", item.desc);
|
||||
description.insertAdjacentHTML("beforeend", item.desc);
|
||||
|
||||
description.appendChild(spanDesc);
|
||||
wrapper.appendChild(description);
|
||||
link.appendChild(wrapper);
|
||||
link.appendChild(description);
|
||||
output.appendChild(link);
|
||||
});
|
||||
} else if (query.error === null) {
|
||||
|
|
|
@ -7,6 +7,7 @@ pub fn bar() { unsafe { foo() } }
|
|||
extern "C" {
|
||||
// CHECK-LABEL: declare{{.*}}void @foo()
|
||||
// CHECK-SAME: [[ATTRS:#[0-9]+]]
|
||||
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readnone{{.*}} }
|
||||
// The attribute changed from `readnone` to `memory(none)` with LLVM 16.0.
|
||||
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readnone|memory\(none\)}}{{.*}} }
|
||||
#[ffi_const] pub fn foo();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ pub fn bar() { unsafe { foo() } }
|
|||
extern "C" {
|
||||
// CHECK-LABEL: declare{{.*}}void @foo()
|
||||
// CHECK-SAME: [[ATTRS:#[0-9]+]]
|
||||
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readonly{{.*}} }
|
||||
// The attribute changed from `readonly` to `memory(read)` with LLVM 16.0.
|
||||
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readonly|memory\(read\)}}{{.*}} }
|
||||
#[ffi_pure] pub fn foo();
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ reload:
|
|||
// Waiting for the search results to appear...
|
||||
wait-for: "#titles"
|
||||
assert-css: (
|
||||
"//*[@class='desc']//*[text()='Just a normal struct.']",
|
||||
"//*[@class='desc'][text()='Just a normal struct.']",
|
||||
{"color": "rgb(197, 197, 197)"},
|
||||
)
|
||||
assert-css: (
|
||||
|
@ -159,7 +159,7 @@ assert-css: (
|
|||
)
|
||||
|
||||
// Checking color and background on hover.
|
||||
move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']"
|
||||
move-cursor-to: "//*[@class='desc'][text()='Just a normal struct.']"
|
||||
assert-css: (
|
||||
"//*[@class='result-name']/*[text()='test_docs::']",
|
||||
{"color": "rgb(255, 255, 255)"},
|
||||
|
@ -179,7 +179,7 @@ reload:
|
|||
// Waiting for the search results to appear...
|
||||
wait-for: "#titles"
|
||||
assert-css: (
|
||||
"//*[@class='desc']//*[text()='Just a normal struct.']",
|
||||
"//*[@class='desc'][text()='Just a normal struct.']",
|
||||
{"color": "rgb(221, 221, 221)"},
|
||||
)
|
||||
assert-css: (
|
||||
|
@ -276,7 +276,7 @@ reload:
|
|||
// Waiting for the search results to appear...
|
||||
wait-for: "#titles"
|
||||
assert-css: (
|
||||
"//*[@class='desc']//*[text()='Just a normal struct.']",
|
||||
"//*[@class='desc'][text()='Just a normal struct.']",
|
||||
{"color": "rgb(0, 0, 0)"},
|
||||
)
|
||||
assert-css: (
|
||||
|
|
|
@ -7,7 +7,7 @@ press-key: 'Enter'
|
|||
wait-for: "#crate-search"
|
||||
// The width is returned by "getComputedStyle" which returns the exact number instead of the
|
||||
// CSS rule which is "50%"...
|
||||
assert-css: (".search-results div.desc", {"width": "318px"})
|
||||
assert-css: (".search-results div.desc", {"width": "310px"})
|
||||
size: (600, 100)
|
||||
// As counter-intuitive as it may seem, in this width, the width is "100%", which is why
|
||||
// when computed it's larger.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use std::collections::HashSet;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn check_unused_files(path: &Path, bad: &mut bool) {
|
||||
fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) {
|
||||
let mut rs_files = Vec::<PathBuf>::new();
|
||||
let mut output_files = HashSet::<PathBuf>::new();
|
||||
let files = walkdir::WalkDir::new(&path.join("test/mir-opt")).into_iter();
|
||||
|
@ -27,11 +27,15 @@ fn check_unused_files(path: &Path, bad: &mut bool) {
|
|||
|
||||
for extra in output_files {
|
||||
if extra.file_name() != Some("README.md".as_ref()) {
|
||||
tidy_error!(
|
||||
bad,
|
||||
"the following output file is not associated with any mir-opt test, you can remove it: {}",
|
||||
extra.display()
|
||||
);
|
||||
if !bless {
|
||||
tidy_error!(
|
||||
bad,
|
||||
"the following output file is not associated with any mir-opt test, you can remove it: {}",
|
||||
extra.display()
|
||||
);
|
||||
} else {
|
||||
let _ = std::fs::remove_file(extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +69,6 @@ fn check_dash_files(path: &Path, bless: bool, bad: &mut bool) {
|
|||
}
|
||||
|
||||
pub fn check(path: &Path, bless: bool, bad: &mut bool) {
|
||||
check_unused_files(path, bad);
|
||||
check_unused_files(path, bless, bad);
|
||||
check_dash_files(path, bless, bad);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue