Merge from rustc
This commit is contained in:
commit
482859261a
444 changed files with 5150 additions and 3511 deletions
|
|
@ -175,9 +175,7 @@ fn main() {
|
|||
// Find any host flags that were passed by bootstrap.
|
||||
// The flags are stored in a RUSTC_HOST_FLAGS variable, separated by spaces.
|
||||
if let Ok(flags) = std::env::var("RUSTC_HOST_FLAGS") {
|
||||
for flag in flags.split(' ') {
|
||||
cmd.arg(flag);
|
||||
}
|
||||
cmd.args(flags.split(' '));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,6 @@ impl Step for Std {
|
|||
// NOTE: the beta compiler may generate different artifacts than the downloaded compiler, so
|
||||
// its artifacts can't be reused.
|
||||
&& compiler.stage != 0
|
||||
// This check is specific to testing std itself; see `test::Std` for more details.
|
||||
&& !self.force_recompile
|
||||
{
|
||||
let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false });
|
||||
|
|
|
|||
|
|
@ -2767,25 +2767,32 @@ impl Config {
|
|||
}
|
||||
};
|
||||
|
||||
let files_to_track =
|
||||
&["compiler", "library", "src/version", "src/stage0", "src/ci/channel"];
|
||||
let mut files_to_track = vec!["compiler", "src/version", "src/stage0", "src/ci/channel"];
|
||||
|
||||
// In CI, disable ci-rustc if there are changes in the library tree. But for non-CI, ignore
|
||||
// these changes to speed up the build process for library developers. This provides consistent
|
||||
// functionality for library developers between `download-rustc=true` and `download-rustc="if-unchanged"`
|
||||
// options.
|
||||
if CiEnv::is_ci() {
|
||||
files_to_track.push("library");
|
||||
}
|
||||
|
||||
// Look for a version to compare to based on the current commit.
|
||||
// Only commits merged by bors will have CI artifacts.
|
||||
let commit = match self.last_modified_commit(files_to_track, "download-rustc", if_unchanged)
|
||||
{
|
||||
Some(commit) => commit,
|
||||
None => {
|
||||
if if_unchanged {
|
||||
return None;
|
||||
let commit =
|
||||
match self.last_modified_commit(&files_to_track, "download-rustc", if_unchanged) {
|
||||
Some(commit) => commit,
|
||||
None => {
|
||||
if if_unchanged {
|
||||
return None;
|
||||
}
|
||||
println!("ERROR: could not find commit hash for downloading rustc");
|
||||
println!("HELP: maybe your repository history is too shallow?");
|
||||
println!("HELP: consider disabling `download-rustc`");
|
||||
println!("HELP: or fetch enough history to include one upstream commit");
|
||||
crate::exit!(1);
|
||||
}
|
||||
println!("ERROR: could not find commit hash for downloading rustc");
|
||||
println!("HELP: maybe your repository history is too shallow?");
|
||||
println!("HELP: consider disabling `download-rustc`");
|
||||
println!("HELP: or fetch enough history to include one upstream commit");
|
||||
crate::exit!(1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
if CiEnv::is_ci() && {
|
||||
let head_sha =
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ Rust for AIX operating system, currently only 64-bit PowerPC is supported.
|
|||
|
||||
## Target maintainers
|
||||
|
||||
- QIU Chaofan `qiucofan@cn.ibm.com`, https://github.com/ecnelises
|
||||
- Kai LUO, `lkail@cn.ibm.com`, https://github.com/bzEq
|
||||
- David Tenty `daltenty@ibm.com`, https://github.com/daltenty
|
||||
- Chris Cambly, `ccambly@ca.ibm.com`, https://github.com/gilamn5tr
|
||||
|
||||
## Requirements
|
||||
|
||||
|
|
|
|||
|
|
@ -7,17 +7,9 @@ updatable, and performant.
|
|||
|
||||
## Target maintainers
|
||||
|
||||
The [Fuchsia team]:
|
||||
See [`fuchsia.toml`] in the `team` repository for current target maintainers.
|
||||
|
||||
- Tyler Mandry ([@tmandry](https://github.com/tmandry))
|
||||
- David Koloski ([@djkoloski](https://github.com/djkoloski))
|
||||
- Julia Ryan ([@P1n3appl3](https://github.com/P1n3appl3))
|
||||
- Erick Tryzelaar ([@erickt](https://github.com/erickt))
|
||||
|
||||
As the team evolves over time, the specific members listed here may differ from
|
||||
the members reported by the API. The API should be considered to be
|
||||
authoritative if this occurs. Instead of pinging individual members, use
|
||||
`@rustbot ping fuchsia` to contact the team on GitHub.
|
||||
[`fuchsia.toml`]: https://github.com/rust-lang/team/blob/master/teams/fuchsia.toml
|
||||
|
||||
## Table of contents
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TyCtxtInferExt};
|
||||
use rustc_infer::traits;
|
||||
use rustc_middle::ty::{self, Upcast};
|
||||
use rustc_middle::ty::{self, TypingMode, Upcast};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
|
|
@ -38,7 +38,7 @@ pub(crate) fn synthesize_blanket_impls(
|
|||
if !matches!(trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) {
|
||||
continue;
|
||||
}
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
let args = infcx.fresh_args_for_item(DUMMY_SP, item_def_id);
|
||||
let impl_ty = ty.instantiate(tcx, args);
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE, LocalDefId};
|
|||
use rustc_hir_analysis::lower_ty;
|
||||
use rustc_middle::metadata::Reexport;
|
||||
use rustc_middle::middle::resolve_bound_vars as rbv;
|
||||
use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::ExpnKind;
|
||||
use rustc_span::hygiene::{AstPass, MacroKind};
|
||||
|
|
@ -1829,7 +1829,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
|||
Array(Box::new(clean_ty(ty, cx)), length.into())
|
||||
}
|
||||
TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
|
||||
TyKind::OpaqueDef(ty, _) => {
|
||||
TyKind::OpaqueDef(ty) => {
|
||||
ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
|
||||
}
|
||||
TyKind::Path(_) => clean_qpath(ty, cx),
|
||||
|
|
@ -1863,7 +1863,7 @@ fn normalize<'tcx>(
|
|||
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
|
||||
|
||||
// Try to normalize `<X as Y>::T` to a type
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
let infcx = cx.tcx.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
let normalized = infcx
|
||||
.at(&ObligationCause::dummy(), cx.param_env)
|
||||
.query_normalize(ty)
|
||||
|
|
@ -2399,7 +2399,7 @@ pub(crate) fn clean_variant_def_with_args<'tcx>(
|
|||
use rustc_trait_selection::infer::TyCtxtInferExt;
|
||||
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
|
||||
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
let infcx = cx.tcx.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
let kind = match variant.ctor_kind() {
|
||||
Some(CtorKind::Const) => VariantKind::CLike,
|
||||
Some(CtorKind::Fn) => VariantKind::Tuple(
|
||||
|
|
|
|||
|
|
@ -198,10 +198,6 @@ fn generate_mergeable_doctest(
|
|||
} else {
|
||||
writeln!(output, "mod {test_id} {{\n{}{}", doctest.crates, doctest.maybe_crate_attrs)
|
||||
.unwrap();
|
||||
if scraped_test.langstr.no_run {
|
||||
// To prevent having warnings about unused items since they're not called.
|
||||
writeln!(output, "#![allow(unused)]").unwrap();
|
||||
}
|
||||
if doctest.has_main_fn {
|
||||
output.push_str(&doctest.everything_else);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,19 @@ impl<'tcx> HirCollector<'tcx> {
|
|||
let attrs = Attributes::from_ast(ast_attrs);
|
||||
if let Some(doc) = attrs.opt_doc_value() {
|
||||
let span = span_of_fragments(&attrs.doc_strings).unwrap_or(sp);
|
||||
self.collector.position = span;
|
||||
self.collector.position = if span.edition().at_least_rust_2024() {
|
||||
span
|
||||
} else {
|
||||
// this span affects filesystem path resolution,
|
||||
// so we need to keep it the same as it was previously
|
||||
ast_attrs
|
||||
.iter()
|
||||
.find(|attr| attr.doc_str().is_some())
|
||||
.map(|attr| {
|
||||
attr.span.ctxt().outer_expn().expansion_cause().unwrap_or(attr.span)
|
||||
})
|
||||
.unwrap_or(DUMMY_SP)
|
||||
};
|
||||
markdown::find_testable_code(
|
||||
&doc,
|
||||
&mut self.collector,
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_metadata::creader::{CStore, LoadedMacro};
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypingMode};
|
||||
use rustc_span::symbol::kw;
|
||||
use rustc_span::{Symbol, sym};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
|
@ -613,7 +612,7 @@ fn generate_item_def_id_path(
|
|||
// No need to try to infer the actual parent item if it's not an associated item from the `impl`
|
||||
// block.
|
||||
if def_id != original_def_id && matches!(tcx.def_kind(def_id), DefKind::Impl { .. }) {
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
def_id = infcx
|
||||
.at(&ObligationCause::dummy(), tcx.param_env(def_id))
|
||||
.query_normalize(ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()))
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, Saf
|
|||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{
|
||||
self, Binder, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, Ty, TypeVisitableExt, TypeckResults,
|
||||
self, Binder, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, Ty, TypeVisitableExt,
|
||||
TypeckResults,
|
||||
};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::symbol::sym;
|
||||
|
|
@ -203,7 +204,7 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
|
|||
// 'cuz currently nothing changes after deleting this check.
|
||||
local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr)
|
||||
}) {
|
||||
match cx.tcx.infer_ctxt().build().err_ctxt().type_implements_fn_trait(
|
||||
match cx.tcx.infer_ctxt().build(cx.typing_mode()).err_ctxt().type_implements_fn_trait(
|
||||
cx.param_env,
|
||||
Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
|
||||
ty::PredicatePolarity::Positive,
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ fn check_needless_must_use(
|
|||
} else if attr.value_str().is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {
|
||||
// Ignore async functions unless Future::Output type is a must_use type
|
||||
if sig.header.is_async() {
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
|
||||
if let Some(future_ty) = infcx.err_ctxt().get_impl_future_output_ty(return_ty(cx, item_id))
|
||||
&& !is_must_use_ty(cx, future_ty)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
|
|||
if is_future {
|
||||
let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap();
|
||||
let span = decl.output.span();
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
let cause = traits::ObligationCause::misc(span, fn_def_id);
|
||||
ocx.register_bound(cause, cx.param_env, ret_ty, send_trait);
|
||||
|
|
|
|||
|
|
@ -420,15 +420,6 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
|
|||
|
||||
fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
|
||||
match ty.kind {
|
||||
TyKind::OpaqueDef(opaque, bounds) => {
|
||||
let len = self.lts.len();
|
||||
self.visit_opaque_ty(opaque);
|
||||
self.lts.truncate(len);
|
||||
self.lts.extend(bounds.iter().filter_map(|bound| match bound {
|
||||
GenericArg::Lifetime(&l) => Some(l),
|
||||
_ => None,
|
||||
}));
|
||||
},
|
||||
TyKind::BareFn(&BareFnTy { decl, .. }) => {
|
||||
let mut sub_visitor = RefVisitor::new(self.cx);
|
||||
sub_visitor.visit_fn_decl(decl);
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ use rustc_errors::Applicability;
|
|||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
|
||||
FnRetTy, GenericArg, GenericBound, ImplItem, Item, LifetimeName, Node, TraitRef, Ty, TyKind,
|
||||
FnRetTy, GenericBound, ImplItem, Item, Node, OpaqueTy, TraitRef, Ty, TyKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{Span, sym};
|
||||
|
|
@ -44,21 +46,22 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
|
|||
decl: &'tcx FnDecl<'_>,
|
||||
body: &'tcx Body<'_>,
|
||||
span: Span,
|
||||
def_id: LocalDefId,
|
||||
fn_def_id: LocalDefId,
|
||||
) {
|
||||
if let Some(header) = kind.header()
|
||||
&& !header.asyncness.is_async()
|
||||
// Check that this function returns `impl Future`
|
||||
&& let FnRetTy::Return(ret_ty) = decl.output
|
||||
&& let Some((trait_ref, output_lifetimes)) = future_trait_ref(cx, ret_ty)
|
||||
&& let TyKind::OpaqueDef(opaque) = ret_ty.kind
|
||||
&& let Some(trait_ref) = future_trait_ref(cx, opaque)
|
||||
&& let Some(output) = future_output_ty(trait_ref)
|
||||
&& captures_all_lifetimes(decl.inputs, &output_lifetimes)
|
||||
&& captures_all_lifetimes(cx, fn_def_id, opaque.def_id)
|
||||
// Check that the body of the function consists of one async block
|
||||
&& let ExprKind::Block(block, _) = body.value.kind
|
||||
&& block.stmts.is_empty()
|
||||
&& let Some(closure_body) = desugared_async_block(cx, block)
|
||||
&& let Node::Item(Item {vis_span, ..}) | Node::ImplItem(ImplItem {vis_span, ..}) =
|
||||
cx.tcx.hir_node_by_def_id(def_id)
|
||||
cx.tcx.hir_node_by_def_id(fn_def_id)
|
||||
{
|
||||
let header_span = span.with_hi(ret_ty.span.hi());
|
||||
|
||||
|
|
@ -101,12 +104,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
|
|||
}
|
||||
}
|
||||
|
||||
fn future_trait_ref<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
ty: &'tcx Ty<'tcx>,
|
||||
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
|
||||
if let TyKind::OpaqueDef(opaque, bounds) = ty.kind
|
||||
&& let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
|
||||
fn future_trait_ref<'tcx>(cx: &LateContext<'tcx>, opaque: &'tcx OpaqueTy<'tcx>) -> Option<&'tcx TraitRef<'tcx>> {
|
||||
if let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
|
||||
if let GenericBound::Trait(poly) = bound {
|
||||
Some(&poly.trait_ref)
|
||||
} else {
|
||||
|
|
@ -115,18 +114,7 @@ fn future_trait_ref<'tcx>(
|
|||
})
|
||||
&& trait_ref.trait_def_id() == cx.tcx.lang_items().future_trait()
|
||||
{
|
||||
let output_lifetimes = bounds
|
||||
.iter()
|
||||
.filter_map(|bound| {
|
||||
if let GenericArg::Lifetime(lt) = bound {
|
||||
Some(lt.res)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
return Some((trait_ref, output_lifetimes));
|
||||
return Some(trait_ref);
|
||||
}
|
||||
|
||||
None
|
||||
|
|
@ -145,27 +133,35 @@ fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'t
|
|||
None
|
||||
}
|
||||
|
||||
fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName]) -> bool {
|
||||
let input_lifetimes: Vec<LifetimeName> = inputs
|
||||
.iter()
|
||||
.filter_map(|ty| {
|
||||
if let TyKind::Ref(lt, _) = ty.kind {
|
||||
Some(lt.res)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
fn captures_all_lifetimes(cx: &LateContext<'_>, fn_def_id: LocalDefId, opaque_def_id: LocalDefId) -> bool {
|
||||
let early_input_params = ty::GenericArgs::identity_for_item(cx.tcx, fn_def_id);
|
||||
let late_input_params = cx.tcx.late_bound_vars(cx.tcx.local_def_id_to_hir_id(fn_def_id));
|
||||
|
||||
// The lint should trigger in one of these cases:
|
||||
// - There are no input lifetimes
|
||||
// - There's only one output lifetime bound using `+ '_`
|
||||
// - All input lifetimes are explicitly bound to the output
|
||||
input_lifetimes.is_empty()
|
||||
|| (output_lifetimes.len() == 1 && matches!(output_lifetimes[0], LifetimeName::Infer))
|
||||
|| input_lifetimes
|
||||
.iter()
|
||||
.all(|in_lt| output_lifetimes.iter().any(|out_lt| in_lt == out_lt))
|
||||
let num_early_lifetimes = early_input_params
|
||||
.iter()
|
||||
.filter(|param| param.as_region().is_some())
|
||||
.count();
|
||||
let num_late_lifetimes = late_input_params
|
||||
.iter()
|
||||
.filter(|param_kind| matches!(param_kind, ty::BoundVariableKind::Region(_)))
|
||||
.count();
|
||||
|
||||
// There is no lifetime, so they are all captured.
|
||||
if num_early_lifetimes == 0 && num_late_lifetimes == 0 {
|
||||
return true;
|
||||
}
|
||||
|
||||
// By construction, each captured lifetime only appears once in `opaque_captured_lifetimes`.
|
||||
let num_captured_lifetimes = cx
|
||||
.tcx
|
||||
.opaque_captured_lifetimes(opaque_def_id)
|
||||
.iter()
|
||||
.filter(|&(lifetime, _)| match *lifetime {
|
||||
ResolvedArg::EarlyBound(_) | ResolvedArg::LateBound(ty::INNERMOST, _, _) => true,
|
||||
_ => false,
|
||||
})
|
||||
.count();
|
||||
num_captured_lifetimes == num_early_lifetimes + num_late_lifetimes
|
||||
}
|
||||
|
||||
fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> {
|
||||
|
|
|
|||
|
|
@ -568,7 +568,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
|
|||
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
|
||||
!cx.tcx
|
||||
.infer_ctxt()
|
||||
.build()
|
||||
.build(cx.typing_mode())
|
||||
.predicate_must_hold_modulo_regions(&obligation)
|
||||
}) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ fn needless_borrow_count<'tcx>(
|
|||
|
||||
let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty[..]);
|
||||
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
|
||||
infcx.predicate_must_hold_modulo_regions(&obligation)
|
||||
})
|
||||
};
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ impl NoEffect {
|
|||
// Remove `impl Future<Output = T>` to get `T`
|
||||
if cx.tcx.ty_is_opaque_future(ret_ty)
|
||||
&& let Some(true_ret_ty) =
|
||||
cx.tcx.infer_ctxt().build().err_ctxt().get_impl_future_output_ty(ret_ty)
|
||||
cx.tcx.infer_ctxt().build(cx.typing_mode()).err_ctxt().get_impl_future_output_ty(ret_ty)
|
||||
{
|
||||
ret_ty = true_ret_ty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -695,7 +695,7 @@ fn matches_preds<'tcx>(
|
|||
ty: Ty<'tcx>,
|
||||
preds: &'tcx [ty::PolyExistentialPredicate<'tcx>],
|
||||
) -> bool {
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
|
||||
preds
|
||||
.iter()
|
||||
.all(|&p| match cx.tcx.instantiate_bound_regions_with_erased(p) {
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ fn into_iter_bound<'tcx>(
|
|||
if !cx
|
||||
.tcx
|
||||
.infer_ctxt()
|
||||
.build()
|
||||
.build(cx.typing_mode())
|
||||
.predicate_must_hold_modulo_regions(&obligation)
|
||||
{
|
||||
return None;
|
||||
|
|
|
|||
|
|
@ -1231,16 +1231,13 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
}
|
||||
},
|
||||
TyKind::Path(ref qpath) => self.hash_qpath(qpath),
|
||||
TyKind::OpaqueDef(_, arg_list) => {
|
||||
self.hash_generic_args(arg_list);
|
||||
},
|
||||
TyKind::TraitObject(_, lifetime, _) => {
|
||||
self.hash_lifetime(lifetime);
|
||||
},
|
||||
TyKind::Typeof(anon_const) => {
|
||||
self.hash_body(anon_const.body);
|
||||
},
|
||||
TyKind::Err(_) | TyKind::Infer | TyKind::Never | TyKind::InferDelegation(..) | TyKind::AnonAdt(_) => {},
|
||||
TyKind::Err(_) | TyKind::Infer | TyKind::Never | TyKind::InferDelegation(..) | TyKind::OpaqueDef(_) | TyKind::AnonAdt(_) => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -185,9 +185,7 @@ impl<'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {
|
|||
vis.into_map(cx)
|
||||
};
|
||||
let maybe_storage_live_result = MaybeStorageLive::new(Cow::Owned(BitSet::new_empty(mir.local_decls.len())))
|
||||
.into_engine(cx.tcx, mir)
|
||||
.pass_name("redundant_clone")
|
||||
.iterate_to_fixpoint()
|
||||
.iterate_to_fixpoint(cx.tcx, mir, Some("redundant_clone"))
|
||||
.into_results_cursor(mir);
|
||||
let mut vis = PossibleBorrowerVisitor::new(cx, mir, possible_origin);
|
||||
vis.visit_body(mir);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use rustc_middle::mir::{
|
|||
};
|
||||
use rustc_middle::traits::{BuiltinImplSource, ImplSource, ObligationCause};
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt, TypingMode};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext};
|
||||
|
|
@ -420,7 +420,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
|
|||
TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]),
|
||||
);
|
||||
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(obligation.param_env));
|
||||
let mut selcx = SelectionContext::new(&infcx);
|
||||
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use rustc_middle::ty::layout::ValidityRequirement;
|
|||
use rustc_middle::ty::{
|
||||
self, AdtDef, AliasTy, AssocItem, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind,
|
||||
GenericArgsRef, GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable,
|
||||
TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
|
||||
TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, TypingMode,
|
||||
};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
|
||||
|
|
@ -268,7 +268,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
|
|||
return false;
|
||||
}
|
||||
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env));
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|arg| arg.into().unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into()))
|
||||
|
|
@ -362,7 +362,7 @@ fn is_normalizable_helper<'tcx>(
|
|||
}
|
||||
// prevent recursive loops, false-negative is better than endless loop leading to stack overflow
|
||||
cache.insert(ty, false);
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
let infcx = cx.tcx.infer_ctxt().build(TypingMode::from_param_env(param_env));
|
||||
let cause = ObligationCause::dummy();
|
||||
let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() {
|
||||
match ty.kind() {
|
||||
|
|
@ -1268,7 +1268,7 @@ pub fn make_normalized_projection_with_regions<'tcx>(
|
|||
let cause = ObligationCause::dummy();
|
||||
match tcx
|
||||
.infer_ctxt()
|
||||
.build()
|
||||
.build(TypingMode::from_param_env(param_env))
|
||||
.at(&cause, param_env)
|
||||
.query_normalize(Ty::new_projection_from_args(tcx, ty.def_id, ty.args))
|
||||
{
|
||||
|
|
@ -1284,7 +1284,7 @@ pub fn make_normalized_projection_with_regions<'tcx>(
|
|||
|
||||
pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let cause = ObligationCause::dummy();
|
||||
match tcx.infer_ctxt().build().at(&cause, param_env).query_normalize(ty) {
|
||||
match tcx.infer_ctxt().build(TypingMode::from_param_env(param_env)).at(&cause, param_env).query_normalize(ty) {
|
||||
Ok(ty) => ty.value,
|
||||
Err(_) => ty,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ error: the following explicit lifetimes could be elided: 'a
|
|||
--> tests/ui/issue_4266.rs:10:21
|
||||
|
|
||||
LL | async fn one_to_one<'a>(s: &'a str) -> &'a str {
|
||||
| ^^ ^^
|
||||
| ^^ ^^ ^^
|
||||
|
||||
error: methods called `new` usually take no `self`
|
||||
--> tests/ui/issue_4266.rs:31:22
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ build_helper = { path = "../build_helper" }
|
|||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
|
||||
regex = "1.0"
|
||||
semver = { version = "1.0.23", features = ["serde"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
rustfix = "0.8.1"
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use std::sync::OnceLock;
|
|||
use std::{fmt, iter};
|
||||
|
||||
use build_helper::git::GitConfig;
|
||||
use semver::Version;
|
||||
use serde::de::{Deserialize, Deserializer, Error as _};
|
||||
use test::{ColorConfig, OutputFormat};
|
||||
|
||||
|
|
@ -298,7 +299,7 @@ pub struct Config {
|
|||
pub lldb_version: Option<u32>,
|
||||
|
||||
/// Version of LLVM
|
||||
pub llvm_version: Option<u32>,
|
||||
pub llvm_version: Option<Version>,
|
||||
|
||||
/// Is LLVM a system LLVM
|
||||
pub system_llvm: bool,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use std::io::prelude::*;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use semver::Version;
|
||||
use tracing::*;
|
||||
|
||||
use crate::common::{Config, Debugger, FailMode, Mode, PassMode};
|
||||
|
|
@ -1113,26 +1114,39 @@ fn parse_normalize_rule(header: &str) -> Option<(String, String)> {
|
|||
Some((regex, replacement))
|
||||
}
|
||||
|
||||
pub fn extract_llvm_version(version: &str) -> Option<u32> {
|
||||
let pat = |c: char| !c.is_ascii_digit() && c != '.';
|
||||
let version_without_suffix = match version.find(pat) {
|
||||
Some(pos) => &version[..pos],
|
||||
/// Given an llvm version string that looks like `1.2.3-rc1`, extract as semver. Note that this
|
||||
/// accepts more than just strict `semver` syntax (as in `major.minor.patch`); this permits omitting
|
||||
/// minor and patch version components so users can write e.g. `//@ min-llvm-version: 19` instead of
|
||||
/// having to write `//@ min-llvm-version: 19.0.0`.
|
||||
///
|
||||
/// Currently panics if the input string is malformed, though we really should not use panic as an
|
||||
/// error handling strategy.
|
||||
///
|
||||
/// FIXME(jieyouxu): improve error handling
|
||||
pub fn extract_llvm_version(version: &str) -> Version {
|
||||
// The version substring we're interested in usually looks like the `1.2.3`, without any of the
|
||||
// fancy suffix like `-rc1` or `meow`.
|
||||
let version = version.trim();
|
||||
let uninterested = |c: char| !c.is_ascii_digit() && c != '.';
|
||||
let version_without_suffix = match version.split_once(uninterested) {
|
||||
Some((prefix, _suffix)) => prefix,
|
||||
None => version,
|
||||
};
|
||||
let components: Vec<u32> = version_without_suffix
|
||||
|
||||
let components: Vec<u64> = version_without_suffix
|
||||
.split('.')
|
||||
.map(|s| s.parse().expect("Malformed version component"))
|
||||
.map(|s| s.parse().expect("llvm version component should consist of only digits"))
|
||||
.collect();
|
||||
let version = match *components {
|
||||
[a] => a * 10_000,
|
||||
[a, b] => a * 10_000 + b * 100,
|
||||
[a, b, c] => a * 10_000 + b * 100 + c,
|
||||
_ => panic!("Malformed version"),
|
||||
};
|
||||
Some(version)
|
||||
|
||||
match &components[..] {
|
||||
[major] => Version::new(*major, 0, 0),
|
||||
[major, minor] => Version::new(*major, *minor, 0),
|
||||
[major, minor, patch] => Version::new(*major, *minor, *patch),
|
||||
_ => panic!("malformed llvm version string, expected only 1-3 components: {version}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_llvm_version_from_binary(binary_path: &str) -> Option<u32> {
|
||||
pub fn extract_llvm_version_from_binary(binary_path: &str) -> Option<Version> {
|
||||
let output = Command::new(binary_path).arg("--version").output().ok()?;
|
||||
if !output.status.success() {
|
||||
return None;
|
||||
|
|
@ -1140,7 +1154,7 @@ pub fn extract_llvm_version_from_binary(binary_path: &str) -> Option<u32> {
|
|||
let version = String::from_utf8(output.stdout).ok()?;
|
||||
for line in version.lines() {
|
||||
if let Some(version) = line.split("LLVM version ").nth(1) {
|
||||
return extract_llvm_version(version);
|
||||
return Some(extract_llvm_version(version));
|
||||
}
|
||||
}
|
||||
None
|
||||
|
|
@ -1247,15 +1261,17 @@ pub fn llvm_has_libzstd(config: &Config) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
/// Takes a directive of the form `"<version1> [- <version2>]"`,
|
||||
/// returns the numeric representation of `<version1>` and `<version2>` as
|
||||
/// tuple: `(<version1> as u32, <version2> as u32)`.
|
||||
/// Takes a directive of the form `"<version1> [- <version2>]"`, returns the numeric representation
|
||||
/// of `<version1>` and `<version2>` as tuple: `(<version1>, <version2>)`.
|
||||
///
|
||||
/// If the `<version2>` part is omitted, the second component of the tuple
|
||||
/// is the same as `<version1>`.
|
||||
fn extract_version_range<F>(line: &str, parse: F) -> Option<(u32, u32)>
|
||||
/// If the `<version2>` part is omitted, the second component of the tuple is the same as
|
||||
/// `<version1>`.
|
||||
fn extract_version_range<'a, F, VersionTy: Clone>(
|
||||
line: &'a str,
|
||||
parse: F,
|
||||
) -> Option<(VersionTy, VersionTy)>
|
||||
where
|
||||
F: Fn(&str) -> Option<u32>,
|
||||
F: Fn(&'a str) -> Option<VersionTy>,
|
||||
{
|
||||
let mut splits = line.splitn(2, "- ").map(str::trim);
|
||||
let min = splits.next().unwrap();
|
||||
|
|
@ -1273,7 +1289,7 @@ where
|
|||
let max = match max {
|
||||
Some("") => return None,
|
||||
Some(max) => parse(max)?,
|
||||
_ => min,
|
||||
_ => min.clone(),
|
||||
};
|
||||
|
||||
Some((min, max))
|
||||
|
|
@ -1489,43 +1505,55 @@ fn ignore_llvm(config: &Config, line: &str) -> IgnoreDecision {
|
|||
};
|
||||
}
|
||||
}
|
||||
if let Some(actual_version) = config.llvm_version {
|
||||
if let Some(rest) = line.strip_prefix("min-llvm-version:").map(str::trim) {
|
||||
let min_version = extract_llvm_version(rest).unwrap();
|
||||
// Ignore if actual version is smaller the minimum required
|
||||
// version
|
||||
if actual_version < min_version {
|
||||
if let Some(actual_version) = &config.llvm_version {
|
||||
// Note that these `min` versions will check for not just major versions.
|
||||
|
||||
if let Some(version_string) = config.parse_name_value_directive(line, "min-llvm-version") {
|
||||
let min_version = extract_llvm_version(&version_string);
|
||||
// Ignore if actual version is smaller than the minimum required version.
|
||||
if *actual_version < min_version {
|
||||
return IgnoreDecision::Ignore {
|
||||
reason: format!("ignored when the LLVM version is older than {rest}"),
|
||||
reason: format!(
|
||||
"ignored when the LLVM version {actual_version} is older than {min_version}"
|
||||
),
|
||||
};
|
||||
}
|
||||
} else if let Some(rest) = line.strip_prefix("min-system-llvm-version:").map(str::trim) {
|
||||
let min_version = extract_llvm_version(rest).unwrap();
|
||||
} else if let Some(version_string) =
|
||||
config.parse_name_value_directive(line, "min-system-llvm-version")
|
||||
{
|
||||
let min_version = extract_llvm_version(&version_string);
|
||||
// Ignore if using system LLVM and actual version
|
||||
// is smaller the minimum required version
|
||||
if config.system_llvm && actual_version < min_version {
|
||||
if config.system_llvm && *actual_version < min_version {
|
||||
return IgnoreDecision::Ignore {
|
||||
reason: format!("ignored when the system LLVM version is older than {rest}"),
|
||||
reason: format!(
|
||||
"ignored when the system LLVM version {actual_version} is older than {min_version}"
|
||||
),
|
||||
};
|
||||
}
|
||||
} else if let Some(rest) = line.strip_prefix("ignore-llvm-version:").map(str::trim) {
|
||||
} else if let Some(version_range) =
|
||||
config.parse_name_value_directive(line, "ignore-llvm-version")
|
||||
{
|
||||
// Syntax is: "ignore-llvm-version: <version1> [- <version2>]"
|
||||
let (v_min, v_max) =
|
||||
extract_version_range(rest, extract_llvm_version).unwrap_or_else(|| {
|
||||
panic!("couldn't parse version range: {:?}", rest);
|
||||
});
|
||||
extract_version_range(&version_range, |s| Some(extract_llvm_version(s)))
|
||||
.unwrap_or_else(|| {
|
||||
panic!("couldn't parse version range: \"{version_range}\"");
|
||||
});
|
||||
if v_max < v_min {
|
||||
panic!("Malformed LLVM version range: max < min")
|
||||
panic!("malformed LLVM version range where {v_max} < {v_min}")
|
||||
}
|
||||
// Ignore if version lies inside of range.
|
||||
if actual_version >= v_min && actual_version <= v_max {
|
||||
if *actual_version >= v_min && *actual_version <= v_max {
|
||||
if v_min == v_max {
|
||||
return IgnoreDecision::Ignore {
|
||||
reason: format!("ignored when the LLVM version is {rest}"),
|
||||
reason: format!("ignored when the LLVM version is {actual_version}"),
|
||||
};
|
||||
} else {
|
||||
return IgnoreDecision::Ignore {
|
||||
reason: format!("ignored when the LLVM version is between {rest}"),
|
||||
reason: format!(
|
||||
"ignored when the LLVM version is between {v_min} and {v_max}"
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
|
||||
use super::iter_header;
|
||||
use semver::Version;
|
||||
|
||||
use super::{
|
||||
EarlyProps, HeadersCache, extract_llvm_version, extract_version_range, iter_header,
|
||||
parse_normalize_rule,
|
||||
};
|
||||
use crate::common::{Config, Debugger, Mode};
|
||||
use crate::header::{EarlyProps, HeadersCache, parse_normalize_rule};
|
||||
|
||||
fn make_test_description<R: Read>(
|
||||
config: &Config,
|
||||
|
|
@ -408,18 +412,66 @@ fn channel() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_version_range() {
|
||||
use super::{extract_llvm_version, extract_version_range};
|
||||
fn test_extract_llvm_version() {
|
||||
// Note: officially, semver *requires* that versions at the minimum have all three
|
||||
// `major.minor.patch` numbers, though for test-writer's convenience we allow omitting the minor
|
||||
// and patch numbers (which will be stubbed out as 0).
|
||||
assert_eq!(extract_llvm_version("0"), Version::new(0, 0, 0));
|
||||
assert_eq!(extract_llvm_version("0.0"), Version::new(0, 0, 0));
|
||||
assert_eq!(extract_llvm_version("0.0.0"), Version::new(0, 0, 0));
|
||||
assert_eq!(extract_llvm_version("1"), Version::new(1, 0, 0));
|
||||
assert_eq!(extract_llvm_version("1.2"), Version::new(1, 2, 0));
|
||||
assert_eq!(extract_llvm_version("1.2.3"), Version::new(1, 2, 3));
|
||||
assert_eq!(extract_llvm_version("4.5.6git"), Version::new(4, 5, 6));
|
||||
assert_eq!(extract_llvm_version("4.5.6-rc1"), Version::new(4, 5, 6));
|
||||
assert_eq!(extract_llvm_version("123.456.789-rc1"), Version::new(123, 456, 789));
|
||||
assert_eq!(extract_llvm_version("8.1.2-rust"), Version::new(8, 1, 2));
|
||||
assert_eq!(extract_llvm_version("9.0.1-rust-1.43.0-dev"), Version::new(9, 0, 1));
|
||||
assert_eq!(extract_llvm_version("9.3.1-rust-1.43.0-dev"), Version::new(9, 3, 1));
|
||||
assert_eq!(extract_llvm_version("10.0.0-rust"), Version::new(10, 0, 0));
|
||||
assert_eq!(extract_llvm_version("11.1.0"), Version::new(11, 1, 0));
|
||||
assert_eq!(extract_llvm_version("12.0.0libcxx"), Version::new(12, 0, 0));
|
||||
assert_eq!(extract_llvm_version("12.0.0-rc3"), Version::new(12, 0, 0));
|
||||
assert_eq!(extract_llvm_version("13.0.0git"), Version::new(13, 0, 0));
|
||||
}
|
||||
|
||||
assert_eq!(extract_version_range("1.2.3 - 4.5.6", extract_llvm_version), Some((10203, 40506)));
|
||||
assert_eq!(extract_version_range("0 - 4.5.6", extract_llvm_version), Some((0, 40506)));
|
||||
assert_eq!(extract_version_range("1.2.3 -", extract_llvm_version), None);
|
||||
assert_eq!(extract_version_range("1.2.3 - ", extract_llvm_version), None);
|
||||
assert_eq!(extract_version_range("- 4.5.6", extract_llvm_version), None);
|
||||
assert_eq!(extract_version_range("-", extract_llvm_version), None);
|
||||
assert_eq!(extract_version_range(" - 4.5.6", extract_llvm_version), None);
|
||||
assert_eq!(extract_version_range(" - 4.5.6", extract_llvm_version), None);
|
||||
assert_eq!(extract_version_range("0 -", extract_llvm_version), None);
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_llvm_version_invalid_components() {
|
||||
extract_llvm_version("4.x.6");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_llvm_version_invalid_prefix() {
|
||||
extract_llvm_version("meow4.5.6");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_llvm_version_too_many_components() {
|
||||
extract_llvm_version("4.5.6.7");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_version_range() {
|
||||
let wrapped_extract = |s: &str| Some(extract_llvm_version(s));
|
||||
|
||||
assert_eq!(
|
||||
extract_version_range("1.2.3 - 4.5.6", wrapped_extract),
|
||||
Some((Version::new(1, 2, 3), Version::new(4, 5, 6)))
|
||||
);
|
||||
assert_eq!(
|
||||
extract_version_range("0 - 4.5.6", wrapped_extract),
|
||||
Some((Version::new(0, 0, 0), Version::new(4, 5, 6)))
|
||||
);
|
||||
assert_eq!(extract_version_range("1.2.3 -", wrapped_extract), None);
|
||||
assert_eq!(extract_version_range("1.2.3 - ", wrapped_extract), None);
|
||||
assert_eq!(extract_version_range("- 4.5.6", wrapped_extract), None);
|
||||
assert_eq!(extract_version_range("-", wrapped_extract), None);
|
||||
assert_eq!(extract_version_range(" - 4.5.6", wrapped_extract), None);
|
||||
assert_eq!(extract_version_range(" - 4.5.6", wrapped_extract), None);
|
||||
assert_eq!(extract_version_range("0 -", wrapped_extract), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
Some(x) => panic!("argument for --color must be auto, always, or never, but found `{}`", x),
|
||||
};
|
||||
let llvm_version =
|
||||
matches.opt_str("llvm-version").as_deref().and_then(header::extract_llvm_version).or_else(
|
||||
matches.opt_str("llvm-version").as_deref().map(header::extract_llvm_version).or_else(
|
||||
|| header::extract_llvm_version_from_binary(&matches.opt_str("llvm-filecheck")?),
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use std::ffi::OsString;
|
||||
|
||||
use crate::debuggers::{extract_gdb_version, extract_lldb_version};
|
||||
use crate::header::extract_llvm_version;
|
||||
use crate::is_test;
|
||||
|
||||
#[test]
|
||||
|
|
@ -67,15 +66,3 @@ fn is_test_test() {
|
|||
assert!(!is_test(&OsString::from("#a_dog_gif")));
|
||||
assert!(!is_test(&OsString::from("~a_temp_file")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_llvm_version() {
|
||||
assert_eq!(extract_llvm_version("8.1.2-rust"), Some(80102));
|
||||
assert_eq!(extract_llvm_version("9.0.1-rust-1.43.0-dev"), Some(90001));
|
||||
assert_eq!(extract_llvm_version("9.3.1-rust-1.43.0-dev"), Some(90301));
|
||||
assert_eq!(extract_llvm_version("10.0.0-rust"), Some(100000));
|
||||
assert_eq!(extract_llvm_version("11.1.0"), Some(110100));
|
||||
assert_eq!(extract_llvm_version("12.0.0libcxx"), Some(120000));
|
||||
assert_eq!(extract_llvm_version("12.0.0-rc3"), Some(120000));
|
||||
assert_eq!(extract_llvm_version("13.0.0git"), Some(130000));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ use std::cell::RefCell;
|
|||
use std::fmt::Write;
|
||||
use std::{cmp, mem};
|
||||
|
||||
use rustc_abi::{BackendRepr, Size};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::mir::{Mutability, RetagKind};
|
||||
use rustc_middle::ty::layout::HasParamEnv;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_target::abi::{Abi, Size};
|
||||
|
||||
use self::diagnostics::{RetagCause, RetagInfo};
|
||||
pub use self::item::{Item, Permission};
|
||||
|
|
@ -972,7 +972,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
RetagFields::OnlyScalar => {
|
||||
// Matching `ArgAbi::new` at the time of writing, only fields of
|
||||
// `Scalar` and `ScalarPair` ABI are considered.
|
||||
matches!(place.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..))
|
||||
matches!(
|
||||
place.layout.backend_repr,
|
||||
BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..)
|
||||
)
|
||||
}
|
||||
};
|
||||
if recurse {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use rustc_abi::{BackendRepr, Size};
|
||||
use rustc_middle::mir::{Mutability, RetagKind};
|
||||
use rustc_middle::ty::layout::HasParamEnv;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_target::abi::{Abi, Size};
|
||||
|
||||
use crate::borrow_tracker::{GlobalState, GlobalStateInner, ProtectorKind};
|
||||
use crate::concurrency::data_race::NaReadType;
|
||||
|
|
@ -495,7 +495,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
RetagFields::OnlyScalar => {
|
||||
// Matching `ArgAbi::new` at the time of writing, only fields of
|
||||
// `Scalar` and `ScalarPair` ABI are considered.
|
||||
matches!(place.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..))
|
||||
matches!(
|
||||
place.layout.backend_repr,
|
||||
BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..)
|
||||
)
|
||||
}
|
||||
};
|
||||
if recurse {
|
||||
|
|
|
|||
|
|
@ -349,8 +349,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
i: impl Into<i128>,
|
||||
dest: &impl Writeable<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
assert!(dest.layout().abi.is_scalar(), "write_int on non-scalar type {}", dest.layout().ty);
|
||||
let val = if dest.layout().abi.is_signed() {
|
||||
assert!(
|
||||
dest.layout().backend_repr.is_scalar(),
|
||||
"write_int on non-scalar type {}",
|
||||
dest.layout().ty
|
||||
);
|
||||
let val = if dest.layout().backend_repr.is_signed() {
|
||||
Scalar::from_int(i, dest.layout().size)
|
||||
} else {
|
||||
// `unwrap` can only fail here if `i` is negative
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ extern crate either;
|
|||
extern crate tracing;
|
||||
|
||||
// The rustc crates we need
|
||||
extern crate rustc_abi;
|
||||
extern crate rustc_apfloat;
|
||||
extern crate rustc_ast;
|
||||
extern crate rustc_attr;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
interp_ok(match bin_op {
|
||||
Eq | Ne | Lt | Le | Gt | Ge => {
|
||||
assert_eq!(left.layout.abi, right.layout.abi); // types can differ, e.g. fn ptrs with different `for`
|
||||
assert_eq!(left.layout.backend_repr, right.layout.backend_repr); // types can differ, e.g. fn ptrs with different `for`
|
||||
let size = this.pointer_size();
|
||||
// Just compare the bits. ScalarPairs are compared lexicographically.
|
||||
// We thus always compare pairs and simply fill scalars up with 0.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use libffi::high::call as ffi;
|
|||
use libffi::low::CodePtr;
|
||||
use rustc_middle::ty::{self as ty, IntTy, UintTy};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::abi::{Abi, HasDataLayout};
|
||||
use rustc_abi::{BackendRepr, HasDataLayout};
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Get the function arguments, and convert them to `libffi`-compatible form.
|
||||
let mut libffi_args = Vec::<CArg>::with_capacity(args.len());
|
||||
for arg in args.iter() {
|
||||
if !matches!(arg.layout.abi, Abi::Scalar(_)) {
|
||||
if !matches!(arg.layout.backend_repr, BackendRepr::Scalar(_)) {
|
||||
throw_unsup_format!("only scalar argument types are support for native calls")
|
||||
}
|
||||
libffi_args.push(imm_to_carg(this.read_immediate(arg)?, this)?);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use base_db::ra_salsa::Cycle;
|
|||
use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
|
||||
use hir_def::{
|
||||
layout::{
|
||||
Abi, FieldsShape, Float, Integer, LayoutCalculator, LayoutCalculatorError, LayoutData,
|
||||
BackendRepr, FieldsShape, Float, Integer, LayoutCalculator, LayoutCalculatorError, LayoutData,
|
||||
Primitive, ReprOptions, Scalar, Size, StructKind, TargetDataLayout, WrappingRange,
|
||||
},
|
||||
LocalFieldId, StructId,
|
||||
|
|
@ -168,7 +168,7 @@ fn layout_of_simd_ty(
|
|||
|
||||
// Compute the ABI of the element type:
|
||||
let e_ly = db.layout_of_ty(e_ty, env)?;
|
||||
let Abi::Scalar(e_abi) = e_ly.abi else {
|
||||
let BackendRepr::Scalar(e_abi) = e_ly.backend_repr else {
|
||||
return Err(LayoutError::Unknown);
|
||||
};
|
||||
|
||||
|
|
@ -190,7 +190,7 @@ fn layout_of_simd_ty(
|
|||
Ok(Arc::new(Layout {
|
||||
variants: Variants::Single { index: struct_variant_idx() },
|
||||
fields,
|
||||
abi: Abi::Vector { element: e_abi, count: e_len },
|
||||
backend_repr: BackendRepr::Vector { element: e_abi, count: e_len },
|
||||
largest_niche: e_ly.largest_niche,
|
||||
size,
|
||||
align,
|
||||
|
|
@ -294,10 +294,10 @@ pub fn layout_of_ty_query(
|
|||
.checked_mul(count, dl)
|
||||
.ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
|
||||
|
||||
let abi = if count != 0 && matches!(element.abi, Abi::Uninhabited) {
|
||||
Abi::Uninhabited
|
||||
let backend_repr = if count != 0 && matches!(element.backend_repr, BackendRepr::Uninhabited) {
|
||||
BackendRepr::Uninhabited
|
||||
} else {
|
||||
Abi::Aggregate { sized: true }
|
||||
BackendRepr::Memory { sized: true }
|
||||
};
|
||||
|
||||
let largest_niche = if count != 0 { element.largest_niche } else { None };
|
||||
|
|
@ -305,7 +305,7 @@ pub fn layout_of_ty_query(
|
|||
Layout {
|
||||
variants: Variants::Single { index: struct_variant_idx() },
|
||||
fields: FieldsShape::Array { stride: element.size, count },
|
||||
abi,
|
||||
backend_repr,
|
||||
largest_niche,
|
||||
align: element.align,
|
||||
size,
|
||||
|
|
@ -318,7 +318,7 @@ pub fn layout_of_ty_query(
|
|||
Layout {
|
||||
variants: Variants::Single { index: struct_variant_idx() },
|
||||
fields: FieldsShape::Array { stride: element.size, count: 0 },
|
||||
abi: Abi::Aggregate { sized: false },
|
||||
backend_repr: BackendRepr::Memory { sized: false },
|
||||
largest_niche: None,
|
||||
align: element.align,
|
||||
size: Size::ZERO,
|
||||
|
|
@ -329,7 +329,7 @@ pub fn layout_of_ty_query(
|
|||
TyKind::Str => Layout {
|
||||
variants: Variants::Single { index: struct_variant_idx() },
|
||||
fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
|
||||
abi: Abi::Aggregate { sized: false },
|
||||
backend_repr: BackendRepr::Memory { sized: false },
|
||||
largest_niche: None,
|
||||
align: dl.i8_align,
|
||||
size: Size::ZERO,
|
||||
|
|
@ -379,8 +379,8 @@ pub fn layout_of_ty_query(
|
|||
TyKind::Never => cx.calc.layout_of_never_type(),
|
||||
TyKind::Dyn(_) | TyKind::Foreign(_) => {
|
||||
let mut unit = layout_of_unit(&cx)?;
|
||||
match &mut unit.abi {
|
||||
Abi::Aggregate { sized } => *sized = false,
|
||||
match &mut unit.backend_repr {
|
||||
BackendRepr::Memory { sized } => *sized = false,
|
||||
_ => return Err(LayoutError::Unknown),
|
||||
}
|
||||
unit
|
||||
|
|
|
|||
|
|
@ -4102,7 +4102,6 @@ ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs
|
|||
ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs
|
||||
ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs
|
||||
ui/type-alias-impl-trait/issue-57611-trait-alias.rs
|
||||
ui/type-alias-impl-trait/issue-57700.rs
|
||||
ui/type-alias-impl-trait/issue-57807-associated-type.rs
|
||||
ui/type-alias-impl-trait/issue-57961.rs
|
||||
ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue