Skip to content

Commit

Permalink
Auto merge of rust-lang#132626 - workingjubilee:rollup-hbmtbzk, r=wor…
Browse files Browse the repository at this point in the history
…kingjubilee

Rollup of 11 pull requests

Successful merges:

 - rust-lang#131153 (Improve duplicate derive Copy/Clone diagnostics)
 - rust-lang#132025 (fix suggestion for diagnostic error E0027)
 - rust-lang#132303 (More tests for non-exhaustive C-like enums in FFI)
 - rust-lang#132492 (remove support for extern-block const intrinsics)
 - rust-lang#132587 (Revert "Avoid nested replacement ranges" from rust-lang#129346.)
 - rust-lang#132596 ([rustdoc] Fix `--show-coverage` when JSON output format is used)
 - rust-lang#132598 (Clippy: Move some attribute lints to be early pass (post expansion))
 - rust-lang#132601 (Update books)
 - rust-lang#132606 (Improve example of `impl Pattern for &[char]`)
 - rust-lang#132608 (document `type_implements_trait`)
 - rust-lang#132609 (docs: fix grammar in doc comment at unix/process.rs)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Nov 5, 2024
2 parents 96477c5 + 7bff6ff commit 27e38f8
Show file tree
Hide file tree
Showing 82 changed files with 1,705 additions and 1,401 deletions.
10 changes: 3 additions & 7 deletions compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,7 @@ pub fn find_stability(
/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable`
/// attributes in `attrs`. Returns `None` if no stability attributes are found.
///
/// `is_const_fn` indicates whether this is a function marked as `const`. It will always
/// be false for intrinsics in an `extern` block!
/// `is_const_fn` indicates whether this is a function marked as `const`.
pub fn find_const_stability(
sess: &Session,
attrs: &[Attribute],
Expand Down Expand Up @@ -330,7 +329,7 @@ pub fn find_const_stability(
}
}

// Merge promotable and not_exposed_on_stable into stability info
// Merge promotable and const_stable_indirect into stability info
if promotable {
match &mut const_stab {
Some((stab, _)) => stab.promotable = promotable,
Expand All @@ -352,10 +351,7 @@ pub fn find_const_stability(
})
}
}
_ => {
// We ignore the `#[rustc_const_stable_indirect]` here, it should be picked up by
// the `default_const_unstable` logic.
}
_ => {}
}
}
// Make sure if `const_stable_indirect` is present, that is recorded. Also make sure all `const
Expand Down
17 changes: 17 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_middle::ty::{self, Ty};
use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex};
use rustc_span::{BytePos, ExpnKind, MacroKind, Span};
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
use rustc_trait_selection::infer::InferCtxtExt;
use tracing::debug;

use crate::MirBorrowckCtxt;
Expand Down Expand Up @@ -267,6 +268,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
kind,
self.is_upvar_field_projection(original_path.as_ref())
);
if self.has_ambiguous_copy(original_path.ty(self.body, self.infcx.tcx).ty) {
// If the type may implement Copy, skip the error.
// It's an error with the Copy implementation (e.g. duplicate Copy) rather than borrow check
self.dcx().span_delayed_bug(
span,
"Type may implement copy, but there is no other error.",
);
return;
}
(
match kind {
&IllegalMoveOriginKind::BorrowedContent { target_place } => self
Expand All @@ -291,6 +301,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
self.buffer_error(err);
}

fn has_ambiguous_copy(&mut self, ty: Ty<'tcx>) -> bool {
let Some(copy_trait_def) = self.infcx.tcx.lang_items().copy_trait() else { return false };
// This is only going to be ambiguous if there are incoherent impls, because otherwise
// ambiguity should never happen in MIR.
self.infcx.type_implements_trait(copy_trait_def, [ty], self.param_env).may_apply()
}

fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'infcx> {
let description = if place.projection.len() == 1 {
format!("static item {}", self.describe_any_place(place.as_ref()))
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ const_eval_uninhabited_enum_variant_written =
const_eval_unmarked_const_fn_exposed = `{$def_path}` cannot be (indirectly) exposed to stable
.help = either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`
const_eval_unmarked_intrinsic_exposed = intrinsic `{$def_path}` cannot be (indirectly) exposed to stable
.help = mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_indirect]` (but this requires team approval)
.help = mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
const_eval_unreachable = entering unreachable code
const_eval_unreachable_unwind =
Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,16 +736,25 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {

// Intrinsics are language primitives, not regular calls, so treat them separately.
if let Some(intrinsic) = tcx.intrinsic(callee) {
// We use `intrinsic.const_stable` to determine if this can be safely exposed to
// stable code, rather than `const_stable_indirect`. This is to make
// `#[rustc_const_stable_indirect]` an attribute that is always safe to add.
// We also ask is_safe_to_expose_on_stable_const_fn; this determines whether the intrinsic
// fallback body is safe to expose on stable.
let is_const_stable = intrinsic.const_stable
|| (!intrinsic.must_be_overridden
&& tcx.is_const_fn(callee)
&& is_safe_to_expose_on_stable_const_fn(tcx, callee));
match tcx.lookup_const_stability(callee) {
None => {
// Non-const intrinsic.
self.check_op(ops::IntrinsicNonConst { name: intrinsic.name });
}
Some(ConstStability { feature: None, const_stable_indirect, .. }) => {
Some(ConstStability { feature: None, .. }) => {
// Intrinsic does not need a separate feature gate (we rely on the
// regular stability checker). However, we have to worry about recursive
// const stability.
if !const_stable_indirect && self.enforce_recursive_const_stability() {
if !is_const_stable && self.enforce_recursive_const_stability() {
self.dcx().emit_err(errors::UnmarkedIntrinsicExposed {
span: self.span,
def_path: self.tcx.def_path_str(callee),
Expand All @@ -755,17 +764,19 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
Some(ConstStability {
feature: Some(feature),
level: StabilityLevel::Unstable { .. },
const_stable_indirect,
..
}) => {
self.check_op(ops::IntrinsicUnstable {
name: intrinsic.name,
feature,
const_stable_indirect,
const_stable: is_const_stable,
});
}
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
// All good.
// All good. Note that a `#[rustc_const_stable]` intrinsic (meaning it
// can be *directly* invoked from stable const code) does not always
// have the `#[rustc_const_stable_intrinsic]` attribute (which controls
// exposing an intrinsic indirectly); we accept this call anyway.
}
}
// This completes the checks for intrinsics.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,14 +354,14 @@ impl<'tcx> NonConstOp<'tcx> for IntrinsicNonConst {
pub(crate) struct IntrinsicUnstable {
pub name: Symbol,
pub feature: Symbol,
pub const_stable_indirect: bool,
pub const_stable: bool,
}

impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable {
fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
Status::Unstable {
gate: self.feature,
safe_to_expose_on_stable: self.const_stable_indirect,
safe_to_expose_on_stable: self.const_stable,
// We do *not* want to suggest to mark the intrinsic as `const_stable_indirect`,
// that's not a trivial change!
is_function_call: false,
Expand Down
12 changes: 3 additions & 9 deletions compiler/rustc_const_eval/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,9 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
hir::Constness::Const
}
hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
// Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
// foreign items cannot be evaluated at compile-time.
let is_const = if tcx.intrinsic(def_id).is_some() {
tcx.lookup_const_stability(def_id).is_some()
} else {
false
};
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
hir::Node::ForeignItem(_) => {
// Foreign items cannot be evaluated at compile-time.
hir::Constness::NotConst
}
hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness,
_ => {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_const_stable_indirect, Normal,
template!(Word), WarnFollowing, EncodeCrossCrate::No, IMPL_DETAIL,
),
rustc_attr!(
rustc_const_stable_intrinsic, Normal,
template!(Word), WarnFollowing, EncodeCrossCrate::No, IMPL_DETAIL,
),
gated!(
rustc_allow_const_fn_unstable, Normal,
template!(Word, List: "feat1, feat2, ..."), DuplicatesOk, EncodeCrossCrate::No,
Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2071,6 +2071,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
s = pluralize!(len),
them = if len == 1 { "it" } else { "them" },
),
format!(
"{}{}{}{}",
prefix,
unmentioned_fields
.iter()
.map(|(_, name)| {
let field_name = name.to_string();
format!("{field_name}: _")
})
.collect::<Vec<_>>()
.join(", "),
if have_inaccessible_fields { ", .." } else { "" },
postfix,
),
Applicability::MachineApplicable,
);
err.span_suggestion(
sp,
"or always ignore missing fields here",
format!("{prefix}..{postfix}"),
Applicability::MachineApplicable,
);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ pub struct IntrinsicDef {
pub name: Symbol,
/// Whether the intrinsic has no meaningful body and all backends need to shim all calls to it.
pub must_be_overridden: bool,
/// Whether the intrinsic can be invoked from stable const fn
pub const_stable: bool,
}

impl TyCtxt<'_> {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,7 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Intrinsi
Some(ty::IntrinsicDef {
name: tcx.item_name(def_id.into()),
must_be_overridden: tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden),
const_stable: tcx.has_attr(def_id, sym::rustc_const_stable_intrinsic),
})
} else {
None
Expand Down
28 changes: 21 additions & 7 deletions compiler/rustc_parse/src/parser/attr_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,30 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
node_replacements.array_windows()
{
assert!(
node_range.0.end <= next_node_range.0.start,
"Node ranges should be disjoint: ({:?}, {:?}) ({:?}, {:?})",
node_range.0.end <= next_node_range.0.start
|| node_range.0.end >= next_node_range.0.end,
"Node ranges should be disjoint or nested: ({:?}, {:?}) ({:?}, {:?})",
node_range,
tokens,
next_node_range,
next_tokens,
);
}

// Process the replace ranges.
for (node_range, target) in node_replacements.into_iter() {
// Process the replace ranges, starting from the highest start
// position and working our way back. If have tokens like:
//
// `#[cfg(FALSE)] struct Foo { #[cfg(FALSE)] field: bool }`
//
// Then we will generate replace ranges for both
// the `#[cfg(FALSE)] field: bool` and the entire
// `#[cfg(FALSE)] struct Foo { #[cfg(FALSE)] field: bool }`
//
// By starting processing from the replace range with the greatest
// start position, we ensure that any (outer) replace range which
// encloses another (inner) replace range will fully overwrite the
// inner range's replacement.
for (node_range, target) in node_replacements.into_iter().rev() {
assert!(
!node_range.0.is_empty(),
"Cannot replace an empty node range: {:?}",
Expand Down Expand Up @@ -383,9 +396,10 @@ impl<'a> Parser<'a> {
// from `ParserRange` form to `NodeRange` form. We will perform the actual
// replacement only when we convert the `LazyAttrTokenStream` to an
// `AttrTokenStream`.
self.capture_state
.parser_replacements
.drain(parser_replacements_start..parser_replacements_end)
self.capture_state.parser_replacements
[parser_replacements_start..parser_replacements_end]
.iter()
.cloned()
.chain(inner_attr_parser_replacements)
.map(|(parser_range, data)| {
(NodeRange::new(parser_range, collect_pos.start_pos), data)
Expand Down
15 changes: 0 additions & 15 deletions compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
def_id: LocalDefId,
item_sp: Span,
fn_sig: Option<&'tcx hir::FnSig<'tcx>>,
is_foreign_item: bool,
kind: AnnotationKind,
inherit_deprecation: InheritDeprecation,
inherit_const_stability: InheritConstStability,
Expand Down Expand Up @@ -175,11 +174,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
// implied), check if the function/method is const or the parent impl block is const.
if let Some(fn_sig) = fn_sig
&& !fn_sig.header.is_const()
// We have to exclude foreign items as they might be intrinsics. Sadly we can't check
// their ABI; `fn_sig.abi` is *not* correct for foreign functions.
&& !is_foreign_item
&& const_stab.is_some()
&& (!self.in_trait_impl || !self.tcx.is_const_fn(def_id.to_def_id()))
{
self.tcx.dcx().emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span });
}
Expand Down Expand Up @@ -398,7 +393,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
ctor_def_id,
i.span,
None,
/* is_foreign_item */ false,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
Expand All @@ -417,7 +411,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
i.owner_id.def_id,
i.span,
fn_sig,
/* is_foreign_item */ false,
kind,
InheritDeprecation::Yes,
const_stab_inherit,
Expand All @@ -437,7 +430,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
ti.owner_id.def_id,
ti.span,
fn_sig,
/* is_foreign_item */ false,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
Expand All @@ -461,7 +453,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
ii.owner_id.def_id,
ii.span,
fn_sig,
/* is_foreign_item */ false,
kind,
InheritDeprecation::Yes,
InheritConstStability::No,
Expand All @@ -477,7 +468,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
var.def_id,
var.span,
None,
/* is_foreign_item */ false,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
Expand All @@ -488,7 +478,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
ctor_def_id,
var.span,
None,
/* is_foreign_item */ false,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
Expand All @@ -507,7 +496,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
s.def_id,
s.span,
None,
/* is_foreign_item */ false,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
Expand All @@ -527,7 +515,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
i.owner_id.def_id,
i.span,
fn_sig,
/* is_foreign_item */ true,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
Expand All @@ -550,7 +537,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
p.def_id,
p.span,
None,
/* is_foreign_item */ false,
kind,
InheritDeprecation::No,
InheritConstStability::No,
Expand Down Expand Up @@ -712,7 +698,6 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
CRATE_DEF_ID,
tcx.hir().span(CRATE_HIR_ID),
None,
/* is_foreign_item */ false,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1663,6 +1663,7 @@ symbols! {
rustc_const_panic_str,
rustc_const_stable,
rustc_const_stable_indirect,
rustc_const_stable_intrinsic,
rustc_const_unstable,
rustc_conversion_suggestion,
rustc_deallocator,
Expand Down
Loading

0 comments on commit 27e38f8

Please sign in to comment.