diff options
| author | bors <bors@rust-lang.org> | 2024-01-04 19:44:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-01-04 19:44:14 +0000 |
| commit | 4c5ce1f0d5bf8b2ee35ff6917658ba56ef57643b (patch) | |
| tree | d4ae642bdb3ae0af49c83ea1866217cc4c07581a /compiler | |
| parent | 090d5eac722000906cc00d991f2bf052b0e388c3 (diff) | |
| parent | 657937850b3fbc2668516a21c2437af45a16889d (diff) | |
| download | rust-4c5ce1f0d5bf8b2ee35ff6917658ba56ef57643b.tar.gz rust-4c5ce1f0d5bf8b2ee35ff6917658ba56ef57643b.zip | |
Auto merge of #119578 - matthiaskrgr:rollup-42yizmx, r=matthiaskrgr
Rollup of 10 pull requests
Successful merges:
- #117636 (add test for #117626)
- #118704 (Promote `riscv32{im|imafc}` targets to tier 2)
- #119184 (Switch from using `//~ERROR` annotations with `--error-format` to `error-pattern`)
- #119325 (custom mir: make it clear what the return block is)
- #119391 (Use Result::flatten in catch_with_exit_code)
- #119431 (Support reg_addr register class in s390x inline assembly)
- #119475 (Remove libtest's dylib)
- #119532 (Make offset_of field parsing use metavariable which handles any spacing)
- #119553 (stop feed vis when cant access for trait item)
- #119574 (Miri subtree update)
r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_codegen_gcc/src/asm.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/asm.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_driver_impl/src/lib.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/custom/parse/instruction.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_parse/messages.ftl | 4 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/errors.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 164 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/s390x.rs | 29 |
10 files changed, 179 insertions, 64 deletions
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index ddd67a994c9..78e8e32b972 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -634,6 +634,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { } InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", InlineAsmRegClass::Err => unreachable!(), } @@ -704,7 +705,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") }, - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::S390x( + S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr + ) => cx.type_i32(), InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), InlineAsmRegClass::Err => unreachable!(), } diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 1323261ae92..a413466093b 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -690,6 +690,7 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => "w", InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => "e", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r", InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", @@ -867,7 +868,9 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => cx.type_i16(), InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => cx.type_i16(), InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(), - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::S390x( + S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr, + ) => cx.type_i32(), InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(), InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(), diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index ca6b0afc76a..2041ffefe77 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -12,6 +12,7 @@ #![feature(lazy_cell)] #![feature(let_chains)] #![feature(panic_update_hook)] +#![feature(result_flattening)] #![recursion_limit = "256"] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] @@ -1249,8 +1250,7 @@ pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorGuarantee /// Variant of `catch_fatal_errors` for the `interface::Result` return type /// that also computes the exit code. pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 { - let result = catch_fatal_errors(f).and_then(|result| result); - match result { + match catch_fatal_errors(f).flatten() { Ok(()) => EXIT_SUCCESS, Err(_) => EXIT_FAILURE, } diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 4ce7f831c87..e3dea2212df 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -61,7 +61,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { @call(mir_drop, args) => { Ok(TerminatorKind::Drop { place: self.parse_place(args[0])?, - target: self.parse_block(args[1])?, + target: self.parse_return_to(args[1])?, unwind: self.parse_unwind_action(args[2])?, replace: false, }) @@ -104,6 +104,14 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { ) } + fn parse_return_to(&self, expr_id: ExprId) -> PResult<BasicBlock> { + parse_by_kind!(self, expr_id, _, "return block", + @call(mir_return_to, args) => { + self.parse_block(args[0]) + }, + ) + } + fn parse_match(&self, arms: &[ArmId], span: Span) -> PResult<SwitchTargets> { let Some((otherwise, rest)) = arms.split_last() else { return Err(ParseError { @@ -146,7 +154,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { ExprKind::Assign { lhs, rhs } => (*lhs, *rhs), ); let destination = self.parse_place(destination)?; - let target = self.parse_block(args[1])?; + let target = self.parse_return_to(args[1])?; let unwind = self.parse_unwind_action(args[2])?; parse_by_kind!(self, call, _, "function call", diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index c6bddbfacd6..9a76872a383 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -10,6 +10,8 @@ parse_ambiguous_range_pattern = the range pattern here has ambiguous interpretat parse_array_brackets_instead_of_braces = this is a block expression, not an array .suggestion = to make an array, use square brackets instead of curly braces +parse_array_index_offset_of = array indexing not supported in offset_of + parse_assignment_else_not_allowed = <assignment> ... else {"{"} ... {"}"} is not allowed parse_assoc_lifetime = associated lifetimes are not supported @@ -405,6 +407,8 @@ parse_invalid_logical_operator = `{$incorrect}` is not a logical operator parse_invalid_meta_item = expected unsuffixed literal or identifier, found `{$token}` +parse_invalid_offset_of = offset_of expects dot-separated field and variant names + parse_invalid_unicode_escape = invalid unicode character escape .label = invalid escape .help = unicode escape must {$surrogate -> diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index e276b34ca37..04d70872d78 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2887,3 +2887,11 @@ pub(crate) struct TransposeDynOrImplSugg<'a> { pub insertion_span: Span, pub kw: &'a str, } + +#[derive(Diagnostic)] +#[diag(parse_array_index_offset_of)] +pub(crate) struct ArrayIndexInOffsetOf(#[primary_span] pub Span); + +#[derive(Diagnostic)] +#[diag(parse_invalid_offset_of)] +pub(crate) struct InvalidOffsetOf(#[primary_span] pub Span); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index bf6151b64d3..0b24e784126 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1023,7 +1023,7 @@ impl<'a> Parser<'a> { // we should break everything including floats into more basic proc-macro style // tokens in the lexer (probably preferable). // See also `TokenKind::break_two_token_op` which does similar splitting of `>>` into `>`. - fn break_up_float(&mut self, float: Symbol) -> DestructuredFloat { + fn break_up_float(&self, float: Symbol, span: Span) -> DestructuredFloat { #[derive(Debug)] enum FloatComponent { IdentLike(String), @@ -1053,7 +1053,6 @@ impl<'a> Parser<'a> { // With proc macros the span can refer to anything, the source may be too short, // or too long, or non-ASCII. It only makes sense to break our span into components // if its underlying text is identical to our float literal. - let span = self.token.span; let can_take_span_apart = || self.span_to_snippet(span).as_deref() == Ok(float_str).as_deref(); @@ -1115,7 +1114,7 @@ impl<'a> Parser<'a> { float: Symbol, suffix: Option<Symbol>, ) -> P<Expr> { - match self.break_up_float(float) { + match self.break_up_float(float, self.token.span) { // 1e2 DestructuredFloat::Single(sym, _sp) => { self.parse_expr_tuple_field_access(lo, base, sym, suffix, None) @@ -1143,40 +1142,105 @@ impl<'a> Parser<'a> { } } - fn parse_field_name_maybe_tuple(&mut self) -> PResult<'a, ThinVec<Ident>> { - let token::Literal(token::Lit { kind: token::Float, symbol, suffix }) = self.token.kind - else { - return Ok(thin_vec![self.parse_field_name()?]); - }; - Ok(match self.break_up_float(symbol) { - // 1e2 - DestructuredFloat::Single(sym, sp) => { - self.bump(); - thin_vec![Ident::new(sym, sp)] - } - // 1. - DestructuredFloat::TrailingDot(sym, sym_span, dot_span) => { - assert!(suffix.is_none()); - // Analogous to `Self::break_and_eat` - self.break_last_token = true; - // This might work, in cases like `1. 2`, and might not, - // in cases like `offset_of!(Ty, 1.)`. It depends on what comes - // after the float-like token, and therefore we have to make - // the other parts of the parser think that there is a dot literal. - self.token = Token::new(token::Ident(sym, false), sym_span); - self.bump_with((Token::new(token::Dot, dot_span), self.token_spacing)); - thin_vec![Ident::new(sym, sym_span)] - } - // 1.2 | 1.2e3 - DestructuredFloat::MiddleDot(symbol1, ident1_span, _dot_span, symbol2, ident2_span) => { - self.bump(); - thin_vec![Ident::new(symbol1, ident1_span), Ident::new(symbol2, ident2_span)] + /// Parse the field access used in offset_of, matched by `$(e:expr)+`. + /// Currently returns a list of idents. However, it should be possible in + /// future to also do array indices, which might be arbitrary expressions. + fn parse_floating_field_access(&mut self) -> PResult<'a, P<[Ident]>> { + let mut fields = Vec::new(); + let mut trailing_dot = None; + + loop { + // This is expected to use a metavariable $(args:expr)+, but the builtin syntax + // could be called directly. Calling `parse_expr` allows this function to only + // consider `Expr`s. + let expr = self.parse_expr()?; + let mut current = &expr; + let start_idx = fields.len(); + loop { + match current.kind { + ExprKind::Field(ref left, right) => { + // Field access is read right-to-left. + fields.insert(start_idx, right); + trailing_dot = None; + current = left; + } + // Parse this both to give helpful error messages and to + // verify it can be done with this parser setup. + ExprKind::Index(ref left, ref _right, span) => { + self.dcx().emit_err(errors::ArrayIndexInOffsetOf(span)); + current = left; + } + ExprKind::Lit(token::Lit { + kind: token::Float | token::Integer, + symbol, + suffix, + }) => { + if let Some(suffix) = suffix { + self.expect_no_tuple_index_suffix(current.span, suffix); + } + match self.break_up_float(symbol, current.span) { + // 1e2 + DestructuredFloat::Single(sym, sp) => { + trailing_dot = None; + fields.insert(start_idx, Ident::new(sym, sp)); + } + // 1. + DestructuredFloat::TrailingDot(sym, sym_span, dot_span) => { + assert!(suffix.is_none()); + trailing_dot = Some(dot_span); + fields.insert(start_idx, Ident::new(sym, sym_span)); + } + // 1.2 | 1.2e3 + DestructuredFloat::MiddleDot( + symbol1, + span1, + _dot_span, + symbol2, + span2, + ) => { + trailing_dot = None; + fields.insert(start_idx, Ident::new(symbol2, span2)); + fields.insert(start_idx, Ident::new(symbol1, span1)); + } + DestructuredFloat::Error => { + trailing_dot = None; + fields.insert(start_idx, Ident::new(symbol, self.prev_token.span)); + } + } + break; + } + ExprKind::Path(None, Path { ref segments, .. }) => { + match &segments[..] { + [PathSegment { ident, args: None, .. }] => { + trailing_dot = None; + fields.insert(start_idx, *ident) + } + _ => { + self.dcx().emit_err(errors::InvalidOffsetOf(current.span)); + break; + } + } + break; + } + _ => { + self.dcx().emit_err(errors::InvalidOffsetOf(current.span)); + break; + } + } } - DestructuredFloat::Error => { - self.bump(); - thin_vec![Ident::new(symbol, self.prev_token.span)] + + if matches!(self.token.kind, token::CloseDelim(..) | token::Comma) { + break; + } else if trailing_dot.is_none() { + // This loop should only repeat if there is a trailing dot. + self.dcx().emit_err(errors::InvalidOffsetOf(self.token.span)); + break; } - }) + } + if let Some(dot) = trailing_dot { + self.dcx().emit_err(errors::InvalidOffsetOf(dot)); + } + Ok(fields.into_iter().collect()) } fn parse_expr_tuple_field_access( @@ -1907,15 +1971,29 @@ impl<'a> Parser<'a> { let container = self.parse_ty()?; self.expect(&TokenKind::Comma)?; - let seq_sep = SeqSep { sep: Some(token::Dot), trailing_sep_allowed: false }; - let (fields, _trailing, _recovered) = self.parse_seq_to_before_end( - &TokenKind::CloseDelim(Delimiter::Parenthesis), - seq_sep, - Parser::parse_field_name_maybe_tuple, - )?; - let fields = fields.into_iter().flatten().collect::<Vec<_>>(); + let fields = self.parse_floating_field_access()?; + let trailing_comma = self.eat_noexpect(&TokenKind::Comma); + + if let Err(mut e) = + self.expect_one_of(&[], &[TokenKind::CloseDelim(Delimiter::Parenthesis)]) + { + if trailing_comma { + e.note("unexpected third argument to offset_of"); + } else { + e.note("offset_of expects dot-separated field and variant names"); + } + e.emit(); + } + + // Eat tokens until the macro call ends. + if self.may_recover() { + while !matches!(self.token.kind, token::CloseDelim(..) | token::Eof) { + self.bump(); + } + } + let span = lo.to(self.token.span); - Ok(self.mk_expr(span, ExprKind::OffsetOf(container, fields.into()))) + Ok(self.mk_expr(span, ExprKind::OffsetOf(container, fields))) } /// Returns a string literal if the next token is a string literal. diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index c3026e52430..a82f7bdfbf3 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3076,7 +3076,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } let feed_visibility = |this: &mut Self, def_id| { - let vis = this.r.tcx.visibility(def_id).expect_local(); + let vis = this.r.tcx.visibility(def_id); + let vis = if vis.is_visible_locally() { + vis.expect_local() + } else { + this.r.dcx().span_delayed_bug( + span, + "error should be emitted when an unexpected trait item is used", + ); + rustc_middle::ty::Visibility::Public + }; this.r.feed_visibility(this.r.local_def_id(id), vis); }; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 0b44071496e..9af81e06303 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1041,6 +1041,7 @@ symbols! { mir_offset, mir_retag, mir_return, + mir_return_to, mir_set_discriminant, mir_static, mir_static_mut, diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index 0a50064f587..b8afeb824d8 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -6,6 +6,7 @@ use std::fmt; def_reg_class! { S390x S390xInlineAsmRegClass { reg, + reg_addr, freg, } } @@ -36,7 +37,7 @@ impl S390xInlineAsmRegClass { arch: InlineAsmArch, ) -> &'static [(InlineAsmType, Option<Symbol>)] { match (self, arch) { - (Self::reg, _) => types! { _: I8, I16, I32, I64; }, + (Self::reg | Self::reg_addr, _) => types! { _: I8, I16, I32, I64; }, (Self::freg, _) => types! { _: F32, F64; }, } } @@ -45,19 +46,19 @@ impl S390xInlineAsmRegClass { def_regs! { S390x S390xInlineAsmReg S390xInlineAsmRegClass { r0: reg = ["r0"], - r1: reg = ["r1"], - r2: reg = ["r2"], - r3: reg = ["r3"], - r4: reg = ["r4"], - r5: reg = ["r5"], - r6: reg = ["r6"], - r7: reg = ["r7"], - r8: reg = ["r8"], - r9: reg = ["r9"], - r10: reg = ["r10"], - r12: reg = ["r12"], - r13: reg = ["r13"], - r14: reg = ["r14"], + r1: reg, reg_addr = ["r1"], + r2: reg, reg_addr = ["r2"], + r3: reg, reg_addr = ["r3"], + r4: reg, reg_addr = ["r4"], + r5: reg, reg_addr = ["r5"], + r6: reg, reg_addr = ["r6"], + r7: reg, reg_addr = ["r7"], + r8: reg, reg_addr = ["r8"], + r9: reg, reg_addr = ["r9"], + r10: reg, reg_addr = ["r10"], + r12: reg, reg_addr = ["r12"], + r13: reg, reg_addr = ["r13"], + r14: reg, reg_addr = ["r14"], f0: freg = ["f0"], f1: freg = ["f1"], f2: freg = ["f2"], |
