Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3684,7 +3684,6 @@ dependencies = [
"rustc_macros",
"rustc_metadata",
"rustc_middle",
"rustc_query_system",
"rustc_serialize",
"rustc_session",
"rustc_span",
Expand Down Expand Up @@ -4337,11 +4336,11 @@ dependencies = [
"polonius-engine",
"regex",
"rustc_abi",
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_graphviz",
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_middle",
Expand Down
93 changes: 91 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::path::PathBuf;

use rustc_ast::{LitIntType, LitKind, MetaItemLit};
use rustc_hir::attrs::RustcLayoutType;
use rustc_hir::attrs::{BorrowckGraphvizFormatKind, RustcLayoutType, RustcMirKind};
use rustc_session::errors;

use super::prelude::*;
Expand Down Expand Up @@ -357,7 +359,6 @@ impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser {

const TEMPLATE: AttributeTemplate =
template!(List: &["abi", "align", "size", "homogenous_aggregate", "debug"]);

fn extend(
cx: &mut AcceptContext<'_, '_, S>,
args: &ArgParser,
Expand Down Expand Up @@ -397,6 +398,94 @@ impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser {
}
}

pub(crate) struct RustcMirParser;

impl<S: Stage> CombineAttributeParser<S> for RustcMirParser {
const PATH: &[rustc_span::Symbol] = &[sym::rustc_mir];

type Item = RustcMirKind;

const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcMir(items);

const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Method(MethodKind::Trait { body: false })),
Allow(Target::Method(MethodKind::Trait { body: true })),
]);

const TEMPLATE: AttributeTemplate = template!(List: &["arg1, arg2, ..."]);

fn extend(
cx: &mut AcceptContext<'_, '_, S>,
args: &ArgParser,
) -> impl IntoIterator<Item = Self::Item> {
let Some(list) = args.list() else {
cx.expected_list(cx.attr_span, args);
return ThinVec::new();
};

list.mixed()
.filter_map(|arg| arg.meta_item())
.filter_map(|mi| {
if let Some(ident) = mi.ident() {
match ident.name {
sym::rustc_peek_maybe_init => Some(RustcMirKind::PeekMaybeInit),
sym::rustc_peek_maybe_uninit => Some(RustcMirKind::PeekMaybeUninit),
sym::rustc_peek_liveness => Some(RustcMirKind::PeekLiveness),
sym::stop_after_dataflow => Some(RustcMirKind::StopAfterDataflow),
sym::borrowck_graphviz_postflow => {
let Some(nv) = mi.args().name_value() else {
cx.expected_name_value(
mi.span(),
Some(sym::borrowck_graphviz_postflow),
);
return None;
};
let Some(path) = nv.value_as_str() else {
cx.expected_string_literal(nv.value_span, None);
return None;
};
let path = PathBuf::from(path.to_string());
if path.file_name().is_some() {
Some(RustcMirKind::BorrowckGraphvizPostflow { path })
} else {
cx.expected_filename_literal(nv.value_span);
None
}
}
sym::borrowck_graphviz_format => {
let Some(nv) = mi.args().name_value() else {
cx.expected_name_value(
mi.span(),
Some(sym::borrowck_graphviz_format),
);
return None;
};
let Some(format) = nv.value_as_ident() else {
cx.expected_identifier(nv.value_span);
return None;
};
match format.name {
sym::two_phase => Some(RustcMirKind::BorrowckGraphvizFormat {
format: BorrowckGraphvizFormatKind::TwoPhase,
}),
_ => {
cx.expected_specific_argument(format.span, &[sym::two_phase]);
None
}
}
}
_ => None,
}
} else {
None
}
})
.collect()
}
}
pub(crate) struct RustcNonConstTraitMethodParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcNonConstTraitMethodParser {
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ use crate::attributes::rustc_internal::{
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser,
RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser,
RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser,
RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser,
RustcMirParser, RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser,
RustcNoImplicitAutorefsParser, RustcNonConstTraitMethodParser, RustcNounwindParser,
RustcObjectLifetimeDefaultParser, RustcOffloadKernelParser, RustcScalableVectorParser,
RustcSimdMonomorphizeLaneLimitParser,
Expand Down Expand Up @@ -202,6 +202,7 @@ attribute_parsers!(
Combine<LinkParser>,
Combine<ReprParser>,
Combine<RustcLayoutParser>,
Combine<RustcMirParser>,
Combine<TargetFeatureParser>,
Combine<UnstableFeatureBoundParser>,
// tidy-alphabetical-end
Expand Down Expand Up @@ -517,6 +518,11 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
)
}

/// Error that a filename string literal was expected.
pub(crate) fn expected_filename_literal(&self, span: Span) {
self.emit_parse_error(span, AttributeParseErrorReason::ExpectedFilenameLiteral);
}

pub(crate) fn expected_integer_literal(&self, span: Span) -> ErrorGuaranteed {
self.emit_parse_error(span, AttributeParseErrorReason::ExpectedIntegerLiteral)
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,7 @@ pub(crate) enum AttributeParseErrorReason<'a> {
ExpectedStringLiteral {
byte_string: Option<Span>,
},
ExpectedFilenameLiteral,
ExpectedIntegerLiteral,
ExpectedIntegerLiteralInRange {
lower_bound: isize,
Expand Down Expand Up @@ -597,6 +598,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
diag.span_label(self.span, "expected a string literal here");
}
}
AttributeParseErrorReason::ExpectedFilenameLiteral => {
diag.span_label(self.span, "expected a filename string literal here");
}
AttributeParseErrorReason::ExpectedIntegerLiteral => {
diag.span_label(self.span, "expected an integer literal here");
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_codegen_ssa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ rustc_lint_defs = { path = "../rustc_lint_defs" }
rustc_macros = { path = "../rustc_macros" }
rustc_metadata = { path = "../rustc_metadata" }
rustc_middle = { path = "../rustc_middle" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use rustc_data_structures::unord::UnordMap;
use rustc_hir::CRATE_HIR_ID;
use rustc_hir::attrs::{CfgEntry, NativeLibKind, WindowsSubsystemKind};
use rustc_hir::def_id::CrateNum;
use rustc_macros::{Decodable, Encodable, HashStable};
use rustc_macros::{Decodable, Encodable};
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::lint::LevelAndSource;
Expand Down Expand Up @@ -175,7 +175,12 @@ bitflags::bitflags! {
}
}

#[derive(Clone, Debug, Encodable, Decodable, HashStable)]
// This is the same as `rustc_session::cstore::NativeLib`, except:
// - (important) the `foreign_module` field is missing, because it contains a `DefId`, which can't
// be encoded with `FileEncoder`.
// - (less important) the `verbatim` field is a `bool` rather than an `Option<bool>`, because here
// we can treat `false` and `absent` the same.
#[derive(Clone, Debug, Encodable, Decodable)]
pub struct NativeLib {
pub kind: NativeLibKind,
pub name: Symbol,
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,21 @@ pub enum RustcLayoutType {
Debug,
}

#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute, PartialEq, Eq)]
pub enum RustcMirKind {
PeekMaybeInit,
PeekMaybeUninit,
PeekLiveness,
StopAfterDataflow,
BorrowckGraphvizPostflow { path: PathBuf },
BorrowckGraphvizFormat { format: BorrowckGraphvizFormatKind },
}

#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute, PartialEq, Eq)]
pub enum BorrowckGraphvizFormatKind {
TwoPhase,
}

/// Represents parsed *built-in* inert attributes.
///
/// ## Overview
Expand Down Expand Up @@ -1090,6 +1105,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_main]`.
RustcMain,

/// Represents `#[rustc_mir]`.
RustcMir(ThinVec<RustcMirKind>),

/// Represents `#[rustc_must_implement_one_of]`
RustcMustImplementOneOf { attr_span: Span, fn_names: ThinVec<Ident> },

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ impl AttributeKind {
RustcLintUntrackedQueryInformation => Yes,
RustcMacroTransparency(..) => Yes,
RustcMain => No,
RustcMir(..) => Yes,
RustcMustImplementOneOf { .. } => No,
RustcNeverReturnsNullPointer => Yes,
RustcNoImplicitAutorefs => Yes,
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_hir/src/attrs/pretty_printing.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::num::NonZero;
use std::ops::Deref;
use std::path::PathBuf;

use rustc_abi::Align;
use rustc_ast::attr::data_structures::CfgEntry;
Expand Down Expand Up @@ -96,7 +97,15 @@ impl<T: PrintAttribute> PrintAttribute for FxIndexMap<T, Span> {
p.word("]");
}
}
impl PrintAttribute for PathBuf {
fn should_render(&self) -> bool {
true
}

fn print_attribute(&self, p: &mut Printer) {
p.word(self.display().to_string());
}
}
macro_rules! print_skip {
($($t: ty),* $(,)?) => {$(
impl PrintAttribute for $t {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a par
hir_analysis_impl_not_marked_default_err = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
.note = parent implementation is in crate `{$cname}`
hir_analysis_impl_unpin_for_pin_projected_type = explicit impls for the `Unpin` trait are not permitted for structurally pinned types
.label = impl of `Unpin` not allowed
.help = `{$adt_name}` is structurally pinned because it is marked as `#[pin_v2]`
hir_analysis_inherent_dyn = cannot define inherent `impl` for a dyn auto trait
.label = impl requires at least one non-auto trait
.note = define and implement a new trait or type instead
Expand Down
36 changes: 36 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub(super) fn check_trait<'tcx>(
checker.check(lang_items.drop_trait(), visit_implementation_of_drop)?;
checker.check(lang_items.async_drop_trait(), visit_implementation_of_drop)?;
checker.check(lang_items.copy_trait(), visit_implementation_of_copy)?;
checker.check(lang_items.unpin_trait(), visit_implementation_of_unpin)?;
checker.check(lang_items.const_param_ty_trait(), |checker| {
visit_implementation_of_const_param_ty(checker)
})?;
Expand Down Expand Up @@ -134,6 +135,41 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
}
}

fn visit_implementation_of_unpin(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
let tcx = checker.tcx;
let impl_header = checker.impl_header;
let impl_did = checker.impl_def_id;
debug!("visit_implementation_of_unpin: impl_did={:?}", impl_did);

let self_type = impl_header.trait_ref.instantiate_identity().self_ty();
debug!("visit_implementation_of_unpin: self_type={:?}", self_type);

let span = tcx.def_span(impl_did);

if tcx.features().pin_ergonomics() {
match self_type.kind() {
// Soundness concerns: a type `T` annotated with `#[pin_v2]` is allowed to project
// `Pin<&mut T>` to its field `Pin<&mut U>` safely (even if `U: !Unpin`).
// If `T` is allowed to impl `Unpin` manually (note that `Unpin` is a safe trait,
// which cannot carry safety properties), then `&mut U` could be obtained from
// `&mut T` that dereferenced by `Pin<&mut T>`, which breaks the safety contract of
// `Pin<&mut U>` for `U: !Unpin`.
ty::Adt(adt, _) if adt.is_pin_project() => {
return Err(tcx.dcx().emit_err(crate::errors::ImplUnpinForPinProjectedType {
span,
adt_span: tcx.def_span(adt.did()),
adt_name: tcx.item_name(adt.did()),
}));
}
ty::Adt(_, _) => {}
_ => {
return Err(tcx.dcx().span_delayed_bug(span, "impl of `Unpin` for a non-adt type"));
}
};
}
Ok(())
}

fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
let tcx = checker.tcx;
let header = checker.impl_header;
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1690,3 +1690,14 @@ pub(crate) struct EiiWithGenerics {
pub eii_name: Symbol,
pub impl_name: Symbol,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_impl_unpin_for_pin_projected_type)]
pub(crate) struct ImplUnpinForPinProjectedType {
#[primary_span]
#[label]
pub span: Span,
#[help]
pub adt_span: Span,
pub adt_name: Symbol,
}
8 changes: 8 additions & 0 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,14 @@ fn typeck_with_inspect<'tcx>(
let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code);

if let hir::Node::AnonConst(_) = node {
fcx.require_type_is_sized(
expected_type,
body.value.span,
ObligationCauseCode::SizedConstOrStatic,
);
}

fcx.check_expr_coercible_to_type(body.value, expected_type, None);

fcx.write_ty(id, expected_type);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_dataflow/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ edition = "2024"
polonius-engine = "0.13.0"
regex = "1"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_graphviz = { path = "../rustc_graphviz" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
Expand Down
12 changes: 0 additions & 12 deletions compiler/rustc_mir_dataflow/messages.ftl
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
mir_dataflow_duplicate_values_for =
duplicate values for `{$name}`

mir_dataflow_path_must_end_in_filename =
path must end in a filename

mir_dataflow_peek_argument_not_a_local =
rustc_peek: argument was not a local

Expand All @@ -19,11 +13,5 @@ mir_dataflow_peek_must_be_not_temporary =
mir_dataflow_peek_must_be_place_or_ref_place =
rustc_peek: argument expression must be either `place` or `&place`

mir_dataflow_requires_an_argument =
`{$name}` requires an argument

mir_dataflow_stop_after_dataflow_ended_compilation =
stop_after_dataflow ended compilation

mir_dataflow_unknown_formatter =
unknown formatter
Loading
Loading