Auto merge of #110752 - matthiaskrgr:rollup-959s77u, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #110255 (Suggest using integration tests for test crate using own proc-macro) - #110514 (Remove `find_map_relevant_impl`) - #110566 (Don't create projection ty for const projection) - #110637 (Group some sections of our logs in github actions) - #110706 (Add `intrinsics::transmute_unchecked`) - #110714 (Normalize types and consts in MIR opts.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
64bcb32651
38 changed files with 523 additions and 409 deletions
|
|
@ -198,7 +198,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
|||
| sym::assert_zero_valid
|
||||
| sym::assert_mem_uninitialized_valid => (1, Vec::new(), tcx.mk_unit()),
|
||||
sym::forget => (1, vec![param(0)], tcx.mk_unit()),
|
||||
sym::transmute => (2, vec![param(0)], param(1)),
|
||||
sym::transmute | sym::transmute_unchecked => (2, vec![param(0)], param(1)),
|
||||
sym::prefetch_read_data
|
||||
| sym::prefetch_write_data
|
||||
| sym::prefetch_read_instruction
|
||||
|
|
|
|||
|
|
@ -139,11 +139,38 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
treat_projections: TreatProjections,
|
||||
mut f: impl FnMut(DefId),
|
||||
) {
|
||||
let _: Option<()> =
|
||||
self.find_map_relevant_impl(trait_def_id, self_ty, treat_projections, |did| {
|
||||
f(did);
|
||||
None
|
||||
});
|
||||
// FIXME: This depends on the set of all impls for the trait. That is
|
||||
// unfortunate wrt. incremental compilation.
|
||||
//
|
||||
// If we want to be faster, we could have separate queries for
|
||||
// blanket and non-blanket impls, and compare them separately.
|
||||
let impls = self.trait_impls_of(trait_def_id);
|
||||
|
||||
for &impl_def_id in impls.blanket_impls.iter() {
|
||||
f(impl_def_id);
|
||||
}
|
||||
|
||||
// Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using
|
||||
// `TreatParams::AsCandidateKey` while actually adding them.
|
||||
let treat_params = match treat_projections {
|
||||
TreatProjections::NextSolverLookup => TreatParams::NextSolverLookup,
|
||||
TreatProjections::ForLookup => TreatParams::ForLookup,
|
||||
};
|
||||
// This way, when searching for some impl for `T: Trait`, we do not look at any impls
|
||||
// whose outer level is not a parameter or projection. Especially for things like
|
||||
// `T: Clone` this is incredibly useful as we would otherwise look at all the impls
|
||||
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
|
||||
if let Some(simp) = fast_reject::simplify_type(self, self_ty, treat_params) {
|
||||
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
|
||||
for &impl_def_id in impls {
|
||||
f(impl_def_id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for &impl_def_id in impls.non_blanket_impls.values().flatten() {
|
||||
f(impl_def_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `trait_def_id` MUST BE the `DefId` of a trait.
|
||||
|
|
@ -162,59 +189,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
[].iter().copied()
|
||||
}
|
||||
|
||||
/// Applies function to every impl that could possibly match the self type `self_ty` and returns
|
||||
/// the first non-none value.
|
||||
///
|
||||
/// `trait_def_id` MUST BE the `DefId` of a trait.
|
||||
pub fn find_map_relevant_impl<T>(
|
||||
self,
|
||||
trait_def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
treat_projections: TreatProjections,
|
||||
mut f: impl FnMut(DefId) -> Option<T>,
|
||||
) -> Option<T> {
|
||||
// FIXME: This depends on the set of all impls for the trait. That is
|
||||
// unfortunate wrt. incremental compilation.
|
||||
//
|
||||
// If we want to be faster, we could have separate queries for
|
||||
// blanket and non-blanket impls, and compare them separately.
|
||||
let impls = self.trait_impls_of(trait_def_id);
|
||||
|
||||
for &impl_def_id in impls.blanket_impls.iter() {
|
||||
if let result @ Some(_) = f(impl_def_id) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using
|
||||
// `TreatParams::AsCandidateKey` while actually adding them.
|
||||
let treat_params = match treat_projections {
|
||||
TreatProjections::NextSolverLookup => TreatParams::NextSolverLookup,
|
||||
TreatProjections::ForLookup => TreatParams::ForLookup,
|
||||
};
|
||||
// This way, when searching for some impl for `T: Trait`, we do not look at any impls
|
||||
// whose outer level is not a parameter or projection. Especially for things like
|
||||
// `T: Clone` this is incredibly useful as we would otherwise look at all the impls
|
||||
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
|
||||
if let Some(simp) = fast_reject::simplify_type(self, self_ty, treat_params) {
|
||||
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
|
||||
for &impl_def_id in impls {
|
||||
if let result @ Some(_) = f(impl_def_id) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for &impl_def_id in impls.non_blanket_impls.values().flatten() {
|
||||
if let result @ Some(_) = f(impl_def_id) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns an iterator containing all impls for `trait_def_id`.
|
||||
///
|
||||
/// `trait_def_id` MUST BE the `DefId` of a trait.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use crate::mir;
|
||||
use crate::ty::fast_reject::TreatProjections;
|
||||
use crate::ty::layout::IntegerExt;
|
||||
use crate::ty::{
|
||||
self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
||||
|
|
@ -359,21 +358,29 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
self.ensure().coherent_trait(drop_trait);
|
||||
|
||||
let ty = self.type_of(adt_did).subst_identity();
|
||||
let (did, constness) = self.find_map_relevant_impl(
|
||||
drop_trait,
|
||||
ty,
|
||||
// FIXME: This could also be some other mode, like "unexpected"
|
||||
TreatProjections::ForLookup,
|
||||
|impl_did| {
|
||||
if let Some(item_id) = self.associated_item_def_ids(impl_did).first() {
|
||||
if validate(self, impl_did).is_ok() {
|
||||
return Some((*item_id, self.constness(impl_did)));
|
||||
}
|
||||
}
|
||||
None
|
||||
},
|
||||
)?;
|
||||
let mut dtor_candidate = None;
|
||||
self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
|
||||
let Some(item_id) = self.associated_item_def_ids(impl_did).first() else {
|
||||
self.sess.delay_span_bug(self.def_span(impl_did), "Drop impl without drop function");
|
||||
return;
|
||||
};
|
||||
|
||||
if validate(self, impl_did).is_err() {
|
||||
// Already `ErrorGuaranteed`, no need to delay a span bug here.
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some((old_item_id, _)) = dtor_candidate {
|
||||
self.sess
|
||||
.struct_span_err(self.def_span(item_id), "multiple drop impls found")
|
||||
.span_note(self.def_span(old_item_id), "other impl here")
|
||||
.delay_as_bug();
|
||||
}
|
||||
|
||||
dtor_candidate = Some((*item_id, self.constness(impl_did)));
|
||||
});
|
||||
|
||||
let (did, constness) = dtor_candidate?;
|
||||
Some(ty::Destructor { did, constness })
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ impl<'tcx> std::fmt::Debug for ScalarTy<'tcx> {
|
|||
|
||||
impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: Map) -> Self {
|
||||
let param_env = tcx.param_env(body.source.def_id());
|
||||
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
|
||||
Self {
|
||||
map,
|
||||
tcx,
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ impl EnumSizeOpt {
|
|||
fn optim<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let mut alloc_cache = FxHashMap::default();
|
||||
let body_did = body.source.def_id();
|
||||
let param_env = tcx.param_env(body_did);
|
||||
let param_env = tcx.param_env_reveal_all_normalized(body_did);
|
||||
|
||||
let blocks = body.basic_blocks.as_mut();
|
||||
let local_decls = &mut body.local_decls;
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
}
|
||||
sym::transmute => {
|
||||
sym::transmute | sym::transmute_unchecked => {
|
||||
let dst_ty = destination.ty(local_decls, tcx).ty;
|
||||
let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else {
|
||||
span_bug!(
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
|
|||
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let def_id = body.source.def_id();
|
||||
let param_env = tcx.param_env(def_id);
|
||||
let param_env = tcx.param_env_reveal_all_normalized(def_id);
|
||||
|
||||
let bbs = body.basic_blocks.as_mut();
|
||||
let mut should_cleanup = false;
|
||||
|
|
|
|||
|
|
@ -34,11 +34,23 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _: Location) {
|
||||
// We have to use `try_normalize_erasing_regions` here, since it's
|
||||
// possible that we visit impossible-to-satisfy where clauses here,
|
||||
// see #91745
|
||||
if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.literal) {
|
||||
constant.literal = c;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
|
||||
// We have to use `try_normalize_erasing_regions` here, since it's
|
||||
// possible that we visit impossible-to-satisfy where clauses here,
|
||||
// see #91745
|
||||
*ty = self.tcx.try_normalize_erasing_regions(self.param_env, *ty).unwrap_or(*ty);
|
||||
if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.param_env, *ty) {
|
||||
*ty = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'t
|
|||
fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> {
|
||||
debug!("build_clone_shim(def_id={:?})", def_id);
|
||||
|
||||
let param_env = tcx.param_env(def_id);
|
||||
let param_env = tcx.param_env_reveal_all_normalized(def_id);
|
||||
|
||||
let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
|
||||
let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env);
|
||||
|
|
@ -836,7 +836,7 @@ fn build_call_shim<'tcx>(
|
|||
pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
|
||||
debug_assert!(tcx.is_constructor(ctor_id));
|
||||
|
||||
let param_env = tcx.param_env(ctor_id);
|
||||
let param_env = tcx.param_env_reveal_all_normalized(ctor_id);
|
||||
|
||||
// Normalize the sig.
|
||||
let sig = tcx
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
|
|||
}
|
||||
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let param_env = tcx.param_env(body.source.def_id());
|
||||
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
|
||||
for block in body.basic_blocks_mut() {
|
||||
let terminator = block.terminator_mut();
|
||||
terminator.kind = match terminator.kind {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral {
|
|||
let opts = helper.find_optimizations();
|
||||
let mut storage_deads_to_insert = vec![];
|
||||
let mut storage_deads_to_remove: Vec<(usize, BasicBlock)> = vec![];
|
||||
let param_env = tcx.param_env(body.source.def_id());
|
||||
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
|
||||
for opt in opts {
|
||||
trace!("SUCCESS: Applying {:?}", opt);
|
||||
// replace terminator with a switchInt that switches on the integer directly
|
||||
|
|
|
|||
|
|
@ -109,7 +109,9 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
|
|||
continue;
|
||||
};
|
||||
|
||||
let layout = tcx.layout_of(tcx.param_env(body.source.def_id()).and(discriminant_ty));
|
||||
let layout = tcx.layout_of(
|
||||
tcx.param_env_reveal_all_normalized(body.source.def_id()).and(discriminant_ty),
|
||||
);
|
||||
|
||||
let allowed_variants = if let Ok(layout) = layout {
|
||||
variant_discriminants(&layout, discriminant_ty, tcx)
|
||||
|
|
|
|||
|
|
@ -223,3 +223,6 @@ resolve_remove_surrounding_derive =
|
|||
resolve_add_as_non_derive =
|
||||
add as non-Derive macro
|
||||
`#[{$macro_path}]`
|
||||
|
||||
resolve_proc_macro_same_crate = can't use a procedural macro from the same crate that defines it
|
||||
.help = you can define integration tests in a directory named `tests`
|
||||
|
|
|
|||
|
|
@ -508,3 +508,12 @@ pub(crate) struct RemoveSurroundingDerive {
|
|||
pub(crate) struct AddAsNonDerive<'a> {
|
||||
pub(crate) macro_path: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_proc_macro_same_crate)]
|
||||
pub(crate) struct ProcMacroSameCrate {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
#[help]
|
||||
pub(crate) is_test: bool,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! A bunch of methods and structures more or less related to resolving macros and
|
||||
//! interface provided by `Resolver` to macro expander.
|
||||
|
||||
use crate::errors::{AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive};
|
||||
use crate::errors::{self, AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive};
|
||||
use crate::Namespace::*;
|
||||
use crate::{BuiltinMacroState, Determinacy};
|
||||
use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
|
||||
|
|
@ -513,10 +513,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
if let Some(def_id) = def_id.as_local() {
|
||||
self.unused_macros.remove(&def_id);
|
||||
if self.proc_macro_stubs.contains(&def_id) {
|
||||
self.tcx.sess.span_err(
|
||||
path.span,
|
||||
"can't use a procedural macro from the same crate that defines it",
|
||||
);
|
||||
self.tcx.sess.emit_err(errors::ProcMacroSameCrate {
|
||||
span: path.span,
|
||||
is_test: self.tcx.sess.is_test_crate(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1505,6 +1505,7 @@ symbols! {
|
|||
transmute_generic_consts,
|
||||
transmute_opts,
|
||||
transmute_trait,
|
||||
transmute_unchecked,
|
||||
transparent,
|
||||
transparent_enums,
|
||||
transparent_unions,
|
||||
|
|
|
|||
|
|
@ -645,12 +645,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
// FIXME: Handling opaques here is kinda sus. Especially because we
|
||||
// simplify them to PlaceholderSimplifiedType.
|
||||
| ty::Alias(ty::Opaque, _) => {
|
||||
if let Some(def_id) = self.tcx().find_map_relevant_impl(
|
||||
let mut disqualifying_impl = None;
|
||||
self.tcx().for_each_relevant_impl_treating_projections(
|
||||
goal.predicate.def_id(),
|
||||
goal.predicate.self_ty(),
|
||||
TreatProjections::NextSolverLookup,
|
||||
Some,
|
||||
) {
|
||||
|impl_def_id| {
|
||||
disqualifying_impl = Some(impl_def_id);
|
||||
},
|
||||
);
|
||||
if let Some(def_id) = disqualifying_impl {
|
||||
debug!(?def_id, ?goal, "disqualified auto-trait implementation");
|
||||
// No need to actually consider the candidate here,
|
||||
// since we do that in `consider_impl_candidate`.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ use rustc_infer::infer::{InferOk, TypeTrace};
|
|||
use rustc_middle::traits::select::OverflowError;
|
||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::fast_reject::TreatProjections;
|
||||
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print};
|
||||
use rustc_middle::ty::{
|
||||
|
|
@ -1836,57 +1835,61 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
});
|
||||
let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
|
||||
|
||||
let secondary_span = match predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self
|
||||
.tcx
|
||||
.opt_associated_item(proj.projection_ty.def_id)
|
||||
.and_then(|trait_assoc_item| {
|
||||
self.tcx
|
||||
.trait_of_item(proj.projection_ty.def_id)
|
||||
.map(|id| (trait_assoc_item, id))
|
||||
})
|
||||
.and_then(|(trait_assoc_item, id)| {
|
||||
let trait_assoc_ident = trait_assoc_item.ident(self.tcx);
|
||||
self.tcx.find_map_relevant_impl(
|
||||
id,
|
||||
proj.projection_ty.self_ty(),
|
||||
TreatProjections::ForLookup,
|
||||
|did| {
|
||||
self.tcx
|
||||
.associated_items(did)
|
||||
.in_definition_order()
|
||||
.find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident)
|
||||
},
|
||||
)
|
||||
})
|
||||
.and_then(|item| match self.tcx.hir().get_if_local(item.def_id) {
|
||||
Some(
|
||||
hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Type(_, Some(ty)),
|
||||
..
|
||||
})
|
||||
| hir::Node::ImplItem(hir::ImplItem {
|
||||
kind: hir::ImplItemKind::Type(ty),
|
||||
..
|
||||
}),
|
||||
) => Some((
|
||||
ty.span,
|
||||
with_forced_trimmed_paths!(format!(
|
||||
"type mismatch resolving `{}`",
|
||||
self.resolve_vars_if_possible(predicate)
|
||||
.print(FmtPrinter::new_with_limit(
|
||||
self.tcx,
|
||||
Namespace::TypeNS,
|
||||
rustc_session::Limit(5),
|
||||
))
|
||||
.unwrap()
|
||||
.into_buffer()
|
||||
)),
|
||||
let secondary_span = (|| {
|
||||
let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) =
|
||||
predicate.kind().skip_binder()
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_ty.def_id)?;
|
||||
let trait_assoc_ident = trait_assoc_item.ident(self.tcx);
|
||||
|
||||
let mut associated_items = vec![];
|
||||
self.tcx.for_each_relevant_impl(
|
||||
self.tcx.trait_of_item(proj.projection_ty.def_id)?,
|
||||
proj.projection_ty.self_ty(),
|
||||
|impl_def_id| {
|
||||
associated_items.extend(
|
||||
self.tcx
|
||||
.associated_items(impl_def_id)
|
||||
.in_definition_order()
|
||||
.find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
let [associated_item]: &[ty::AssocItem] = &associated_items[..] else {
|
||||
return None;
|
||||
};
|
||||
match self.tcx.hir().get_if_local(associated_item.def_id) {
|
||||
Some(
|
||||
hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Type(_, Some(ty)),
|
||||
..
|
||||
})
|
||||
| hir::Node::ImplItem(hir::ImplItem {
|
||||
kind: hir::ImplItemKind::Type(ty),
|
||||
..
|
||||
}),
|
||||
) => Some((
|
||||
ty.span,
|
||||
with_forced_trimmed_paths!(format!(
|
||||
"type mismatch resolving `{}`",
|
||||
self.resolve_vars_if_possible(predicate)
|
||||
.print(FmtPrinter::new_with_limit(
|
||||
self.tcx,
|
||||
Namespace::TypeNS,
|
||||
rustc_session::Limit(5),
|
||||
))
|
||||
.unwrap()
|
||||
.into_buffer()
|
||||
)),
|
||||
_ => None,
|
||||
}),
|
||||
_ => None,
|
||||
};
|
||||
)),
|
||||
_ => None,
|
||||
}
|
||||
})();
|
||||
|
||||
self.note_type_err(
|
||||
&mut diag,
|
||||
&obligation.cause,
|
||||
|
|
@ -2228,14 +2231,18 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
err: &mut Diagnostic,
|
||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
||||
) -> bool {
|
||||
let get_trait_impl = |trait_def_id| {
|
||||
self.tcx.find_map_relevant_impl(
|
||||
let get_trait_impls = |trait_def_id| {
|
||||
let mut trait_impls = vec![];
|
||||
self.tcx.for_each_relevant_impl(
|
||||
trait_def_id,
|
||||
trait_ref.skip_binder().self_ty(),
|
||||
TreatProjections::ForLookup,
|
||||
Some,
|
||||
)
|
||||
|impl_def_id| {
|
||||
trait_impls.push(impl_def_id);
|
||||
},
|
||||
);
|
||||
trait_impls
|
||||
};
|
||||
|
||||
let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
|
||||
let traits_with_same_path: std::collections::BTreeSet<_> = self
|
||||
.tcx
|
||||
|
|
@ -2245,17 +2252,23 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
.collect();
|
||||
let mut suggested = false;
|
||||
for trait_with_same_path in traits_with_same_path {
|
||||
if let Some(impl_def_id) = get_trait_impl(trait_with_same_path) {
|
||||
let impl_span = self.tcx.def_span(impl_def_id);
|
||||
err.span_help(impl_span, "trait impl with same name found");
|
||||
let trait_crate = self.tcx.crate_name(trait_with_same_path.krate);
|
||||
let crate_msg = format!(
|
||||
"perhaps two different versions of crate `{}` are being used?",
|
||||
trait_crate
|
||||
);
|
||||
err.note(&crate_msg);
|
||||
suggested = true;
|
||||
let trait_impls = get_trait_impls(trait_with_same_path);
|
||||
if trait_impls.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let impl_spans: Vec<_> =
|
||||
trait_impls.iter().map(|impl_def_id| self.tcx.def_span(*impl_def_id)).collect();
|
||||
err.span_help(
|
||||
impl_spans,
|
||||
format!("trait impl{} with same name found", pluralize!(trait_impls.len())),
|
||||
);
|
||||
let trait_crate = self.tcx.crate_name(trait_with_same_path.krate);
|
||||
let crate_msg = format!(
|
||||
"perhaps two different versions of crate `{}` are being used?",
|
||||
trait_crate
|
||||
);
|
||||
err.note(&crate_msg);
|
||||
suggested = true;
|
||||
}
|
||||
suggested
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1272,14 +1272,29 @@ fn project<'cx, 'tcx>(
|
|||
ProjectionCandidateSet::Single(candidate) => {
|
||||
Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate)))
|
||||
}
|
||||
ProjectionCandidateSet::None => Ok(Projected::NoProgress(
|
||||
// FIXME(associated_const_generics): this may need to change in the future?
|
||||
// need to investigate whether or not this is fine.
|
||||
selcx
|
||||
.tcx()
|
||||
.mk_projection(obligation.predicate.def_id, obligation.predicate.substs)
|
||||
.into(),
|
||||
)),
|
||||
ProjectionCandidateSet::None => {
|
||||
let tcx = selcx.tcx();
|
||||
let term = match tcx.def_kind(obligation.predicate.def_id) {
|
||||
DefKind::AssocTy | DefKind::ImplTraitPlaceholder => tcx
|
||||
.mk_projection(obligation.predicate.def_id, obligation.predicate.substs)
|
||||
.into(),
|
||||
DefKind::AssocConst => tcx
|
||||
.mk_const(
|
||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(
|
||||
obligation.predicate.def_id,
|
||||
obligation.predicate.substs,
|
||||
)),
|
||||
tcx.type_of(obligation.predicate.def_id)
|
||||
.subst(tcx, obligation.predicate.substs),
|
||||
)
|
||||
.into(),
|
||||
kind => {
|
||||
bug!("unknown projection def-id: {}", kind.descr(obligation.predicate.def_id))
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Projected::NoProgress(term))
|
||||
}
|
||||
// Error occurred while trying to processing impls.
|
||||
ProjectionCandidateSet::Error(e) => Err(ProjectionError::TraitSelectionError(e)),
|
||||
// Inherent ambiguity that prevents us from even enumerating the
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use hir::LangItem;
|
|||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections};
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
|
||||
|
||||
use crate::traits;
|
||||
|
|
@ -875,12 +875,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
ty::Adt(..) => {
|
||||
// Find a custom `impl Drop` impl, if it exists
|
||||
let relevant_impl = self.tcx().find_map_relevant_impl(
|
||||
let mut relevant_impl = None;
|
||||
self.tcx().for_each_relevant_impl(
|
||||
self.tcx().require_lang_item(LangItem::Drop, None),
|
||||
obligation.predicate.skip_binder().trait_ref.self_ty(),
|
||||
TreatProjections::ForLookup,
|
||||
Some,
|
||||
|impl_def_id| {
|
||||
if let Some(old_impl_def_id) = relevant_impl {
|
||||
self.tcx()
|
||||
.sess
|
||||
.struct_span_err(
|
||||
self.tcx().def_span(impl_def_id),
|
||||
"multiple drop impls found",
|
||||
)
|
||||
.span_note(self.tcx().def_span(old_impl_def_id), "other impl here")
|
||||
.delay_as_bug();
|
||||
}
|
||||
|
||||
relevant_impl = Some(impl_def_id);
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(impl_def_id) = relevant_impl {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
use crate::num::NonZeroUsize;
|
||||
use crate::{
|
||||
fmt,
|
||||
intrinsics::transmute_unchecked,
|
||||
iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
|
||||
mem::{self, MaybeUninit},
|
||||
mem::MaybeUninit,
|
||||
ops::{IndexRange, Range},
|
||||
ptr,
|
||||
};
|
||||
|
|
@ -63,18 +64,11 @@ impl<T, const N: usize> IntoIterator for [T; N] {
|
|||
// an array of `T`.
|
||||
//
|
||||
// With that, this initialization satisfies the invariants.
|
||||
|
||||
// FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
|
||||
// works with const generics:
|
||||
// `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)`
|
||||
//
|
||||
// Until then, we can use `mem::transmute_copy` to create a bitwise copy
|
||||
// as a different type, then forget `array` so that it is not dropped.
|
||||
unsafe {
|
||||
let iter = IntoIter { data: mem::transmute_copy(&self), alive: IndexRange::zero_to(N) };
|
||||
mem::forget(self);
|
||||
iter
|
||||
}
|
||||
// FIXME: If normal `transmute` ever gets smart enough to allow this
|
||||
// directly, use it instead of `transmute_unchecked`.
|
||||
let data: [MaybeUninit<T>; N] = unsafe { transmute_unchecked(self) };
|
||||
IntoIter { data, alive: IndexRange::zero_to(N) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1376,6 +1376,20 @@ extern "rust-intrinsic" {
|
|||
#[rustc_nounwind]
|
||||
pub fn transmute<Src, Dst>(src: Src) -> Dst;
|
||||
|
||||
/// Like [`transmute`], but even less checked at compile-time: rather than
|
||||
/// giving an error for `size_of::<Src>() != size_of::<Dst>()`, it's
|
||||
/// **Undefined Behaviour** at runtime.
|
||||
///
|
||||
/// Prefer normal `transmute` where possible, for the extra checking, since
|
||||
/// both do exactly the same thing at runtime, if they both compile.
|
||||
///
|
||||
/// This is not expected to ever be exposed directly to users, rather it
|
||||
/// may eventually be exposed through some more-constrained API.
|
||||
#[cfg(not(bootstrap))]
|
||||
#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
|
||||
#[rustc_nounwind]
|
||||
pub fn transmute_unchecked<Src, Dst>(src: Src) -> Dst;
|
||||
|
||||
/// Returns `true` if the actual type given as `T` requires drop
|
||||
/// glue; returns `false` if the actual type provided for `T`
|
||||
/// implements `Copy`.
|
||||
|
|
@ -2798,3 +2812,11 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
|
|||
write_bytes(dst, val, count)
|
||||
}
|
||||
}
|
||||
|
||||
/// Polyfill for bootstrap
|
||||
#[cfg(bootstrap)]
|
||||
pub const unsafe fn transmute_unchecked<Src, Dst>(src: Src) -> Dst {
|
||||
use crate::mem::*;
|
||||
// SAFETY: It's a transmute -- the caller promised it's fine.
|
||||
unsafe { transmute_copy(&ManuallyDrop::new(src)) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -945,14 +945,10 @@ impl<T> MaybeUninit<T> {
|
|||
// * `MaybeUninit<T>` and T are guaranteed to have the same layout
|
||||
// * `MaybeUninit` does not drop, so there are no double-frees
|
||||
// And thus the conversion is safe
|
||||
let ret = unsafe {
|
||||
unsafe {
|
||||
intrinsics::assert_inhabited::<[T; N]>();
|
||||
(&array as *const _ as *const [T; N]).read()
|
||||
};
|
||||
|
||||
// FIXME: required to avoid `~const Destruct` bound
|
||||
super::forget(array);
|
||||
ret
|
||||
intrinsics::transmute_unchecked(array)
|
||||
}
|
||||
}
|
||||
|
||||
/// Assuming all the elements are initialized, get a slice to them.
|
||||
|
|
|
|||
|
|
@ -722,11 +722,14 @@ class RustBuild(object):
|
|||
|
||||
def build_bootstrap(self, color, verbose_count):
|
||||
"""Build bootstrap"""
|
||||
print("Building bootstrap")
|
||||
env = os.environ.copy()
|
||||
if "GITHUB_ACTIONS" in env:
|
||||
print("::group::Building bootstrap")
|
||||
else:
|
||||
print("Building bootstrap")
|
||||
build_dir = os.path.join(self.build_dir, "bootstrap")
|
||||
if self.clean and os.path.exists(build_dir):
|
||||
shutil.rmtree(build_dir)
|
||||
env = os.environ.copy()
|
||||
# `CARGO_BUILD_TARGET` breaks bootstrap build.
|
||||
# See also: <https://github.com/rust-lang/rust/issues/70208>.
|
||||
if "CARGO_BUILD_TARGET" in env:
|
||||
|
|
@ -798,6 +801,9 @@ class RustBuild(object):
|
|||
# Run this from the source directory so cargo finds .cargo/config
|
||||
run(args, env=env, verbose=self.verbose, cwd=self.rust_root)
|
||||
|
||||
if "GITHUB_ACTIONS" in env:
|
||||
print("::endgroup::")
|
||||
|
||||
def build_triple(self):
|
||||
"""Build triple as in LLVM
|
||||
|
||||
|
|
|
|||
|
|
@ -105,15 +105,7 @@ impl Step for Std {
|
|||
cargo.arg("--lib");
|
||||
}
|
||||
|
||||
let msg = if compiler.host == target {
|
||||
format!("Checking stage{} library artifacts ({target})", builder.top_stage)
|
||||
} else {
|
||||
format!(
|
||||
"Checking stage{} library artifacts ({} -> {})",
|
||||
builder.top_stage, &compiler.host, target
|
||||
)
|
||||
};
|
||||
builder.info(&msg);
|
||||
let _guard = builder.msg_check("library artifacts", target);
|
||||
run_cargo(
|
||||
builder,
|
||||
cargo,
|
||||
|
|
@ -167,18 +159,7 @@ impl Step for Std {
|
|||
cargo.arg("-p").arg(krate.name);
|
||||
}
|
||||
|
||||
let msg = if compiler.host == target {
|
||||
format!(
|
||||
"Checking stage{} library test/bench/example targets ({target})",
|
||||
builder.top_stage
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"Checking stage{} library test/bench/example targets ({} -> {})",
|
||||
builder.top_stage, &compiler.host, target
|
||||
)
|
||||
};
|
||||
builder.info(&msg);
|
||||
let _guard = builder.msg_check("library test/bench/example targets", target);
|
||||
run_cargo(
|
||||
builder,
|
||||
cargo,
|
||||
|
|
@ -252,15 +233,7 @@ impl Step for Rustc {
|
|||
cargo.arg("-p").arg(krate.name);
|
||||
}
|
||||
|
||||
let msg = if compiler.host == target {
|
||||
format!("Checking stage{} compiler artifacts ({target})", builder.top_stage)
|
||||
} else {
|
||||
format!(
|
||||
"Checking stage{} compiler artifacts ({} -> {})",
|
||||
builder.top_stage, &compiler.host, target
|
||||
)
|
||||
};
|
||||
builder.info(&msg);
|
||||
let _guard = builder.msg_check("compiler artifacts", target);
|
||||
run_cargo(
|
||||
builder,
|
||||
cargo,
|
||||
|
|
@ -317,15 +290,7 @@ impl Step for CodegenBackend {
|
|||
.arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend)));
|
||||
rustc_cargo_env(builder, &mut cargo, target, compiler.stage);
|
||||
|
||||
let msg = if compiler.host == target {
|
||||
format!("Checking stage{} {} artifacts ({target})", builder.top_stage, backend)
|
||||
} else {
|
||||
format!(
|
||||
"Checking stage{} {} library ({} -> {})",
|
||||
builder.top_stage, backend, &compiler.host.triple, target.triple
|
||||
)
|
||||
};
|
||||
builder.info(&msg);
|
||||
let _guard = builder.msg_check(&backend, target);
|
||||
|
||||
run_cargo(
|
||||
builder,
|
||||
|
|
@ -385,15 +350,7 @@ impl Step for RustAnalyzer {
|
|||
cargo.arg("--benches");
|
||||
}
|
||||
|
||||
let msg = if compiler.host == target {
|
||||
format!("Checking stage{} {} artifacts ({target})", compiler.stage, "rust-analyzer")
|
||||
} else {
|
||||
format!(
|
||||
"Checking stage{} {} artifacts ({} -> {})",
|
||||
compiler.stage, "rust-analyzer", &compiler.host.triple, target.triple
|
||||
)
|
||||
};
|
||||
builder.info(&msg);
|
||||
let _guard = builder.msg_check("rust-analyzer artifacts", target);
|
||||
run_cargo(
|
||||
builder,
|
||||
cargo,
|
||||
|
|
@ -460,18 +417,7 @@ macro_rules! tool_check_step {
|
|||
// NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]`
|
||||
// See https://github.com/rust-lang/rust/pull/80573#issuecomment-754010776
|
||||
cargo.rustflag("-Zunstable-options");
|
||||
let msg = if compiler.host == target {
|
||||
format!("Checking stage{} {} artifacts ({target})", builder.top_stage, stringify!($name).to_lowercase())
|
||||
} else {
|
||||
format!(
|
||||
"Checking stage{} {} artifacts ({} -> {})",
|
||||
builder.top_stage,
|
||||
stringify!($name).to_lowercase(),
|
||||
&compiler.host.triple,
|
||||
target.triple
|
||||
)
|
||||
};
|
||||
builder.info(&msg);
|
||||
let _guard = builder.msg_check(&concat!(stringify!($name), " artifacts").to_lowercase(), target);
|
||||
run_cargo(
|
||||
builder,
|
||||
cargo,
|
||||
|
|
|
|||
|
|
@ -143,23 +143,13 @@ impl Step for Std {
|
|||
cargo.arg("-p").arg(krate);
|
||||
}
|
||||
|
||||
let msg = if compiler.host == target {
|
||||
format!(
|
||||
"Building{} stage{} library artifacts ({}) ",
|
||||
crate_description(&self.crates),
|
||||
compiler.stage,
|
||||
compiler.host
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"Building{} stage{} library artifacts ({} -> {})",
|
||||
crate_description(&self.crates),
|
||||
compiler.stage,
|
||||
compiler.host,
|
||||
target,
|
||||
)
|
||||
};
|
||||
builder.info(&msg);
|
||||
let _guard = builder.msg(
|
||||
Kind::Build,
|
||||
compiler.stage,
|
||||
format_args!("library artifacts{}", crate_description(&self.crates)),
|
||||
compiler.host,
|
||||
target,
|
||||
);
|
||||
run_cargo(
|
||||
builder,
|
||||
cargo,
|
||||
|
|
@ -790,24 +780,13 @@ impl Step for Rustc {
|
|||
cargo.arg("-p").arg(krate);
|
||||
}
|
||||
|
||||
let msg = if compiler.host == target {
|
||||
format!(
|
||||
"Building{} compiler artifacts (stage{} -> stage{})",
|
||||
crate_description(&self.crates),
|
||||
compiler.stage,
|
||||
compiler.stage + 1
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"Building{} compiler artifacts (stage{}:{} -> stage{}:{})",
|
||||
crate_description(&self.crates),
|
||||
compiler.stage,
|
||||
compiler.host,
|
||||
compiler.stage + 1,
|
||||
target,
|
||||
)
|
||||
};
|
||||
builder.info(&msg);
|
||||
let _guard = builder.msg_sysroot_tool(
|
||||
Kind::Build,
|
||||
compiler.stage,
|
||||
format_args!("compiler artifacts{}", crate_description(&self.crates)),
|
||||
compiler.host,
|
||||
target,
|
||||
);
|
||||
run_cargo(
|
||||
builder,
|
||||
cargo,
|
||||
|
|
@ -1114,15 +1093,7 @@ impl Step for CodegenBackend {
|
|||
|
||||
let tmp_stamp = out_dir.join(".tmp.stamp");
|
||||
|
||||
let msg = if compiler.host == target {
|
||||
format!("Building stage{} codegen backend {}", compiler.stage, backend)
|
||||
} else {
|
||||
format!(
|
||||
"Building stage{} codegen backend {} ({} -> {})",
|
||||
compiler.stage, backend, compiler.host, target
|
||||
)
|
||||
};
|
||||
builder.info(&msg);
|
||||
let _guard = builder.msg_build(compiler, format_args!("codegen backend {backend}"), target);
|
||||
let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false, false);
|
||||
if builder.config.dry_run() {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use crate::util::t;
|
|||
|
||||
use crate::dist;
|
||||
use crate::tarball::GeneratedTarball;
|
||||
use crate::Compiler;
|
||||
use crate::{Compiler, Kind};
|
||||
|
||||
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::config::{Config, TargetSelection};
|
||||
|
|
@ -52,7 +52,7 @@ fn install_sh(
|
|||
host: Option<TargetSelection>,
|
||||
tarball: &GeneratedTarball,
|
||||
) {
|
||||
builder.info(&format!("Install {} stage{} ({:?})", package, stage, host));
|
||||
let _guard = builder.msg(Kind::Install, stage, package, host, host);
|
||||
|
||||
let prefix = default_path(&builder.config.prefix, "/usr/local");
|
||||
let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc"));
|
||||
|
|
|
|||
|
|
@ -19,13 +19,14 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::env;
|
||||
use std::fmt::Display;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::str;
|
||||
|
||||
use build_helper::ci::CiEnv;
|
||||
use build_helper::ci::{gha, CiEnv};
|
||||
use channel::GitInfo;
|
||||
use config::{DryRun, Target};
|
||||
use filetime::FileTime;
|
||||
|
|
@ -993,6 +994,85 @@ impl Build {
|
|||
}
|
||||
}
|
||||
|
||||
fn msg_check(
|
||||
&self,
|
||||
what: impl Display,
|
||||
target: impl Into<Option<TargetSelection>>,
|
||||
) -> Option<gha::Group> {
|
||||
self.msg(Kind::Check, self.config.stage, what, self.config.build, target)
|
||||
}
|
||||
|
||||
fn msg_build(
|
||||
&self,
|
||||
compiler: Compiler,
|
||||
what: impl Display,
|
||||
target: impl Into<Option<TargetSelection>>,
|
||||
) -> Option<gha::Group> {
|
||||
self.msg(Kind::Build, compiler.stage, what, compiler.host, target)
|
||||
}
|
||||
|
||||
/// Return a `Group` guard for a [`Step`] that is built for each `--stage`.
|
||||
fn msg(
|
||||
&self,
|
||||
action: impl Into<Kind>,
|
||||
stage: u32,
|
||||
what: impl Display,
|
||||
host: impl Into<Option<TargetSelection>>,
|
||||
target: impl Into<Option<TargetSelection>>,
|
||||
) -> Option<gha::Group> {
|
||||
let action = action.into();
|
||||
let msg = |fmt| format!("{action:?}ing stage{stage} {what}{fmt}");
|
||||
let msg = if let Some(target) = target.into() {
|
||||
let host = host.into().unwrap();
|
||||
if host == target {
|
||||
msg(format_args!(" ({target})"))
|
||||
} else {
|
||||
msg(format_args!(" ({host} -> {target})"))
|
||||
}
|
||||
} else {
|
||||
msg(format_args!(""))
|
||||
};
|
||||
self.group(&msg)
|
||||
}
|
||||
|
||||
/// Return a `Group` guard for a [`Step`] that is only built once and isn't affected by `--stage`.
|
||||
fn msg_unstaged(
|
||||
&self,
|
||||
action: impl Into<Kind>,
|
||||
what: impl Display,
|
||||
target: TargetSelection,
|
||||
) -> Option<gha::Group> {
|
||||
let action = action.into();
|
||||
let msg = format!("{action:?}ing {what} for {target}");
|
||||
self.group(&msg)
|
||||
}
|
||||
|
||||
fn msg_sysroot_tool(
|
||||
&self,
|
||||
action: impl Into<Kind>,
|
||||
stage: u32,
|
||||
what: impl Display,
|
||||
host: TargetSelection,
|
||||
target: TargetSelection,
|
||||
) -> Option<gha::Group> {
|
||||
let action = action.into();
|
||||
let msg = |fmt| format!("{action:?}ing {what} {fmt}");
|
||||
let msg = if host == target {
|
||||
msg(format_args!("(stage{stage} -> stage{}, {target})", stage + 1))
|
||||
} else {
|
||||
msg(format_args!("(stage{stage}:{host} -> stage{}:{target})", stage + 1))
|
||||
};
|
||||
self.group(&msg)
|
||||
}
|
||||
|
||||
fn group(&self, msg: &str) -> Option<gha::Group> {
|
||||
self.info(&msg);
|
||||
match self.config.dry_run {
|
||||
DryRun::SelfCheck => None,
|
||||
DryRun::Disabled | DryRun::UserSelected => Some(gha::group(&msg)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of parallel jobs that have been configured for this
|
||||
/// build.
|
||||
fn jobs(&self) -> u32 {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use crate::channel;
|
|||
use crate::config::{Config, TargetSelection};
|
||||
use crate::util::get_clang_cl_resource_dir;
|
||||
use crate::util::{self, exe, output, t, up_to_date};
|
||||
use crate::{CLang, GitRepo};
|
||||
use crate::{CLang, GitRepo, Kind};
|
||||
|
||||
use build_helper::ci::CiEnv;
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ impl Step for Llvm {
|
|||
panic!("shared linking to LLVM is not currently supported on {}", target.triple);
|
||||
}
|
||||
|
||||
builder.info(&format!("Building LLVM for {}", target));
|
||||
let _guard = builder.msg_unstaged(Kind::Build, "LLVM", target);
|
||||
t!(stamp.remove());
|
||||
let _time = util::timeit(&builder);
|
||||
t!(fs::create_dir_all(&out_dir));
|
||||
|
|
@ -813,7 +813,7 @@ impl Step for Lld {
|
|||
return out_dir;
|
||||
}
|
||||
|
||||
builder.info(&format!("Building LLD for {}", target));
|
||||
let _guard = builder.msg_unstaged(Kind::Build, "LLD", target);
|
||||
let _time = util::timeit(&builder);
|
||||
t!(fs::create_dir_all(&out_dir));
|
||||
|
||||
|
|
@ -911,7 +911,7 @@ impl Step for Sanitizers {
|
|||
return runtimes;
|
||||
}
|
||||
|
||||
builder.info(&format!("Building sanitizers for {}", self.target));
|
||||
let _guard = builder.msg_unstaged(Kind::Build, "sanitizers", self.target);
|
||||
t!(stamp.remove());
|
||||
let _time = util::timeit(&builder);
|
||||
|
||||
|
|
@ -1103,7 +1103,7 @@ impl Step for CrtBeginEnd {
|
|||
return out_dir;
|
||||
}
|
||||
|
||||
builder.info("Building crtbegin.o and crtend.o");
|
||||
let _guard = builder.msg_unstaged(Kind::Build, "crtbegin.o and crtend.o", self.target);
|
||||
t!(fs::create_dir_all(&out_dir));
|
||||
|
||||
let mut cfg = cc::Build::new();
|
||||
|
|
@ -1168,7 +1168,7 @@ impl Step for Libunwind {
|
|||
return out_dir;
|
||||
}
|
||||
|
||||
builder.info(&format!("Building libunwind.a for {}", self.target.triple));
|
||||
let _guard = builder.msg_unstaged(Kind::Build, "libunwind.a", self.target);
|
||||
t!(fs::create_dir_all(&out_dir));
|
||||
|
||||
let mut cc_cfg = cc::Build::new();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::iter;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
|
@ -57,12 +56,12 @@ impl TestKind {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TestKind {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(match *self {
|
||||
TestKind::Test => "Testing",
|
||||
TestKind::Bench => "Benchmarking",
|
||||
})
|
||||
impl Into<Kind> for TestKind {
|
||||
fn into(self) -> Kind {
|
||||
match self {
|
||||
TestKind::Test => Kind::Test,
|
||||
TestKind::Bench => Kind::Bench,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1905,7 +1904,13 @@ impl BookTest {
|
|||
rustbook_cmd.env("RUSTC_BOOTSTRAP", "1");
|
||||
rustbook_cmd.env("PATH", new_path).arg("test").arg(path);
|
||||
builder.add_rust_test_threads(&mut rustbook_cmd);
|
||||
builder.info(&format!("Testing rustbook {}", self.path.display()));
|
||||
let _guard = builder.msg(
|
||||
Kind::Test,
|
||||
compiler.stage,
|
||||
format_args!("rustbook {}", self.path.display()),
|
||||
compiler.host,
|
||||
compiler.host,
|
||||
);
|
||||
let _time = util::timeit(&builder);
|
||||
let toolstate = if try_run(builder, &mut rustbook_cmd) {
|
||||
ToolState::TestPass
|
||||
|
|
@ -2033,7 +2038,8 @@ impl Step for ErrorIndex {
|
|||
let mut tool = tool::ErrorIndex::command(builder);
|
||||
tool.arg("markdown").arg(&output);
|
||||
|
||||
builder.info(&format!("Testing error-index stage{}", compiler.stage));
|
||||
let _guard =
|
||||
builder.msg(Kind::Test, compiler.stage, "error-index", compiler.host, compiler.host);
|
||||
let _time = util::timeit(&builder);
|
||||
builder.run_quiet(&mut tool);
|
||||
// The tests themselves need to link to std, so make sure it is
|
||||
|
|
@ -2263,14 +2269,13 @@ impl Step for Crate {
|
|||
);
|
||||
}
|
||||
|
||||
builder.info(&format!(
|
||||
"{}{} stage{} ({} -> {})",
|
||||
let _guard = builder.msg(
|
||||
test_kind,
|
||||
crate_description(&self.crates),
|
||||
compiler.stage,
|
||||
&compiler.host,
|
||||
target
|
||||
));
|
||||
crate_description(&self.crates),
|
||||
compiler.host,
|
||||
target,
|
||||
);
|
||||
let _time = util::timeit(&builder);
|
||||
crate::render_tests::try_run_tests(builder, &mut cargo.into());
|
||||
}
|
||||
|
|
@ -2386,10 +2391,8 @@ impl Step for CrateRustdoc {
|
|||
cargo.arg("--quiet");
|
||||
}
|
||||
|
||||
builder.info(&format!(
|
||||
"{} rustdoc stage{} ({} -> {})",
|
||||
test_kind, compiler.stage, &compiler.host, target
|
||||
));
|
||||
let _guard = builder.msg(test_kind, compiler.stage, "rustdoc", compiler.host, target);
|
||||
|
||||
let _time = util::timeit(&builder);
|
||||
|
||||
add_flags_and_try_run_tests(builder, &mut cargo.into());
|
||||
|
|
@ -2453,10 +2456,8 @@ impl Step for CrateRustdocJsonTypes {
|
|||
cargo.arg("'-Ctarget-feature=-crt-static'");
|
||||
}
|
||||
|
||||
builder.info(&format!(
|
||||
"{} rustdoc-json-types stage{} ({} -> {})",
|
||||
test_kind, compiler.stage, &compiler.host, target
|
||||
));
|
||||
let _guard =
|
||||
builder.msg(test_kind, compiler.stage, "rustdoc-json-types", compiler.host, target);
|
||||
let _time = util::timeit(&builder);
|
||||
|
||||
add_flags_and_try_run_tests(builder, &mut cargo.into());
|
||||
|
|
@ -2845,7 +2846,7 @@ impl Step for TestHelpers {
|
|||
return;
|
||||
}
|
||||
|
||||
builder.info("Building test helpers");
|
||||
let _guard = builder.msg_unstaged(Kind::Build, "test helpers", target);
|
||||
t!(fs::create_dir_all(&dst));
|
||||
let mut cfg = cc::Build::new();
|
||||
// FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use crate::toolstate::ToolState;
|
|||
use crate::util::{add_dylib_path, exe, t};
|
||||
use crate::Compiler;
|
||||
use crate::Mode;
|
||||
use crate::{gha, Kind};
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub enum SourceType {
|
||||
|
|
@ -32,41 +33,27 @@ struct ToolBuild {
|
|||
allow_features: &'static str,
|
||||
}
|
||||
|
||||
fn tooling_output(
|
||||
mode: Mode,
|
||||
tool: &str,
|
||||
build_stage: u32,
|
||||
host: &TargetSelection,
|
||||
target: &TargetSelection,
|
||||
) -> String {
|
||||
match mode {
|
||||
// depends on compiler stage, different to host compiler
|
||||
Mode::ToolRustc => {
|
||||
if host == target {
|
||||
format!("Building tool {} (stage{} -> stage{})", tool, build_stage, build_stage + 1)
|
||||
} else {
|
||||
format!(
|
||||
"Building tool {} (stage{}:{} -> stage{}:{})",
|
||||
tool,
|
||||
build_stage,
|
||||
host,
|
||||
build_stage + 1,
|
||||
target
|
||||
)
|
||||
}
|
||||
impl Builder<'_> {
|
||||
fn msg_tool(
|
||||
&self,
|
||||
mode: Mode,
|
||||
tool: &str,
|
||||
build_stage: u32,
|
||||
host: &TargetSelection,
|
||||
target: &TargetSelection,
|
||||
) -> Option<gha::Group> {
|
||||
match mode {
|
||||
// depends on compiler stage, different to host compiler
|
||||
Mode::ToolRustc => self.msg_sysroot_tool(
|
||||
Kind::Build,
|
||||
build_stage,
|
||||
format_args!("tool {tool}"),
|
||||
*host,
|
||||
*target,
|
||||
),
|
||||
// doesn't depend on compiler, same as host compiler
|
||||
_ => self.msg(Kind::Build, build_stage, format_args!("tool {tool}"), *host, *target),
|
||||
}
|
||||
// doesn't depend on compiler, same as host compiler
|
||||
Mode::ToolStd => {
|
||||
if host == target {
|
||||
format!("Building tool {} (stage{})", tool, build_stage)
|
||||
} else {
|
||||
format!(
|
||||
"Building tool {} (stage{}:{} -> stage{}:{})",
|
||||
tool, build_stage, host, build_stage, target
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => format!("Building tool {} (stage{})", tool, build_stage),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,14 +98,13 @@ impl Step for ToolBuild {
|
|||
if !self.allow_features.is_empty() {
|
||||
cargo.allow_features(self.allow_features);
|
||||
}
|
||||
let msg = tooling_output(
|
||||
let _guard = builder.msg_tool(
|
||||
self.mode,
|
||||
self.tool,
|
||||
self.compiler.stage,
|
||||
&self.compiler.host,
|
||||
&self.target,
|
||||
);
|
||||
builder.info(&msg);
|
||||
|
||||
let mut cargo = Command::from(cargo);
|
||||
let is_expected = builder.try_run(&mut cargo);
|
||||
|
|
@ -492,14 +478,13 @@ impl Step for Rustdoc {
|
|||
cargo.rustflag("--cfg=parallel_compiler");
|
||||
}
|
||||
|
||||
let msg = tooling_output(
|
||||
let _guard = builder.msg_tool(
|
||||
Mode::ToolRustc,
|
||||
"rustdoc",
|
||||
build_compiler.stage,
|
||||
&self.compiler.host,
|
||||
&target,
|
||||
);
|
||||
builder.info(&msg);
|
||||
builder.run(&mut cargo.into());
|
||||
|
||||
// Cargo adds a number of paths to the dylib search path on windows, which results in
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use rustc_hir::def::Namespace::*;
|
|||
use rustc_hir::def::{DefKind, Namespace, PerNS};
|
||||
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
|
||||
use rustc_hir::Mutability;
|
||||
use rustc_middle::ty::{fast_reject::TreatProjections, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{Ty, TyCtxt};
|
||||
use rustc_middle::{bug, ty};
|
||||
use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution};
|
||||
use rustc_resolve::rustdoc::{strip_generics_from_path, MalformedGenerics};
|
||||
|
|
@ -772,11 +772,10 @@ fn trait_impls_for<'a>(
|
|||
module: DefId,
|
||||
) -> FxHashSet<(DefId, DefId)> {
|
||||
let tcx = cx.tcx;
|
||||
let iter = tcx.doc_link_traits_in_scope(module).iter().flat_map(|&trait_| {
|
||||
trace!("considering explicit impl for trait {:?}", trait_);
|
||||
let mut impls = FxHashSet::default();
|
||||
|
||||
// Look at each trait implementation to see if it's an impl for `did`
|
||||
tcx.find_map_relevant_impl(trait_, ty, TreatProjections::ForLookup, |impl_| {
|
||||
for &trait_ in tcx.doc_link_traits_in_scope(module) {
|
||||
tcx.for_each_relevant_impl(trait_, ty, |impl_| {
|
||||
let trait_ref = tcx.impl_trait_ref(impl_).expect("this is not an inherent impl");
|
||||
// Check if these are the same type.
|
||||
let impl_type = trait_ref.skip_binder().self_ty();
|
||||
|
|
@ -800,10 +799,13 @@ fn trait_impls_for<'a>(
|
|||
_ => false,
|
||||
};
|
||||
|
||||
if saw_impl { Some((impl_, trait_)) } else { None }
|
||||
})
|
||||
});
|
||||
iter.collect()
|
||||
if saw_impl {
|
||||
impls.insert((impl_, trait_));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
impls
|
||||
}
|
||||
|
||||
/// Check for resolve collisions between a trait and its derive.
|
||||
|
|
|
|||
|
|
@ -38,3 +38,27 @@ impl CiEnv {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod gha {
|
||||
/// All github actions log messages from this call to the Drop of the return value
|
||||
/// will be grouped and hidden by default in logs. Note that nesting these does
|
||||
/// not really work.
|
||||
pub fn group(name: impl std::fmt::Display) -> Group {
|
||||
if std::env::var_os("GITHUB_ACTIONS").is_some() {
|
||||
eprintln!("::group::{name}");
|
||||
}
|
||||
Group(())
|
||||
}
|
||||
|
||||
/// A guard that closes the current github actions log group on drop.
|
||||
#[must_use]
|
||||
pub struct Group(());
|
||||
|
||||
impl Drop for Group {
|
||||
fn drop(&mut self) {
|
||||
if std::env::var_os("GITHUB_ACTIONS").is_some() {
|
||||
eprintln!("::endgroup::");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@
|
|||
#![feature(inline_const)]
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
use std::mem::{transmute, MaybeUninit};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::intrinsics::{transmute, transmute_unchecked};
|
||||
|
||||
// Some of the cases here are statically rejected by `mem::transmute`, so
|
||||
// we need to generate custom MIR for those cases to get to codegen.
|
||||
// Some of these need custom MIR to not get removed by MIR optimizations.
|
||||
use std::intrinsics::mir::*;
|
||||
|
||||
enum Never {}
|
||||
|
|
@ -30,59 +30,35 @@ pub struct Aggregate8(u8);
|
|||
|
||||
// CHECK-LABEL: @check_bigger_size(
|
||||
#[no_mangle]
|
||||
#[custom_mir(dialect = "runtime", phase = "initial")]
|
||||
pub unsafe fn check_bigger_size(x: u16) -> u32 {
|
||||
// CHECK: call void @llvm.trap
|
||||
mir!{
|
||||
{
|
||||
RET = CastTransmute(x);
|
||||
Return()
|
||||
}
|
||||
}
|
||||
transmute_unchecked(x)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @check_smaller_size(
|
||||
#[no_mangle]
|
||||
#[custom_mir(dialect = "runtime", phase = "initial")]
|
||||
pub unsafe fn check_smaller_size(x: u32) -> u16 {
|
||||
// CHECK: call void @llvm.trap
|
||||
mir!{
|
||||
{
|
||||
RET = CastTransmute(x);
|
||||
Return()
|
||||
}
|
||||
}
|
||||
transmute_unchecked(x)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @check_smaller_array(
|
||||
#[no_mangle]
|
||||
#[custom_mir(dialect = "runtime", phase = "initial")]
|
||||
pub unsafe fn check_smaller_array(x: [u32; 7]) -> [u32; 3] {
|
||||
// CHECK: call void @llvm.trap
|
||||
mir!{
|
||||
{
|
||||
RET = CastTransmute(x);
|
||||
Return()
|
||||
}
|
||||
}
|
||||
transmute_unchecked(x)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @check_bigger_array(
|
||||
#[no_mangle]
|
||||
#[custom_mir(dialect = "runtime", phase = "initial")]
|
||||
pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] {
|
||||
// CHECK: call void @llvm.trap
|
||||
mir!{
|
||||
{
|
||||
RET = CastTransmute(x);
|
||||
Return()
|
||||
}
|
||||
}
|
||||
transmute_unchecked(x)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @check_to_uninhabited(
|
||||
#[no_mangle]
|
||||
#[custom_mir(dialect = "runtime", phase = "initial")]
|
||||
#[custom_mir(dialect = "runtime", phase = "optimized")]
|
||||
pub unsafe fn check_to_uninhabited(x: u16) -> BigNever {
|
||||
// CHECK: call void @llvm.trap
|
||||
mir!{
|
||||
|
|
@ -95,7 +71,7 @@ pub unsafe fn check_to_uninhabited(x: u16) -> BigNever {
|
|||
|
||||
// CHECK-LABEL: @check_from_uninhabited(
|
||||
#[no_mangle]
|
||||
#[custom_mir(dialect = "runtime", phase = "initial")]
|
||||
#[custom_mir(dialect = "runtime", phase = "optimized")]
|
||||
pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 {
|
||||
// CHECK: ret i16 poison
|
||||
mir!{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
#![feature(associated_const_equality)]
|
||||
|
||||
// Issue 110549
|
||||
|
||||
pub trait TraitWAssocConst {
|
||||
const A: usize;
|
||||
}
|
||||
|
||||
fn foo<T: TraitWAssocConst<A = 32>>() {}
|
||||
|
||||
fn bar<T: TraitWAssocConst>() {
|
||||
foo::<T>();
|
||||
//~^ ERROR type mismatch resolving `<T as TraitWAssocConst>::A == 32`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
error[E0271]: type mismatch resolving `<T as TraitWAssocConst>::A == 32`
|
||||
--> $DIR/projection-unspecified-but-bounded.rs:12:11
|
||||
|
|
||||
LL | foo::<T>();
|
||||
| ^ expected `32`, found `<T as TraitWAssocConst>::A`
|
||||
|
|
||||
= note: expected constant `32`
|
||||
found constant `<T as TraitWAssocConst>::A`
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/projection-unspecified-but-bounded.rs:9:28
|
||||
|
|
||||
LL | fn foo<T: TraitWAssocConst<A = 32>>() {}
|
||||
| ^^^^^^ required by this bound in `foo`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
16
tests/ui/proc-macro/test-same-crate.rs
Normal file
16
tests/ui/proc-macro/test-same-crate.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// compile-flags: --test
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro]
|
||||
pub fn mac(input: TokenStream) -> TokenStream { loop {} }
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn t() { crate::mac!(A) }
|
||||
//~^ ERROR can't use a procedural macro from the same crate that defines it
|
||||
//~| HELP you can define integration tests in a directory named `tests`
|
||||
}
|
||||
10
tests/ui/proc-macro/test-same-crate.stderr
Normal file
10
tests/ui/proc-macro/test-same-crate.stderr
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
error: can't use a procedural macro from the same crate that defines it
|
||||
--> $DIR/test-same-crate.rs:13:14
|
||||
|
|
||||
LL | fn t() { crate::mac!(A) }
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: you can define integration tests in a directory named `tests`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue