diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 373c0ebcc5cba..ad92bf2cd4071 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -233,8 +233,7 @@ pub const PREC_JUMP: i8 = -30; pub const PREC_RANGE: i8 = -10; // The range 2..=14 is reserved for AssocOp binary operator precedences. pub const PREC_PREFIX: i8 = 50; -pub const PREC_POSTFIX: i8 = 60; -pub const PREC_PAREN: i8 = 99; +pub const PREC_UNAMBIGUOUS: i8 = 60; pub const PREC_FORCE_PAREN: i8 = 100; #[derive(Debug, Clone, Copy)] @@ -325,37 +324,35 @@ impl ExprPrecedence { | ExprPrecedence::Let | ExprPrecedence::Unary => PREC_PREFIX, - // Unary, postfix - ExprPrecedence::Await + // Never need parens + ExprPrecedence::Array + | ExprPrecedence::Await + | ExprPrecedence::Block | ExprPrecedence::Call - | ExprPrecedence::MethodCall + | ExprPrecedence::ConstBlock | ExprPrecedence::Field + | ExprPrecedence::ForLoop + | ExprPrecedence::FormatArgs + | ExprPrecedence::Gen + | ExprPrecedence::If | ExprPrecedence::Index - | ExprPrecedence::Try | ExprPrecedence::InlineAsm + | ExprPrecedence::Lit + | ExprPrecedence::Loop | ExprPrecedence::Mac - | ExprPrecedence::FormatArgs + | ExprPrecedence::Match + | ExprPrecedence::MethodCall | ExprPrecedence::OffsetOf - | ExprPrecedence::PostfixMatch => PREC_POSTFIX, - - // Never need parens - ExprPrecedence::Array + | ExprPrecedence::Paren + | ExprPrecedence::Path + | ExprPrecedence::PostfixMatch | ExprPrecedence::Repeat + | ExprPrecedence::Struct + | ExprPrecedence::Try + | ExprPrecedence::TryBlock | ExprPrecedence::Tup - | ExprPrecedence::Lit - | ExprPrecedence::Path - | ExprPrecedence::Paren - | ExprPrecedence::If | ExprPrecedence::While - | ExprPrecedence::ForLoop - | ExprPrecedence::Loop - | ExprPrecedence::Match - | ExprPrecedence::ConstBlock - | ExprPrecedence::Block - | ExprPrecedence::TryBlock - | ExprPrecedence::Gen - | ExprPrecedence::Struct - | ExprPrecedence::Err => PREC_PAREN, + | ExprPrecedence::Err => PREC_UNAMBIGUOUS, } } } diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index d9dd0b3bca534..678cac210f413 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -66,14 +66,18 @@ impl<'hir> LoweringContext<'_, 'hir> { let Ok(sig_id) = sig_id else { return false; }; - if let Some(local_sig_id) = sig_id.as_local() { + self.has_self(sig_id, span) + } + + fn has_self(&self, def_id: DefId, span: Span) -> bool { + if let Some(local_sig_id) = def_id.as_local() { // The value may be missing due to recursive delegation. // Error will be emmited later during HIR ty lowering. self.resolver.delegation_fn_sigs.get(&local_sig_id).map_or(false, |sig| sig.has_self) } else { - match self.tcx.def_kind(sig_id) { + match self.tcx.def_kind(def_id) { DefKind::Fn => false, - DefKind::AssocFn => self.tcx.associated_item(sig_id).fn_has_self_parameter, + DefKind::AssocFn => self.tcx.associated_item(def_id).fn_has_self_parameter, _ => span_bug!(span, "unexpected DefKind for delegation item"), } } @@ -107,12 +111,17 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, ) -> Result { let sig_id = if self.is_in_trait_impl { item_id } else { path_id }; - let sig_id = - self.resolver.get_partial_res(sig_id).and_then(|r| r.expect_full_res().opt_def_id()); - sig_id.ok_or_else(|| { - self.tcx - .dcx() - .span_delayed_bug(span, "LoweringContext: couldn't resolve delegation item") + self.get_resolution_id(sig_id, span) + } + + fn get_resolution_id(&self, node_id: NodeId, span: Span) -> Result { + let def_id = + self.resolver.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id()); + def_id.ok_or_else(|| { + self.tcx.dcx().span_delayed_bug( + span, + format!("LoweringContext: couldn't resolve node {:?} in delegation item", node_id), + ) }) } @@ -122,7 +131,7 @@ impl<'hir> LoweringContext<'_, 'hir> { predicates: &[], has_where_clause_predicates: false, where_clause_span: span, - span: span, + span, }) } @@ -222,12 +231,7 @@ impl<'hir> LoweringContext<'_, 'hir> { })); let path = self.arena.alloc(hir::Path { span, res: Res::Local(param_id), segments }); - - hir::Expr { - hir_id: self.next_id(), - kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)), - span, - } + self.mk_expr(hir::ExprKind::Path(hir::QPath::Resolved(None, path)), span) } fn lower_delegation_body( @@ -236,19 +240,11 @@ impl<'hir> LoweringContext<'_, 'hir> { param_count: usize, span: Span, ) -> BodyId { - let path = self.lower_qpath( - delegation.id, - &delegation.qself, - &delegation.path, - ParamMode::Optional, - ImplTraitContext::Disallowed(ImplTraitPosition::Path), - None, - ); let block = delegation.body.as_deref(); self.lower_body(|this| { - let mut parameters: Vec> = Vec::new(); - let mut args: Vec> = Vec::new(); + let mut parameters: Vec> = Vec::with_capacity(param_count); + let mut args: Vec> = Vec::with_capacity(param_count); for idx in 0..param_count { let (param, pat_node_id) = this.generate_param(span); @@ -264,11 +260,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }; self_resolver.visit_block(block); let block = this.lower_block(block, false); - hir::Expr { - hir_id: this.next_id(), - kind: hir::ExprKind::Block(block, None), - span: block.span, - } + this.mk_expr(hir::ExprKind::Block(block, None), block.span) } else { let pat_hir_id = this.lower_node_id(pat_node_id); this.generate_arg(pat_hir_id, span) @@ -276,43 +268,41 @@ impl<'hir> LoweringContext<'_, 'hir> { args.push(arg); } - let args = self.arena.alloc_from_iter(args); - let final_expr = this.generate_call(path, args); + let final_expr = this.finalize_body_lowering(delegation, args, span); (this.arena.alloc_from_iter(parameters), final_expr) }) } - fn generate_call( + // Generates fully qualified call for the resulting body. + fn finalize_body_lowering( &mut self, - path: hir::QPath<'hir>, - args: &'hir [hir::Expr<'hir>], + delegation: &Delegation, + args: Vec>, + span: Span, ) -> hir::Expr<'hir> { - let callee = self.arena.alloc(hir::Expr { - hir_id: self.next_id(), - kind: hir::ExprKind::Path(path), - span: path.span(), - }); + let path = self.lower_qpath( + delegation.id, + &delegation.qself, + &delegation.path, + ParamMode::Optional, + ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, + ); - let expr = self.arena.alloc(hir::Expr { - hir_id: self.next_id(), - kind: hir::ExprKind::Call(callee, args), - span: path.span(), - }); + let args = self.arena.alloc_from_iter(args); + let path_expr = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(path), span)); + let call = self.arena.alloc(self.mk_expr(hir::ExprKind::Call(path_expr, args), span)); let block = self.arena.alloc(hir::Block { stmts: &[], - expr: Some(expr), + expr: Some(call), hir_id: self.next_id(), rules: hir::BlockCheckMode::DefaultBlock, - span: path.span(), + span, targeted_by_break: false, }); - hir::Expr { - hir_id: self.next_id(), - kind: hir::ExprKind::Block(block, None), - span: path.span(), - } + self.mk_expr(hir::ExprKind::Block(block, None), span) } fn generate_delegation_error( @@ -333,11 +323,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let header = self.generate_header_error(); let sig = hir::FnSig { decl, header, span }; - let body_id = self.lower_body(|this| { - let expr = - hir::Expr { hir_id: this.next_id(), kind: hir::ExprKind::Err(err), span: span }; - (&[], expr) - }); + let body_id = self.lower_body(|this| (&[], this.mk_expr(hir::ExprKind::Err(err), span))); DelegationResults { generics, body_id, sig } } @@ -349,6 +335,11 @@ impl<'hir> LoweringContext<'_, 'hir> { abi: abi::Abi::Rust, } } + + #[inline] + fn mk_expr(&mut self, kind: hir::ExprKind<'hir>, span: Span) -> hir::Expr<'hir> { + hir::Expr { hir_id: self.next_id(), kind, span } + } } struct SelfResolver<'a> { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 1e117c46b6e29..f2f6594e6869d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -217,7 +217,7 @@ impl<'a> State<'a> { fn print_expr_call(&mut self, func: &ast::Expr, args: &[P], fixup: FixupContext) { let prec = match func.kind { ast::ExprKind::Field(..) => parser::PREC_FORCE_PAREN, - _ => parser::PREC_POSTFIX, + _ => parser::PREC_UNAMBIGUOUS, }; // Independent of parenthesization related to precedence, we must @@ -257,7 +257,7 @@ impl<'a> State<'a> { // boundaries, `$receiver.method()` can be parsed back as a statement // containing an expression if and only if `$receiver` can be parsed as // a statement containing an expression. - self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX, fixup); + self.print_expr_maybe_paren(receiver, parser::PREC_UNAMBIGUOUS, fixup); self.word("."); self.print_ident(segment.ident); @@ -489,7 +489,7 @@ impl<'a> State<'a> { self.space(); } MatchKind::Postfix => { - self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup); + self.print_expr_maybe_paren(expr, parser::PREC_UNAMBIGUOUS, fixup); self.word_nbsp(".match"); } } @@ -549,7 +549,7 @@ impl<'a> State<'a> { self.print_block_with_attrs(blk, attrs); } ast::ExprKind::Await(expr, _) => { - self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup); + self.print_expr_maybe_paren(expr, parser::PREC_UNAMBIGUOUS, fixup); self.word(".await"); } ast::ExprKind::Assign(lhs, rhs, _) => { @@ -568,14 +568,14 @@ impl<'a> State<'a> { self.print_expr_maybe_paren(rhs, prec, fixup.subsequent_subexpression()); } ast::ExprKind::Field(expr, ident) => { - self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup); + self.print_expr_maybe_paren(expr, parser::PREC_UNAMBIGUOUS, fixup); self.word("."); self.print_ident(*ident); } ast::ExprKind::Index(expr, index, _) => { self.print_expr_maybe_paren( expr, - parser::PREC_POSTFIX, + parser::PREC_UNAMBIGUOUS, fixup.leftmost_subexpression(), ); self.word("["); @@ -713,7 +713,7 @@ impl<'a> State<'a> { } } ast::ExprKind::Try(e) => { - self.print_expr_maybe_paren(e, parser::PREC_POSTFIX, fixup); + self.print_expr_maybe_paren(e, parser::PREC_UNAMBIGUOUS, fixup); self.word("?") } ast::ExprKind::TryBlock(blk) => { diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c352100b01b1c..d509e4ce56d5b 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1490,11 +1490,6 @@ fn print_native_static_libs( let mut lib_args: Vec<_> = all_native_libs .iter() .filter(|l| relevant_lib(sess, l)) - // Deduplication of successive repeated libraries, see rust-lang/rust#113209 - // - // note: we don't use PartialEq/Eq because NativeLib transitively depends on local - // elements like spans, which we don't care about and would make the deduplication impossible - .dedup_by(|l1, l2| l1.name == l2.name && l1.kind == l2.kind && l1.verbatim == l2.verbatim) .filter_map(|lib| { let name = lib.name; match lib.kind { @@ -1521,6 +1516,8 @@ fn print_native_static_libs( | NativeLibKind::RawDylib => None, } }) + // deduplication of consecutive repeated libraries, see rust-lang/rust#113209 + .dedup() .collect(); for path in all_rust_dylibs { // FIXME deduplicate with add_dynamic_crate diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index ff0a94f8e9b27..f525510030b4a 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -50,7 +50,7 @@ libc = "0.2" memmap2 = "0.2.1" # tidy-alphabetical-end -[target.'cfg(any(target_arch = "powerpc", target_arch = "mips"))'.dependencies] +[target.'cfg(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc"))'.dependencies] portable-atomic = "1.5.1" [features] diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index a9ccfbed41165..32fad0de1aa3e 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -147,14 +147,14 @@ cfg_match! { [crate::owned_slice::OwnedSlice] ); - // PowerPC and MIPS platforms with 32-bit pointers do not + // MIPS, PowerPC and SPARC platforms with 32-bit pointers do not // have AtomicU64 type. - #[cfg(not(any(target_arch = "powerpc", target_arch = "mips")))] + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc", target_arch = "sparc")))] already_sync!( [std::sync::atomic::AtomicU64] ); - #[cfg(any(target_arch = "powerpc", target_arch = "mips"))] + #[cfg(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc"))] already_sync!( [portable_atomic::AtomicU64] ); diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index ecb85db33f70d..5ae79ca988f14 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -270,12 +270,12 @@ cfg_match! { pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32}; - // PowerPC and MIPS platforms with 32-bit pointers do not + // MIPS, PowerPC and SPARC platforms with 32-bit pointers do not // have AtomicU64 type. - #[cfg(not(any(target_arch = "powerpc", target_arch = "mips")))] + #[cfg(not(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc")))] pub use std::sync::atomic::AtomicU64; - #[cfg(any(target_arch = "powerpc", target_arch = "mips"))] + #[cfg(any(target_arch = "mips", target_arch = "powerpc", target_arch = "sparc"))] pub use portable_atomic::AtomicU64; pub use std::sync::Arc as Lrc; diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index b21f1eadfb7a3..25b0cbdc026af 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1120,7 +1120,7 @@ impl<'a> State<'a> { fn print_expr_call(&mut self, func: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { let prec = match func.kind { hir::ExprKind::Field(..) => parser::PREC_FORCE_PAREN, - _ => parser::PREC_POSTFIX, + _ => parser::PREC_UNAMBIGUOUS, }; self.print_expr_maybe_paren(func, prec); @@ -1134,7 +1134,7 @@ impl<'a> State<'a> { args: &[hir::Expr<'_>], ) { let base_args = args; - self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX); + self.print_expr_maybe_paren(receiver, parser::PREC_UNAMBIGUOUS); self.word("."); self.print_ident(segment.ident); @@ -1478,12 +1478,12 @@ impl<'a> State<'a> { self.print_expr_maybe_paren(rhs, prec); } hir::ExprKind::Field(expr, ident) => { - self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); + self.print_expr_maybe_paren(expr, parser::PREC_UNAMBIGUOUS); self.word("."); self.print_ident(ident); } hir::ExprKind::Index(expr, index, _) => { - self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); + self.print_expr_maybe_paren(expr, parser::PREC_UNAMBIGUOUS); self.word("["); self.print_expr(index); self.word("]"); diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 46c855155753d..3b199b7e3c26d 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -3,7 +3,7 @@ use super::method::MethodCallee; use super::{Expectation, FnCtxt, TupleArgumentsFlag}; use crate::errors; -use rustc_ast::util::parser::PREC_POSTFIX; +use rustc_ast::util::parser::PREC_UNAMBIGUOUS; use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey}; use rustc_hir::def::{self, CtorKind, Namespace, Res}; use rustc_hir::def_id::DefId; @@ -656,7 +656,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if let Ok(rest_snippet) = rest_snippet { - let sugg = if callee_expr.precedence().order() >= PREC_POSTFIX { + let sugg = if callee_expr.precedence().order() >= PREC_UNAMBIGUOUS { vec![ (up_to_rcvr_span, "".to_string()), (rest_span, format!(".{}({rest_snippet}", segment.ident)), diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 5870851028215..92f2d3254bb22 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -946,7 +946,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) { let expr_prec = self.expr.precedence().order(); - let needs_parens = expr_prec < rustc_ast::util::parser::PREC_POSTFIX; + let needs_parens = expr_prec < rustc_ast::util::parser::PREC_UNAMBIGUOUS; let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize)); let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index b3ebc0621cbd6..8d380caf91628 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -9,7 +9,7 @@ use crate::method::probe::{IsSuggestion, Mode, ProbeScope}; use core::cmp::min; use core::iter; use hir::def_id::LocalDefId; -use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX}; +use rustc_ast::util::parser::{ExprPrecedence, PREC_UNAMBIGUOUS}; use rustc_data_structures::packed::Pu128; use rustc_errors::{Applicability, Diag, MultiSpan}; use rustc_hir as hir; @@ -1329,7 +1329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let span = expr.span.find_oldest_ancestor_in_same_ctxt(); - let mut sugg = if expr.precedence().order() >= PREC_POSTFIX { + let mut sugg = if expr.precedence().order() >= PREC_UNAMBIGUOUS { vec![(span.shrink_to_hi(), ".into()".to_owned())] } else { vec![ @@ -2868,7 +2868,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`", ); - let close_paren = if expr.precedence().order() < PREC_POSTFIX { + let close_paren = if expr.precedence().order() < PREC_UNAMBIGUOUS { sugg.push((expr.span.shrink_to_lo(), "(".to_string())); ")" } else { @@ -2893,7 +2893,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let len = src.trim_end_matches(&checked_ty.to_string()).len(); expr.span.with_lo(expr.span.lo() + BytePos(len as u32)) }, - if expr.precedence().order() < PREC_POSTFIX { + if expr.precedence().order() < PREC_UNAMBIGUOUS { // Readd `)` format!("{expected_ty})") } else { diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index cdaabb036c2ae..3aa852c83045d 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -235,6 +235,7 @@ fn main() { || target.starts_with("mips-") || target.starts_with("mipsel-") || target.starts_with("powerpc-") + || target.starts_with("sparc-") { // 32-bit targets need to link libatomic. println!("cargo:rustc-link-lib=atomic"); diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 68244136d1adf..5ede0dc3ed0e4 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1031,6 +1031,12 @@ impl<'tcx> PatternExtraData<'tcx> { } /// A pattern in a form suitable for generating code. +/// +/// Here, "flat" indicates that the pattern's match pairs have been recursively +/// simplified by [`Builder::simplify_match_pairs`]. They are not necessarily +/// flat in an absolute sense. +/// +/// Will typically be incorporated into a [`Candidate`]. #[derive(Debug, Clone)] struct FlatPat<'pat, 'tcx> { /// To match the pattern, all of these must be satisfied... @@ -1042,23 +1048,25 @@ struct FlatPat<'pat, 'tcx> { } impl<'tcx, 'pat> FlatPat<'pat, 'tcx> { + /// Creates a `FlatPat` containing a simplified [`MatchPair`] list/forest + /// for the given pattern. fn new( place: PlaceBuilder<'tcx>, pattern: &'pat Pat<'tcx>, cx: &mut Builder<'_, 'tcx>, ) -> Self { - let is_never = pattern.is_never_pattern(); - let mut flat_pat = FlatPat { - match_pairs: vec![MatchPair::new(place, pattern, cx)], - extra_data: PatternExtraData { - span: pattern.span, - bindings: Vec::new(), - ascriptions: Vec::new(), - is_never, - }, + // First, recursively build a tree of match pairs for the given pattern. + let mut match_pairs = vec![MatchPair::new(place, pattern, cx)]; + let mut extra_data = PatternExtraData { + span: pattern.span, + bindings: Vec::new(), + ascriptions: Vec::new(), + is_never: pattern.is_never_pattern(), }; - cx.simplify_match_pairs(&mut flat_pat.match_pairs, &mut flat_pat.extra_data); - flat_pat + // Partly-flatten and sort the match pairs, while recording extra data. + cx.simplify_match_pairs(&mut match_pairs, &mut extra_data); + + Self { match_pairs, extra_data } } } @@ -1104,9 +1112,12 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> { has_guard: bool, cx: &mut Builder<'_, 'tcx>, ) -> Self { + // Use `FlatPat` to build simplified match pairs, then immediately + // incorporate them into a new candidate. Self::from_flat_pat(FlatPat::new(place, pattern, cx), has_guard) } + /// Incorporates an already-simplified [`FlatPat`] into a new candidate. fn from_flat_pat(flat_pat: FlatPat<'pat, 'tcx>, has_guard: bool) -> Self { Candidate { match_pairs: flat_pat.match_pairs, diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 50f4ca2d819d3..630d0b9438dca 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -95,6 +95,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { + /// Recursively builds a `MatchPair` tree for the given pattern and its + /// subpatterns. pub(in crate::build) fn new( mut place_builder: PlaceBuilder<'tcx>, pattern: &'pat Pat<'tcx>, diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs index c10f9d82d4636..5cee06e4936c9 100644 --- a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs @@ -1,13 +1,7 @@ use crate::abi::Endian; -use crate::spec::{base, Cc, LinkerFlavor, Lld, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { - let mut base = base::linux_gnu::opts(); - base.endian = Endian::Big; - base.cpu = "v9".into(); - base.max_atomic_width = Some(32); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mv8plus"]); - Target { llvm_target: "sparc-unknown-linux-gnu".into(), metadata: crate::spec::TargetMetadata { @@ -19,6 +13,15 @@ pub fn target() -> Target { pointer_width: 32, data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(), arch: "sparc".into(), - options: base, + options: TargetOptions { + cpu: "v9".into(), + endian: Endian::Big, + late_link_args: TargetOptions::link_args( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &["-mcpu=v9", "-m32"], + ), + max_atomic_width: Some(32), + ..base::linux_gnu::opts() + }, } } diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 6b5054a9f0612..9ba1c6a415470 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2579,7 +2579,7 @@ extern "rust-intrinsic" { /// fn runtime() -> i32 { 1 } /// const fn compiletime() -> i32 { 2 } /// -// // ⚠ This code violates the required equivalence of `compiletime` +/// // ⚠ This code violates the required equivalence of `compiletime` /// // and `runtime`. /// const_eval_select((), compiletime, runtime) /// } diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 8b379d3be5c0b..8e6795b11bd21 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -407,18 +407,21 @@ impl Step for Llvm { cfg.define("LLVM_LINK_LLVM_DYLIB", "ON"); } - if (target.starts_with("riscv") || target.starts_with("csky")) + if (target.starts_with("csky") + || target.starts_with("riscv") + || target.starts_with("sparc-")) && !target.contains("freebsd") && !target.contains("openbsd") && !target.contains("netbsd") { - // RISC-V and CSKY GCC erroneously requires linking against + // CSKY and RISC-V GCC erroneously requires linking against // `libatomic` when using 1-byte and 2-byte C++ // atomics but the LLVM build system check cannot // detect this. Therefore it is set manually here. // Some BSD uses Clang as its system compiler and // provides no libatomic in its base system so does - // not want this. + // not want this. 32-bit SPARC requires linking against + // libatomic as well. ldflags.exe.push(" -latomic"); ldflags.shared.push(" -latomic"); } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 850c8bfe2f8b9..03dfc86ba3066 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -211,6 +211,10 @@ pub fn prepare_tool_cargo( // See https://github.com/rust-lang/rust/issues/116538 cargo.rustflag("-Zunstable-options"); + // If the output is piped to e.g. `head -n1` we want the process to be killed, + // rather than having an error bubble up and cause a panic. + cargo.rustflag("-Zon-broken-pipe=kill"); + cargo } @@ -575,7 +579,8 @@ impl Step for Rustdoc { features.push("jemalloc".to_string()); } - let mut cargo = prepare_tool_cargo( + // NOTE: Never modify the rustflags here, it breaks the build cache for other tools! + let cargo = prepare_tool_cargo( builder, build_compiler, Mode::ToolRustc, @@ -586,11 +591,6 @@ impl Step for Rustdoc { features.as_slice(), ); - // If the rustdoc output is piped to e.g. `head -n1` we want the process - // to be killed, rather than having an error bubble up and cause a - // panic. - cargo.rustflag("-Zon-broken-pipe=kill"); - let _guard = builder.msg_tool( Kind::Build, Mode::ToolRustc, diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index d60320d828253..f451758c33507 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -6,7 +6,7 @@ use clippy_utils::{ expr_use_ctxt, get_parent_expr, is_block_like, is_lint_allowed, path_to_local, DefinedTy, ExprUseNode, }; use core::mem; -use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX}; +use rustc_ast::util::parser::{PREC_UNAMBIGUOUS, PREC_PREFIX}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_ty, Visitor}; @@ -1013,7 +1013,7 @@ fn report<'tcx>( let (precedence, calls_field) = match cx.tcx.parent_hir_node(data.first_expr.hir_id) { Node::Expr(e) => match e.kind { ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false), - ExprKind::Call(..) => (PREC_POSTFIX, matches!(expr.kind, ExprKind::Field(..))), + ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))), _ => (e.precedence().order(), false), }, _ => (0, false), @@ -1160,7 +1160,7 @@ impl<'tcx> Dereferencing<'tcx> { }, Some(parent) if !parent.span.from_expansion() => { // Double reference might be needed at this point. - if parent.precedence().order() == PREC_POSTFIX { + if parent.precedence().order() == PREC_UNAMBIGUOUS { // Parentheses would be needed here, don't lint. *outer_pat = None; } else { diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs index 183caab56c59a..be80aebed6dfb 100644 --- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs +++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs @@ -7,7 +7,7 @@ use clippy_utils::{ can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res, path_to_local_id, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while, CaptureKind, }; -use rustc_ast::util::parser::PREC_POSTFIX; +use rustc_ast::util::parser::PREC_UNAMBIGUOUS; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::LangItem::{OptionNone, OptionSome}; @@ -117,7 +117,7 @@ where // it's being passed by value. let scrutinee = peel_hir_expr_refs(scrutinee).0; let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app); - let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence().order() < PREC_POSTFIX { + let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence().order() < PREC_UNAMBIGUOUS { format!("({scrutinee_str})") } else { scrutinee_str.into() diff --git a/tests/run-make/print-native-static-libs/bar.rs b/tests/run-make/print-native-static-libs/bar.rs index cd9c1c453e5fa..74c76da6938f4 100644 --- a/tests/run-make/print-native-static-libs/bar.rs +++ b/tests/run-make/print-native-static-libs/bar.rs @@ -17,3 +17,9 @@ extern "C" { extern "C" { fn g_free2(p: *mut ()); } + +#[cfg(windows)] +#[link(name = "glib-2.0", kind = "raw-dylib")] +extern "C" { + fn g_free3(p: *mut ()); +} diff --git a/tests/ui/delegation/explicit-paths.stderr b/tests/ui/delegation/explicit-paths.stderr index 30891c94c0e98..d33c5da4377b1 100644 --- a/tests/ui/delegation/explicit-paths.stderr +++ b/tests/ui/delegation/explicit-paths.stderr @@ -110,10 +110,10 @@ error[E0308]: mismatched types --> $DIR/explicit-paths.rs:78:30 | LL | reuse ::foo1; - | ---------------^^^^ - | | | - | | expected `&S2`, found `&S` - | arguments to this function are incorrect + | ^^^^ + | | + | expected `&S2`, found `&S` + | arguments to this function are incorrect | = note: expected reference `&S2` found reference `&S`