diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/intrinsic.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/check.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/ops.rs | 45 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0439.md | 4 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/expand.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/lifetimes.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/expr.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/intrinsic.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/method/mod.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/pat.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/errors.rs | 8 |
13 files changed, 123 insertions, 34 deletions
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 1060f911a9e..b309a124e80 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -918,12 +918,29 @@ fn generic_simd_intrinsic( } if let Some(stripped) = name_str.strip_prefix("simd_shuffle") { - let n: u64 = stripped.parse().unwrap_or_else(|_| { - span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") - }); + // If this intrinsic is the older "simd_shuffleN" form, simply parse the integer. + // If there is no suffix, use the index array length. + let n: u64 = if stripped.is_empty() { + // Make sure this is actually an array, since typeck only checks the length-suffixed + // version of this intrinsic. + match args[2].layout.ty.kind() { + ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => { + len.try_eval_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(|| { + span_bug!(span, "could not evaluate shuffle index array length") + }) + } + _ => return_error!( + "simd_shuffle index must be an array of `u32`, got `{}`", + args[2].layout.ty + ), + } + } else { + stripped.parse().unwrap_or_else(|_| { + span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") + }) + }; require_simd!(ret_ty, "return"); - let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); require!( out_len == n, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index cd0e9354c24..0861aab2e31 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -665,8 +665,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") { if let mir::Operand::Constant(constant) = arg { let c = self.eval_mir_constant(constant); - let (llval, ty) = - self.simd_shuffle_indices(&bx, constant.span, constant.ty(), c); + let (llval, ty) = self.simd_shuffle_indices( + &bx, + constant.span, + self.monomorphize(constant.ty()), + c, + ); return OperandRef { val: Immediate(llval), layout: bx.layout_of(ty), diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 0e5a896a8f1..9eec930f59e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -384,11 +384,11 @@ impl Checker<'mir, 'tcx> { match pred.skip_binder() { ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => { - self.check_op(ops::ty::TraitBound(kind)) + self.check_op(ops::ty::DynTrait(kind)) } ty::ExistentialPredicate::Trait(trait_ref) => { if Some(trait_ref.def_id) != self.tcx.lang_items().sized_trait() { - self.check_op(ops::ty::TraitBound(kind)) + self.check_op(ops::ty::DynTrait(kind)) } } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 2a296750838..1d0ee949a22 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -599,7 +599,7 @@ pub mod ty { } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - let mut builder = feature_err( + let mut err = feature_err( &ccx.tcx.sess.parse_sess, sym::const_fn_trait_bound, span, @@ -608,12 +608,51 @@ pub mod ty { match ccx.fn_sig() { Some(fn_sig) if !fn_sig.span.contains(span) => { - builder.span_label(fn_sig.span, "function declared as const here"); + err.span_label(fn_sig.span, "function declared as const here"); } _ => {} } - builder + err + } + } + + #[derive(Debug)] + pub struct DynTrait(pub mir::LocalKind); + impl NonConstOp for DynTrait { + fn importance(&self) -> DiagnosticImportance { + match self.0 { + mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary, + mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => { + DiagnosticImportance::Primary + } + } + } + + fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status { + if ccx.const_kind() != hir::ConstContext::ConstFn { + Status::Allowed + } else { + Status::Unstable(sym::const_fn_trait_bound) + } + } + + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + let mut err = feature_err( + &ccx.tcx.sess.parse_sess, + sym::const_fn_trait_bound, + span, + "trait objects in const fn are unstable", + ); + + match ccx.fn_sig() { + Some(fn_sig) if !fn_sig.span.contains(span) => { + err.span_label(fn_sig.span, "function declared as const here"); + } + _ => {} + } + + err } } diff --git a/compiler/rustc_error_codes/src/error_codes/E0439.md b/compiler/rustc_error_codes/src/error_codes/E0439.md index 3e663df866c..24268aef222 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0439.md +++ b/compiler/rustc_error_codes/src/error_codes/E0439.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + The length of the platform-intrinsic function `simd_shuffle` wasn't specified. Erroneous code example: -```compile_fail,E0439 +```ignore (no longer emitted) #![feature(platform_intrinsics)] extern "platform-intrinsic" { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 62066ca9657..d32593f34ad 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1386,14 +1386,17 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { // `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` lint if needed. // See #78991 for an investigation of treating macros in this position // as statements, rather than expressions, during parsing. - if let StmtKind::Expr(expr) = &stmt.kind { - if matches!(**expr, ast::Expr { kind: ast::ExprKind::MacCall(..), .. }) { + let res = match &stmt.kind { + StmtKind::Expr(expr) + if matches!(**expr, ast::Expr { kind: ast::ExprKind::MacCall(..), .. }) => + { self.cx.current_expansion.is_trailing_mac = true; + // Don't use `assign_id` for this statement - it may get removed + // entirely due to a `#[cfg]` on the contained expression + noop_flat_map_stmt(stmt, self) } - } - - let res = assign_id!(self, &mut stmt.id, || noop_flat_map_stmt(stmt, self)); - + _ => assign_id!(self, &mut stmt.id, || noop_flat_map_stmt(stmt, self)), + }; self.cx.current_expansion.is_trailing_mac = false; res } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index a5dbbffeaa8..a158e0e48e8 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1652,7 +1652,11 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) { } fn expression_label(ex: &hir::Expr<'_>) -> Option<Ident> { - if let hir::ExprKind::Loop(_, Some(label), ..) = ex.kind { Some(label.ident) } else { None } + match ex.kind { + hir::ExprKind::Loop(_, Some(label), ..) => Some(label.ident), + hir::ExprKind::Block(_, Some(label)) => Some(label.ident), + _ => None, + } } fn check_if_label_shadows_lifetime(tcx: TyCtxt<'_>, mut scope: ScopeRef<'_>, label: Ident) { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 78846d8ffb2..322bea3806c 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1212,6 +1212,7 @@ symbols! { simd_select_bitmask, simd_shl, simd_shr, + simd_shuffle, simd_sub, simd_trunc, simd_xor, diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 53c1470c601..11b6c93a115 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1860,6 +1860,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field, expr_t, expr, + None, ); } err.emit(); @@ -1886,9 +1887,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let expr_snippet = self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap_or(String::new()); - if expr_is_call && expr_snippet.starts_with("(") && expr_snippet.ends_with(")") { - let after_open = expr.span.lo() + rustc_span::BytePos(1); - let before_close = expr.span.hi() - rustc_span::BytePos(1); + let is_wrapped = expr_snippet.starts_with("(") && expr_snippet.ends_with(")"); + let after_open = expr.span.lo() + rustc_span::BytePos(1); + let before_close = expr.span.hi() - rustc_span::BytePos(1); + + if expr_is_call && is_wrapped { err.multipart_suggestion( "remove wrapping parentheses to call the method", vec![ @@ -1898,12 +1901,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } else if !self.expr_in_place(expr.hir_id) { + // Suggest call parentheses inside the wrapping parentheses + let span = if is_wrapped { + expr.span.with_lo(after_open).with_hi(before_close) + } else { + expr.span + }; self.suggest_method_call( &mut err, "use parentheses to call the method", field, expr_t, expr, + Some(span), ); } else { err.help("methods are immutable and cannot be assigned to"); diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index 664954b0eb7..ff7a26853b1 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -2,7 +2,7 @@ //! intrinsics that the compiler exposes. use crate::errors::{ - SimdShuffleMissingLength, UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction, + UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction, WrongNumberOfGenericArgumentsToIntrinsic, }; use crate::require_same_types; @@ -468,6 +468,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) | sym::simd_reduce_max | sym::simd_reduce_min_nanless | sym::simd_reduce_max_nanless => (2, vec![param(0)], param(1)), + sym::simd_shuffle => (3, vec![param(0), param(0), param(1)], param(2)), name if name.as_str().starts_with("simd_shuffle") => { match name.as_str()["simd_shuffle".len()..].parse() { Ok(n) => { @@ -475,7 +476,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) (2, params, param(1)) } Err(_) => { - tcx.sess.emit_err(SimdShuffleMissingLength { span: it.span, name }); + let msg = + format!("unrecognized platform-specific intrinsic function: `{}`", name); + tcx.sess.struct_span_err(it.span, &msg).emit(); return; } } diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 2136d925423..8e09aa97dcf 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -141,6 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method_name: Ident, self_ty: Ty<'tcx>, call_expr: &hir::Expr<'_>, + span: Option<Span>, ) { let params = self .probe_for_name( @@ -159,7 +160,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or(0); // Account for `foo.bar<T>`; - let sugg_span = call_expr.span.shrink_to_hi(); + let sugg_span = span.unwrap_or_else(|| call_expr.span).shrink_to_hi(); let (suggestion, applicability) = ( format!("({})", (0..params).map(|_| "_").collect::<Vec<_>>().join(", ")), if params > 0 { Applicability::HasPlaceholders } else { Applicability::MaybeIncorrect }, diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index a056ab6aef2..829268e3cb5 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -1452,7 +1452,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { plural ), ); - if plural == "" { + + if unmentioned_fields.len() == 1 { let input = unmentioned_fields.iter().map(|(_, field)| field.name).collect::<Vec<_>>(); let suggested_name = find_best_match_for_name(&input, ident.name, None); @@ -1473,6 +1474,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We don't want to throw `E0027` in case we have thrown `E0026` for them. unmentioned_fields.retain(|&(_, x)| x.name != suggested_name); } + } else if inexistent_fields.len() == 1 { + let unmentioned_field = unmentioned_fields[0].1.name; + err.span_suggestion_short( + ident.span, + &format!( + "`{}` has a field named `{}`", + tcx.def_path_str(variant.def_id), + unmentioned_field + ), + unmentioned_field.to_string(), + Applicability::MaybeIncorrect, + ); } } } diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 1e6a240b2f8..47077779616 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -122,14 +122,6 @@ pub struct AssocTypeBindingNotAllowed { } #[derive(SessionDiagnostic)] -#[error = "E0439"] -pub struct SimdShuffleMissingLength { - #[message = "invalid `simd_shuffle`, needs length: `{name}`"] - pub span: Span, - pub name: Symbol, -} - -#[derive(SessionDiagnostic)] #[error = "E0436"] pub struct FunctionalRecordUpdateOnNonStruct { #[message = "functional record update syntax requires a struct"] |
