Skip to content
Merged
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
13 changes: 12 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/stability.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::num::NonZero;

use rustc_errors::ErrorGuaranteed;
use rustc_feature::ACCEPTED_LANG_FEATURES;
use rustc_hir::target::GenericParamKind;
use rustc_hir::{
DefaultBodyStability, MethodKind, PartialConstStability, Stability, StabilityLevel,
Expand Down Expand Up @@ -366,7 +367,7 @@ pub(crate) fn parse_stability<S: Stage>(
}
}

// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable`
/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable`
/// attribute, and return the feature name and its stability information.
pub(crate) fn parse_unstability<S: Stage>(
cx: &AcceptContext<'_, '_, S>,
Expand Down Expand Up @@ -451,6 +452,16 @@ pub(crate) fn parse_unstability<S: Stage>(

match (feature, issue) {
(Ok(feature), Ok(_)) => {
// Stable *language* features shouldn't be used as unstable library features.
// (Not doing this for stable library features is checked by tidy.)
if ACCEPTED_LANG_FEATURES.iter().any(|f| f.name == feature) {
cx.emit_err(session_diagnostics::UnstableAttrForAlreadyStableFeature {
attr_span: cx.attr_span,
item_span: cx.target_span,
});
return None;
}

let level = StabilityLevel::Unstable {
reason: UnstableReason::from_opt_reason(reason),
issue: issue_num,
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1046,3 +1046,14 @@ pub(crate) struct CustomMirIncompatibleDialectAndPhase {
#[label("... is not compatible with this phase")]
pub phase_span: Span,
}

#[derive(Diagnostic)]
#[diag("can't mark as unstable using an already stable feature")]
pub(crate) struct UnstableAttrForAlreadyStableFeature {
#[primary_span]
#[label("this feature is already stable")]
#[help("consider removing the attribute")]
pub attr_span: Span,
#[label("the stability attribute annotates this item")]
pub item_span: Span,
}
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,8 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) {
// ABI bugs <https://github.com/rust-lang/rust/issues/125109> et al. (full
// list at <https://github.com/rust-lang/rust/issues/116909>)
(Arch::PowerPC | Arch::PowerPC64, _) => false,
// ABI unsupported <https://github.com/llvm/llvm-project/issues/41838>
(Arch::Sparc, _) => false,
// ABI unsupported <https://github.com/llvm/llvm-project/issues/41838> (fixed in llvm22)
(Arch::Sparc, _) if major < 22 => false,
// MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
(Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false,
// There are no known problems on other platforms, so the only requirement is that symbols
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,13 @@ pub enum PatKind<'tcx> {
pats: Box<[Pat<'tcx>]>,
},

/// A guard pattern, e.g. `x if guard(x)`
Guard {
subpattern: Box<Pat<'tcx>>,
#[type_visitable(ignore)]
condition: ExprId,
},

/// A never pattern `!`.
Never,

Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_middle/src/thir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,12 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
visitor: &mut V,
pat: &'thir Pat<'tcx>,
) {
if let PatKind::Guard { subpattern, condition } = &pat.kind {
visitor.visit_pat(subpattern);
visitor.visit_expr(&visitor.thir()[*condition]);
return;
};

for_each_immediate_subpat(pat, |p| visitor.visit_pat(p));
}

Expand Down Expand Up @@ -287,5 +293,9 @@ pub(crate) fn for_each_immediate_subpat<'a, 'tcx>(
callback(pat);
}
}

PatKind::Guard { subpattern, .. } => {
callback(subpattern);
}
}
}
5 changes: 5 additions & 0 deletions compiler/rustc_mir_build/src/builder/matches/match_pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,11 @@ impl<'tcx> MatchPairTree<'tcx> {
Some(TestableCase::Deref { temp, mutability })
}

PatKind::Guard { .. } => {
// FIXME(guard_patterns)
None
}

PatKind::Never => Some(TestableCase::Never),
};

Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_mir_build/src/builder/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
visit_subpat(self, subpattern, user_tys, f);
}
}
PatKind::Guard { ref subpattern, .. } => {
visit_subpat(self, subpattern, user_tys, f);
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
| PatKind::Range { .. }
| PatKind::Slice { .. }
| PatKind::Array { .. }
| PatKind::Guard { .. }
// Never constitutes a witness of uninhabitedness.
| PatKind::Never => {
self.requires_unsafe(pat.span, AccessToUnionField);
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_mir_build/src/thir/cx/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
}
Some(_) | None => local.span,
};
let initializer = local.init.map(|init| self.mirror_expr(init));
let stmt = Stmt {
kind: StmtKind::Let {
remainder_scope,
Expand All @@ -91,7 +92,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
data: region::ScopeData::Node,
},
pattern,
initializer: local.init.map(|init| self.mirror_expr(init)),
initializer,
else_block,
hir_id: local.hir_id,
span,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
};

let indices = self.typeck_results.offset_of_data().get(expr.hir_id).unwrap();
let mut expr = None::<ExprKind<'tcx>>;
let mut expr = None::<ExprKind<'_>>;

for &(container, variant, field) in indices.iter() {
let next = mk_call(&mut self.thir, container, variant, field);
Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_mir_build/src/thir/cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ use rustc_middle::thir::*;
use rustc_middle::ty::{self, TyCtxt};

/// Query implementation for [`TyCtxt::thir_body`].
pub(crate) fn thir_body(
tcx: TyCtxt<'_>,
pub(crate) fn thir_body<'tcx>(
tcx: TyCtxt<'tcx>,
owner_def: LocalDefId,
) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> {
) -> Result<(&'tcx Steal<Thir<'tcx>>, ExprId), ErrorGuaranteed> {
debug_assert!(!tcx.is_type_const(owner_def.to_def_id()), "thir_body queried for type_const");

let body = tcx.hir_body_owned_by(owner_def);
let mut cx = ThirBuildCx::new(tcx, owner_def);
let mut cx: ThirBuildCx<'tcx> = ThirBuildCx::new(tcx, owner_def);
if let Some(reported) = cx.typeck_results.tainted_by_errors {
return Err(reported);
}
Expand Down Expand Up @@ -50,7 +50,7 @@ pub(crate) fn thir_body(
}

/// Context for lowering HIR to THIR for a single function body (or other kind of body).
struct ThirBuildCx<'tcx> {
pub(crate) struct ThirBuildCx<'tcx> {
tcx: TyCtxt<'tcx>,
/// The THIR data that this context is building.
thir: Thir<'tcx>,
Expand Down Expand Up @@ -118,6 +118,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
let_stmt_type: Option<&hir::Ty<'tcx>>,
) -> Box<Pat<'tcx>> {
crate::thir::pattern::pat_from_hir(
self,
self.tcx,
self.typing_env,
self.typeck_results,
Expand Down Expand Up @@ -201,7 +202,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
fn_sig.inputs()[index]
};

let pat = self.pattern_from_hir(param.pat);
let pat: Box<Pat<'tcx>> = self.pattern_from_hir(param.pat);
Param { pat: Some(pat), ty, ty_span, self_kind, hir_id: Some(param.hir_id) }
})
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::errors::{
PointerPattern, TypeNotPartialEq, TypeNotStructural, UnionPattern, UnsizedPattern,
};

impl<'tcx> PatCtxt<'tcx> {
impl<'tcx, 'ptcx> PatCtxt<'tcx, 'ptcx> {
/// Converts a constant to a pattern (if possible).
/// This means aggregate values (like structs and enums) are converted
/// to a pattern that matches the value (as if you'd compared via structural equality).
Expand Down Expand Up @@ -61,7 +61,7 @@ struct ConstToPat<'tcx> {
}

impl<'tcx> ConstToPat<'tcx> {
fn new(pat_ctxt: &PatCtxt<'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self {
fn new(pat_ctxt: &PatCtxt<'tcx, '_>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self {
trace!(?pat_ctxt.typeck_results.hir_owner);
ConstToPat { tcx: pat_ctxt.tcx, typing_env: pat_ctxt.typing_env, span, id, c }
}
Expand Down
18 changes: 12 additions & 6 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ use tracing::{debug, instrument};
pub(crate) use self::check_match::check_match;
use self::migration::PatMigration;
use crate::errors::*;
use crate::thir::cx::ThirBuildCx;

/// Context for lowering HIR patterns to THIR patterns.
struct PatCtxt<'tcx> {
struct PatCtxt<'tcx, 'ptcx> {
upper: &'ptcx mut ThirBuildCx<'tcx>,
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
typeck_results: &'tcx ty::TypeckResults<'tcx>,
Expand All @@ -41,8 +43,9 @@ struct PatCtxt<'tcx> {
rust_2024_migration: Option<PatMigration<'tcx>>,
}

#[instrument(level = "debug", skip(tcx, typing_env, typeck_results), ret)]
pub(super) fn pat_from_hir<'tcx>(
#[instrument(level = "debug", skip(upper, tcx, typing_env, typeck_results), ret)]
pub(super) fn pat_from_hir<'tcx, 'ptcx>(
upper: &'ptcx mut ThirBuildCx<'tcx>,
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
typeck_results: &'tcx ty::TypeckResults<'tcx>,
Expand All @@ -51,6 +54,7 @@ pub(super) fn pat_from_hir<'tcx>(
let_stmt_type: Option<&hir::Ty<'tcx>>,
) -> Box<Pat<'tcx>> {
let mut pcx = PatCtxt {
upper,
tcx,
typing_env,
typeck_results,
Expand Down Expand Up @@ -87,7 +91,7 @@ pub(super) fn pat_from_hir<'tcx>(
thir_pat
}

impl<'tcx> PatCtxt<'tcx> {
impl<'tcx, 'ptcx> PatCtxt<'tcx, 'ptcx> {
fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
let adjustments: &[PatAdjustment<'tcx>] =
self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
Expand Down Expand Up @@ -443,8 +447,10 @@ impl<'tcx> PatCtxt<'tcx> {

hir::PatKind::Or(pats) => PatKind::Or { pats: self.lower_patterns(pats) },

// FIXME(guard_patterns): implement guard pattern lowering
hir::PatKind::Guard(pat, _) => self.lower_pattern(pat).kind,
hir::PatKind::Guard(pat, condition) => PatKind::Guard {
subpattern: self.lower_pattern(pat),
condition: self.upper.mirror_expr(condition),
},

hir::PatKind::Err(guar) => PatKind::Error(guar),
};
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_mir_build/src/thir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,14 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
print_indented!(self, "]", depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Guard { subpattern, condition } => {
print_indented!(self, "Guard pattern: {", depth_lvl + 1);
print_indented!(self, "subpattern: ", depth_lvl + 2);
self.print_pat(subpattern, depth_lvl + 3);
print_indented!(self, "guard: ", depth_lvl + 2);
self.print_expr(*condition, depth_lvl + 3);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Error(_) => {
print_indented!(self, "Error", depth_lvl + 1);
}
Expand Down
38 changes: 4 additions & 34 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_data_structures::unord::UnordMap;
use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey, msg};
use rustc_feature::{
ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP,
BuiltinAttribute,
};
use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
use rustc_hir::attrs::diagnostic::Directive;
use rustc_hir::attrs::{
AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, InlineAttr,
Expand All @@ -30,8 +27,7 @@ use rustc_hir::def_id::LocalModDefId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{
self as hir, Attribute, CRATE_HIR_ID, Constness, FnSig, ForeignItem, GenericParamKind, HirId,
Item, ItemKind, MethodKind, Node, ParamName, PartialConstStability, Safety, Stability,
StabilityLevel, Target, TraitItem, find_attr,
Item, ItemKind, MethodKind, Node, ParamName, Safety, Target, TraitItem, find_attr,
};
use rustc_macros::Diagnostic;
use rustc_middle::hir::nested_filter;
Expand Down Expand Up @@ -156,16 +152,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
Attribute::Parsed(AttributeKind::ProcMacroDerive { .. }) => {
self.check_proc_macro(hir_id, target, ProcMacroKind::Derive)
}
Attribute::Parsed(
AttributeKind::Stability {
span: attr_span,
stability: Stability { level, feature },
}
| AttributeKind::RustcConstStability {
span: attr_span,
stability: PartialConstStability { level, feature, .. },
},
) => self.check_stability(*attr_span, span, level, *feature),
Attribute::Parsed(AttributeKind::Inline(InlineAttr::Force { .. }, ..)) => {} // handled separately below
Attribute::Parsed(AttributeKind::Inline(kind, attr_span)) => {
self.check_inline(hir_id, *attr_span, kind, target)
Expand Down Expand Up @@ -312,6 +298,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcCoherenceIsCore(..)
| AttributeKind::RustcCoinductive(..)
| AttributeKind::RustcConfusables { .. }
| AttributeKind::RustcConstStability { .. }
| AttributeKind::RustcConstStableIndirect
| AttributeKind::RustcConversionSuggestion
| AttributeKind::RustcDeallocator
Expand Down Expand Up @@ -384,6 +371,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcTrivialFieldReads
| AttributeKind::RustcUnsafeSpecializationMarker(..)
| AttributeKind::ShouldPanic { .. }
| AttributeKind::Stability { .. }
| AttributeKind::TestRunner(..)
| AttributeKind::ThreadLocal
| AttributeKind::TypeLengthLimit { .. }
Expand Down Expand Up @@ -1570,24 +1558,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}

fn check_stability(
&self,
attr_span: Span,
item_span: Span,
level: &StabilityLevel,
feature: Symbol,
) {
// Stable *language* features shouldn't be used as unstable library features.
// (Not doing this for stable library features is checked by tidy.)
if level.is_unstable()
&& ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some()
{
self.tcx
.dcx()
.emit_err(errors::UnstableAttrForAlreadyStableFeature { attr_span, item_span });
}
}

fn check_deprecated(&self, hir_id: HirId, attr_span: Span, target: Target) {
match target {
Target::AssocConst | Target::Method(..) | Target::AssocTy
Expand Down
11 changes: 0 additions & 11 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -871,17 +871,6 @@ pub(crate) struct CannotStabilizeDeprecated {
pub item_sp: Span,
}

#[derive(Diagnostic)]
#[diag("can't mark as unstable using an already stable feature")]
pub(crate) struct UnstableAttrForAlreadyStableFeature {
#[primary_span]
#[label("this feature is already stable")]
#[help("consider removing the attribute")]
pub attr_span: Span,
#[label("the stability attribute annotates this item")]
pub item_span: Span,
}

#[derive(Diagnostic)]
#[diag("{$descr} has missing stability attribute")]
pub(crate) struct MissingStabilityAttr<'a> {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_pattern_analysis/src/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
let arity;
let fields: Vec<_>;
match &pat.kind {
PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat),
PatKind::Binding { subpattern: Some(subpat), .. }
| PatKind::Guard { subpattern: subpat, .. } => return self.lower_pat(subpat),
PatKind::Missing | PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
ctor = Wildcard;
fields = vec![];
Expand Down
Loading
Loading