diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 3f830acbf27a6..d9594b323dd0d 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -15,7 +15,7 @@ use crate::ast::*; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::Ident; use rustc_span::Span; #[derive(Copy, Clone, Debug, PartialEq)] @@ -109,12 +109,7 @@ pub enum LifetimeCtxt { /// to monitor future changes to `Visitor` in case a new method with a /// new default implementation gets introduced.) pub trait Visitor<'ast>: Sized { - fn visit_name(&mut self, _span: Span, _name: Symbol) { - // Nothing to do. - } - fn visit_ident(&mut self, ident: Ident) { - walk_ident(self, ident); - } + fn visit_ident(&mut self, _ident: Ident) {} fn visit_foreign_item(&mut self, i: &'ast ForeignItem) { walk_foreign_item(self, i) } @@ -267,10 +262,6 @@ macro_rules! walk_list { } } -pub fn walk_ident<'a, V: Visitor<'a>>(visitor: &mut V, ident: Ident) { - visitor.visit_name(ident.span, ident.name); -} - pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) { walk_list!(visitor, visit_item, &krate.items); walk_list!(visitor, visit_attribute, &krate.attrs); @@ -315,11 +306,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_vis(&item.vis); visitor.visit_ident(item.ident); match item.kind { - ItemKind::ExternCrate(orig_name) => { - if let Some(orig_name) = orig_name { - visitor.visit_name(item.span, orig_name); - } - } + ItemKind::ExternCrate(_) => {} ItemKind::Use(ref use_tree) => visitor.visit_use_tree(use_tree, item.id, false), ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(_, ref typ, ref expr) => { visitor.visit_ty(typ); diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs index ee166f7570307..9c7369c83e2da 100644 --- a/compiler/rustc_ast_passes/src/node_count.rs +++ b/compiler/rustc_ast_passes/src/node_count.rs @@ -16,9 +16,8 @@ impl NodeCounter { } impl<'ast> Visitor<'ast> for NodeCounter { - fn visit_ident(&mut self, ident: Ident) { + fn visit_ident(&mut self, _ident: Ident) { self.count += 1; - walk_ident(self, ident); } fn visit_foreign_item(&mut self, i: &ForeignItem) { self.count += 1; diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index b0a7a87fda4f7..d13711c3ab598 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -90,9 +90,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> fn visit_foreign_item(&mut self, it: &'a ast::ForeignItem) { self.with_lint_attrs(it.id, &it.attrs, |cx| { - run_early_pass!(cx, check_foreign_item, it); ast_visit::walk_foreign_item(cx, it); - run_early_pass!(cx, check_foreign_item_post, it); }) } @@ -104,7 +102,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_anon_const(&mut self, c: &'a ast::AnonConst) { - run_early_pass!(self, check_anon_const, c); self.check_id(c.id); ast_visit::walk_anon_const(self, c); } @@ -154,22 +151,17 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> self.check_id(closure_id); } } - - run_early_pass!(self, check_fn_post, fk, span, id); } fn visit_variant_data(&mut self, s: &'a ast::VariantData) { - run_early_pass!(self, check_struct_def, s); if let Some(ctor_hir_id) = s.ctor_id() { self.check_id(ctor_hir_id); } ast_visit::walk_struct_def(self, s); - run_early_pass!(self, check_struct_def_post, s); } fn visit_field_def(&mut self, s: &'a ast::FieldDef) { self.with_lint_attrs(s.id, &s.attrs, |cx| { - run_early_pass!(cx, check_field_def, s); ast_visit::walk_field_def(cx, s); }) } @@ -178,7 +170,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> self.with_lint_attrs(v.id, &v.attrs, |cx| { run_early_pass!(cx, check_variant, v); ast_visit::walk_variant(cx, v); - run_early_pass!(cx, check_variant_post, v); }) } @@ -203,7 +194,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> run_early_pass!(self, check_block, b); self.check_id(b.id); ast_visit::walk_block(self, b); - run_early_pass!(self, check_block_post, b); } fn visit_arm(&mut self, a: &'a ast::Arm) { @@ -214,8 +204,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_expr_post(&mut self, e: &'a ast::Expr) { - run_early_pass!(self, check_expr_post, e); - // Explicitly check for lints associated with 'closure_id', since // it does not have a corresponding AST node match e.kind { @@ -242,7 +230,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) { - run_early_pass!(self, check_where_predicate, p); ast_visit::walk_where_predicate(self, p); } @@ -256,23 +243,19 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> ast_visit::AssocCtxt::Trait => { run_early_pass!(cx, check_trait_item, item); ast_visit::walk_assoc_item(cx, item, ctxt); - run_early_pass!(cx, check_trait_item_post, item); } ast_visit::AssocCtxt::Impl => { run_early_pass!(cx, check_impl_item, item); ast_visit::walk_assoc_item(cx, item, ctxt); - run_early_pass!(cx, check_impl_item_post, item); } }); } fn visit_lifetime(&mut self, lt: &'a ast::Lifetime, _: ast_visit::LifetimeCtxt) { - run_early_pass!(self, check_lifetime, lt); self.check_id(lt.id); } fn visit_path(&mut self, p: &'a ast::Path, id: ast::NodeId) { - run_early_pass!(self, check_path, p, id); self.check_id(id); ast_visit::walk_path(self, p); } diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index afb18451cf398..a329b37519d98 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -81,7 +81,6 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { fn process_mod(&mut self, m: &'tcx hir::Mod<'tcx>, s: Span, n: hir::HirId) { lint_callback!(self, check_mod, m, s, n); hir_visit::walk_mod(self, m, n); - lint_callback!(self, check_mod_post, m, s, n); } } @@ -118,7 +117,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) { self.with_lint_attrs(param.hir_id, |cx| { - lint_callback!(cx, check_param, param); hir_visit::walk_param(cx, param); }); } @@ -151,7 +149,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas cx.with_param_env(it.hir_id(), |cx| { lint_callback!(cx, check_foreign_item, it); hir_visit::walk_foreign_item(cx, it); - lint_callback!(cx, check_foreign_item_post, it); }); }) } @@ -193,7 +190,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas let body = self.context.tcx.hir().body(body_id); lint_callback!(self, check_fn, fk, decl, body, span, id); hir_visit::walk_fn(self, fk, decl, body_id, span, id); - lint_callback!(self, check_fn_post, fk, decl, body, span, id); self.context.enclosing_body = old_enclosing_body; self.context.cached_typeck_results.set(old_cached_typeck_results); } @@ -208,7 +204,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas ) { lint_callback!(self, check_struct_def, s); hir_visit::walk_struct_def(self, s); - lint_callback!(self, check_struct_def_post, s); } fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) { @@ -227,7 +222,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas self.with_lint_attrs(v.id, |cx| { lint_callback!(cx, check_variant, v); hir_visit::walk_variant(cx, v, g, item_id); - lint_callback!(cx, check_variant_post, v); }) } @@ -237,14 +231,9 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas } fn visit_infer(&mut self, inf: &'tcx hir::InferArg) { - lint_callback!(self, check_infer, inf); hir_visit::walk_inf(self, inf); } - fn visit_name(&mut self, sp: Span, name: Symbol) { - lint_callback!(self, check_name, sp, name); - } - fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, s: Span, n: hir::HirId) { if !self.context.only_module { self.process_mod(m, s, n); @@ -280,7 +269,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas } fn visit_where_predicate(&mut self, p: &'tcx hir::WherePredicate<'tcx>) { - lint_callback!(self, check_where_predicate, p); hir_visit::walk_where_predicate(self, p); } @@ -300,7 +288,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas cx.with_param_env(trait_item.hir_id(), |cx| { lint_callback!(cx, check_trait_item, trait_item); hir_visit::walk_trait_item(cx, trait_item); - lint_callback!(cx, check_trait_item_post, trait_item); }); }); self.context.generics = generics; @@ -320,7 +307,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas } fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) { - lint_callback!(self, check_lifetime, lt); hir_visit::walk_lifetime(self, lt); } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 7b0702dad75de..ae2088fbeb6f6 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -75,7 +75,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, }; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::Ident; use rustc_span::Span; use array_into_iter::ArrayIntoIter; diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index b1b4229b1f738..cb7bd407ed4c8 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -5,23 +5,19 @@ use rustc_data_structures::sync; use rustc_hir as hir; use rustc_session::lint::builtin::HardwiredLints; use rustc_session::lint::LintPass; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::Ident; use rustc_span::Span; #[macro_export] macro_rules! late_lint_methods { ($macro:path, $args:tt, [$hir:tt]) => ( $macro!($args, [$hir], [ - fn check_param(a: &$hir hir::Param<$hir>); fn check_body(a: &$hir hir::Body<$hir>); fn check_body_post(a: &$hir hir::Body<$hir>); - fn check_name(a: Span, b: Symbol); fn check_crate(); fn check_crate_post(); fn check_mod(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId); - fn check_mod_post(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId); fn check_foreign_item(a: &$hir hir::ForeignItem<$hir>); - fn check_foreign_item_post(a: &$hir hir::ForeignItem<$hir>); fn check_item(a: &$hir hir::Item<$hir>); fn check_item_post(a: &$hir hir::Item<$hir>); fn check_local(a: &$hir hir::Local<$hir>); @@ -33,11 +29,8 @@ macro_rules! late_lint_methods { fn check_expr(a: &$hir hir::Expr<$hir>); fn check_expr_post(a: &$hir hir::Expr<$hir>); fn check_ty(a: &$hir hir::Ty<$hir>); - fn check_infer(a: &$hir hir::InferArg); - fn check_generic_arg(a: &$hir hir::GenericArg<$hir>); fn check_generic_param(a: &$hir hir::GenericParam<$hir>); fn check_generics(a: &$hir hir::Generics<$hir>); - fn check_where_predicate(a: &$hir hir::WherePredicate<$hir>); fn check_poly_trait_ref(a: &$hir hir::PolyTraitRef<$hir>, b: hir::TraitBoundModifier); fn check_fn( a: rustc_hir::intravisit::FnKind<$hir>, @@ -45,23 +38,12 @@ macro_rules! late_lint_methods { c: &$hir hir::Body<$hir>, d: Span, e: hir::HirId); - fn check_fn_post( - a: rustc_hir::intravisit::FnKind<$hir>, - b: &$hir hir::FnDecl<$hir>, - c: &$hir hir::Body<$hir>, - d: Span, - e: hir::HirId - ); fn check_trait_item(a: &$hir hir::TraitItem<$hir>); - fn check_trait_item_post(a: &$hir hir::TraitItem<$hir>); fn check_impl_item(a: &$hir hir::ImplItem<$hir>); fn check_impl_item_post(a: &$hir hir::ImplItem<$hir>); fn check_struct_def(a: &$hir hir::VariantData<$hir>); - fn check_struct_def_post(a: &$hir hir::VariantData<$hir>); fn check_field_def(a: &$hir hir::FieldDef<$hir>); fn check_variant(a: &$hir hir::Variant<$hir>); - fn check_variant_post(a: &$hir hir::Variant<$hir>); - fn check_lifetime(a: &$hir hir::Lifetime); fn check_path(a: &$hir hir::Path<$hir>, b: hir::HirId); fn check_attribute(a: &$hir ast::Attribute); @@ -161,44 +143,25 @@ macro_rules! early_lint_methods { fn check_ident(a: Ident); fn check_crate(a: &ast::Crate); fn check_crate_post(a: &ast::Crate); - fn check_foreign_item(a: &ast::ForeignItem); - fn check_foreign_item_post(a: &ast::ForeignItem); fn check_item(a: &ast::Item); fn check_item_post(a: &ast::Item); fn check_local(a: &ast::Local); fn check_block(a: &ast::Block); - fn check_block_post(a: &ast::Block); fn check_stmt(a: &ast::Stmt); fn check_arm(a: &ast::Arm); fn check_pat(a: &ast::Pat); - fn check_anon_const(a: &ast::AnonConst); fn check_pat_post(a: &ast::Pat); fn check_expr(a: &ast::Expr); - fn check_expr_post(a: &ast::Expr); fn check_ty(a: &ast::Ty); fn check_generic_arg(a: &ast::GenericArg); fn check_generic_param(a: &ast::GenericParam); fn check_generics(a: &ast::Generics); - fn check_where_predicate(a: &ast::WherePredicate); fn check_poly_trait_ref(a: &ast::PolyTraitRef, b: &ast::TraitBoundModifier); fn check_fn(a: rustc_ast::visit::FnKind<'_>, c: Span, d_: ast::NodeId); - fn check_fn_post( - a: rustc_ast::visit::FnKind<'_>, - c: Span, - d: ast::NodeId - ); fn check_trait_item(a: &ast::AssocItem); - fn check_trait_item_post(a: &ast::AssocItem); fn check_impl_item(a: &ast::AssocItem); - fn check_impl_item_post(a: &ast::AssocItem); - fn check_struct_def(a: &ast::VariantData); - fn check_struct_def_post(a: &ast::VariantData); - fn check_field_def(a: &ast::FieldDef); fn check_variant(a: &ast::Variant); - fn check_variant_post(a: &ast::Variant); - fn check_lifetime(a: &ast::Lifetime); - fn check_path(a: &ast::Path, b: ast::NodeId); fn check_attribute(a: &ast::Attribute); fn check_mac_def(a: &ast::MacroDef, b: ast::NodeId); fn check_mac(a: &ast::MacCall); diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index cb8be51a08562..6875600129a8f 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -132,6 +132,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { initializer_span, else_block, visibility_scope, + *remainder_scope, remainder_span, pattern, ) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 7067a48b783ec..58b1564cc5d8c 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2282,49 +2282,55 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { initializer_span: Span, else_block: &Block, visibility_scope: Option, + remainder_scope: region::Scope, remainder_span: Span, pattern: &Pat<'tcx>, ) -> BlockAnd<()> { - let scrutinee = unpack!(block = self.lower_scrutinee(block, init, initializer_span)); - let pat = Pat { ty: init.ty, span: else_block.span, kind: Box::new(PatKind::Wild) }; - let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false); - self.declare_bindings( - visibility_scope, - remainder_span, - pattern, - ArmHasGuard(false), - Some((None, initializer_span)), - ); - let mut candidate = Candidate::new(scrutinee.clone(), pattern, false); - let fake_borrow_temps = self.lower_match_tree( - block, - initializer_span, - pattern.span, - false, - &mut [&mut candidate, &mut wildcard], - ); - // This block is for the matching case - let matching = self.bind_pattern( - self.source_info(pattern.span), - candidate, - None, - &fake_borrow_temps, - initializer_span, - None, - None, - None, - ); - // This block is for the failure case - let failure = self.bind_pattern( - self.source_info(else_block.span), - wildcard, - None, - &fake_borrow_temps, - initializer_span, - None, - None, - None, - ); + let (matching, failure) = self.in_if_then_scope(remainder_scope, |this| { + let scrutinee = unpack!(block = this.lower_scrutinee(block, init, initializer_span)); + let pat = Pat { ty: init.ty, span: else_block.span, kind: Box::new(PatKind::Wild) }; + let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false); + this.declare_bindings( + visibility_scope, + remainder_span, + pattern, + ArmHasGuard(false), + Some((None, initializer_span)), + ); + let mut candidate = Candidate::new(scrutinee.clone(), pattern, false); + let fake_borrow_temps = this.lower_match_tree( + block, + initializer_span, + pattern.span, + false, + &mut [&mut candidate, &mut wildcard], + ); + // This block is for the matching case + let matching = this.bind_pattern( + this.source_info(pattern.span), + candidate, + None, + &fake_borrow_temps, + initializer_span, + None, + None, + None, + ); + // This block is for the failure case + let failure = this.bind_pattern( + this.source_info(else_block.span), + wildcard, + None, + &fake_borrow_temps, + initializer_span, + None, + None, + None, + ); + this.break_for_else(failure, remainder_scope, this.source_info(initializer_span)); + matching.unit() + }); + // This place is not really used because this destination place // should never be used to take values at the end of the failure // block. diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index b9fd8c50e6a04..b2fd9f25bdde7 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -690,7 +690,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } drops.add_entry(block, drop_idx); - // `build_drop_tree` doesn't have access to our source_info, so we + // `build_drop_trees` doesn't have access to our source_info, so we // create a dummy terminator now. `TerminatorKind::Resume` is used // because MIR type checking will panic if it hasn't been overwritten. self.cfg.terminate(block, source_info, TerminatorKind::Resume); @@ -722,7 +722,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } drops.add_entry(block, drop_idx); - // `build_drop_tree` doesn't have access to our source_info, so we + // `build_drop_trees` doesn't have access to our source_info, so we // create a dummy terminator now. `TerminatorKind::Resume` is used // because MIR type checking will panic if it hasn't been overwritten. self.cfg.terminate(block, source_info, TerminatorKind::Resume); diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index 8d6130a8a7936..7125d141af7f5 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -4,11 +4,21 @@ //! //! Please ping @Lokathor if changes are needed. //! -//! This target profile assumes that you have the ARM binutils in your path (specifically the linker, `arm-none-eabi-ld`). They can be obtained for free for all major OSes from the ARM developer's website, and they may also be available in your system's package manager. Unfortunately, the standard linker that Rust uses (`lld`) only supports as far back as `ARMv5TE`, so we must use the GNU `ld` linker. +//! This target profile assumes that you have the ARM binutils in your path +//! (specifically the linker, `arm-none-eabi-ld`). They can be obtained for free +//! for all major OSes from the ARM developer's website, and they may also be +//! available in your system's package manager. Unfortunately, the standard +//! linker that Rust uses (`lld`) only supports as far back as `ARMv5TE`, so we +//! must use the GNU `ld` linker. //! -//! **Important:** This target profile **does not** specify a linker script. You just get the default link script when you build a binary for this target. The default link script is very likely wrong, so you should use `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. +//! **Important:** This target profile **does not** specify a linker script. You +//! just get the default link script when you build a binary for this target. +//! The default link script is very likely wrong, so you should use +//! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. -use crate::spec::{cvs, LinkerFlavor, Target, TargetOptions}; +use crate::spec::{ + cvs, FramePointer, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions, +}; pub fn target() -> Target { Target { @@ -39,6 +49,14 @@ pub fn target() -> Target { // minimum extra features, these cannot be disabled via -C features: "+soft-float,+strict-align".into(), + panic_strategy: PanicStrategy::Abort, + relocation_model: RelocModel::Static, + // suggested from thumb_base, rust-lang/rust#44993. + emit_debug_gdb_scripts: false, + // suggested from thumb_base, with no-os gcc/clang use 8-bit enums + c_enum_min_bits: 8, + frame_pointer: FramePointer::MayOmit, + main_needs_argc_argv: false, // don't have atomic compare-and-swap diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 25ba520ace2ba..7ee3fe844b5a8 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -531,6 +531,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref); + self.suggest_dereferencing_index(&obligation, &mut err, trait_predicate); let mut suggested = self.suggest_dereferences(&obligation, &mut err, trait_predicate); suggested |= self.suggest_fn_call(&obligation, &mut err, trait_predicate); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 6c8faed0df486..1f72c96406de8 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -320,6 +320,13 @@ pub trait InferCtxtExt<'tcx> { err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ); + + fn suggest_dereferencing_index( + &self, + obligation: &PredicateObligation<'tcx>, + err: &mut Diagnostic, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ); } fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) { @@ -2895,6 +2902,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ); } } + + fn suggest_dereferencing_index( + &self, + obligation: &PredicateObligation<'tcx>, + err: &mut Diagnostic, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ) { + if let ObligationCauseCode::ImplDerivedObligation(_) = obligation.cause.code() + && self.tcx.is_diagnostic_item(sym::SliceIndex, trait_pred.skip_binder().trait_ref.def_id) + && let ty::Slice(_) = trait_pred.skip_binder().trait_ref.substs.type_at(1).kind() + && let ty::Ref(_, inner_ty, _) = trait_pred.skip_binder().self_ty().kind() + && let ty::Uint(ty::UintTy::Usize) = inner_ty.kind() + { + err.span_suggestion_verbose( + obligation.cause.span.shrink_to_lo(), + "dereference this index", + '*', + Applicability::MachineApplicable, + ); + } + } } /// Collect all the returned expressions within the input expression. diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 147d87e7594c5..df315b8a3bc3d 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -39,8 +39,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let scrut_diverges = self.diverges.replace(Diverges::Maybe); // #55810: Type check patterns first so we get types for all bindings. + let scrut_span = scrut.span.find_ancestor_inside(expr.span).unwrap_or(scrut.span); for arm in arms { - self.check_pat_top(&arm.pat, scrutinee_ty, Some(scrut.span), true); + self.check_pat_top(&arm.pat, scrutinee_ty, Some(scrut_span), true); } // Now typecheck the blocks. diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index ba5ef5edc8630..65a562060ebfe 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -2648,6 +2648,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some((index_ty, element_ty)) => { // two-phase not needed because index_ty is never mutable self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No); + self.select_obligations_where_possible(false, |errors| { + self.point_at_index_if_possible(errors, idx.span) + }); element_ty } None => { @@ -2691,6 +2694,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn point_at_index_if_possible( + &self, + errors: &mut Vec>, + span: Span, + ) { + for error in errors { + match error.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Trait(predicate) + if self.tcx.is_diagnostic_item(sym::SliceIndex, predicate.trait_ref.def_id) => { + } + _ => continue, + } + error.obligation.cause.span = span; + } + } + fn check_expr_yield( &self, value: &'tcx hir::Expr<'tcx>, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index eb22938fb61c4..abde4d9acfe1d 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1234,7 +1234,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Does the expected pattern type originate from an expression and what is the span? let (origin_expr, ty_span) = match (decl.ty, decl.init) { (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type. - (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee. + (_, Some(init)) => { + (true, Some(init.span.find_ancestor_inside(decl.span).unwrap_or(init.span))) + } // No explicit type; so use the scrutinee. _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained. }; diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 60c0694ca0e45..36111637a561c 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -3165,9 +3165,11 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { // #73631: closures inherit `#[target_feature]` annotations if tcx.features().target_feature_11 && tcx.is_closure(did.to_def_id()) { let owner_id = tcx.parent(did.to_def_id()); - codegen_fn_attrs - .target_features - .extend(tcx.codegen_fn_attrs(owner_id).target_features.iter().copied()) + if tcx.def_kind(owner_id).has_codegen_attrs() { + codegen_fn_attrs + .target_features + .extend(tcx.codegen_fn_attrs(owner_id).target_features.iter().copied()); + } } // If a function uses #[target_feature] it can't be inlined into general diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 736c30694cddb..d168af60c2df0 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -21,6 +21,7 @@ - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) + - [\*-fuchsia](platform-support/fuchsia.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) - [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md) diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md new file mode 100644 index 0000000000000..61bd1b425bc35 --- /dev/null +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -0,0 +1,295 @@ +# `aarch64-fuchsia` and `x86_64-fuchsia` + +**Tier: 2** + +[Fuchsia] is a modern open source operating system that's simple, secure, +updatable, and performant. + +[Fuchsia]: https://fuchsia.dev/ + +## Target maintainers + +The [Fuchsia team]: + +[Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json + +- Tyler Mandry ([@tmandry](https://github.com/tmandry)) +- Dan Johnson ([@computerdruid](https://github.com/computerdruid)) +- David Koloski ([@djkoloski](https://github.com/djkoloski)) +- Andrew Pollack ([@andrewpollack](https://github.com/andrewpollack)) +- Joseph Ryan ([@P1n3appl3](https://github.com/P1n3appl3)) + +As the team evolves over time, the specific members listed here may differ from +the members reported by the API. The API should be considered to be +authoritative if this occurs. Instead of pinging individual members, use +`@rustbot ping fuchsia` to contact the team on GitHub. + +## Requirements + +This target is cross-compiled from a host environment. Development may be done +from the [source tree] or using the Fuchsia SDK. + +[source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build + +Fuchsia targets support std and follow the `sysv64` calling convention on +x86_64. Fuchsia binaries use the ELF file format. + +## Building the target + +Before building Rust for Fuchsia, you'll need a clang toolchain that supports +Fuchsia as well. A recent version (14+) of clang should be sufficient to compile +Rust for Fuchsia. + +You'll also need a recent copy of the [Fuchsia SDK], which provides the tools +and binaries required to build and link programs for Fuchsia. + +[Fuchsia SDK]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core + +x86-64 and AArch64 Fuchsia targets can be enabled using the following +configuration. + +In `config.toml`, add: + +```toml +[build] +target = ["", "aarch64-fuchsia", "x86_64-fuchsia"] + +[target.x86_64-fuchsia] +llvm-libunwind = "in-tree" + +[target.aarch64-fuchsia] +llvm-libunwind = "in-tree" +``` + +Additionally, the following environment variables must be configured (for +example, using a script like `config-env.sh`): + +```sh +# Configure this environment variable to be the path to the downloaded SDK +export SDK_PATH="" + +export CFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export CXXFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export LDFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -L${SDK_PATH}/arch/arm64/lib" +export CARGO_TARGET_AARCH64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/arm64/sysroot -Lnative=${SDK_PATH}/arch/arm64/sysroot/lib -Lnative=${SDK_PATH}/arch/arm64/lib" +export CFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export CXXFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export LDFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -L${SDK_PATH}/arch/x64/lib" +export CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/x64/sysroot -Lnative=${SDK_PATH}/arch/x64/sysroot/lib -Lnative=${SDK_PATH}/arch/x64/lib" +``` + +These can be run together in a shell environment by executing +`(source config-env.sh && ./x.py install)`. + +## Building Rust programs + +After compiling Rust binaries, you'll need to build a component, package it, and +serve it to a Fuchsia device or emulator. All of this can be done using the +Fuchsia SDK. + +As an example, we'll compile and run this simple program on a Fuchsia emulator: + +**`hello_fuchsia.rs`** +```rust +fn main() { + println!("Hello Fuchsia!"); +} + +#[test] +fn it_works() { + assert_eq!(2 + 2, 4); +} +``` + +Create a new file named `hello_fuchsia.rs` and fill out its contents with that +code. + +### Create a package + +On Fuchsia, a package is the unit of distribution for software. We'll need to +create a new package directory where we will place files like our finished +binary and any data it may need. The working directory will have this layout: + +```txt +hello_fuchsia.rs +hello_fuchsia.cml +package +┣━ bin +┃ ┗━ hello_fuchsia +┣━ meta +┃ ┣━ package +┃ ┗━ hello_fuchsia.cm +┗━ hello_fuchsia.manifest +``` + +Make the `package`, `package/bin`, and `package/meta` directories and create the +following files inside: + +**`package/meta/package`** +```json +{"name":"hello_fuchsia","version":0} +``` + +The `package` file describes our package's name and version number. Every +package must contain one. + +**`package/hello_fuchsia.manifest`** +```txt +bin/hello_fuchsia=package/bin/hello_fuchsia +lib/ld.so.1=/arch/x64/sysroot/dist/lib/ld.so.1 +lib/libfdio.so=/arch/x64/dist/libfdio.so +meta/package=package/meta/package +meta/hello_fuchsia.cm=package/meta/hello_fuchsia.cm +``` + +*Note: Relative manifest paths are resolved starting from the working directory +of `pm`. Make sure to fill out `` with the path to the downloaded +SDK.* + +The `.manifest` file will be used to describe the contents of the package by +relating their location when installed to their location on the file system. You +can use this to make a package pull files from other places, but for this +example we'll just be placing everything in the `package` directory. + +### Compiling a binary + +Using your freshly compiled `rustc`, you can compile a binary for Fuchsia using +the following options: + +* `--target x86_64-fuchsia`/`--target aarch64-fuchsia`: Targets the Fuchsia + platform of your choice +* `-Lnative ${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from + the SDK +* `-Lnative ${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia kernel + libraries from the SDK + +Putting it all together: + +```sh +# Configure these for the Fuchsia target of your choice +TARGET_ARCH="" +ARCH="" + +rustc --target ${TARGET_ARCH} -Lnative=${SDK_PATH}/arch/${ARCH}/lib -Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib -o package/bin/hello_fuchsia hello_fuchsia.rs +``` + +### Bulding a component + +On Fuchsia, components require a component manifest written in Fuchia's markup +language called CML. The Fuchsia devsite contains an [overview of CML] and a +[reference for the file format]. Here's a basic one that can run our single binary: + +[overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests +[reference for the file format]: https://fuchsia.dev/reference/cml + +**`hello_fuchsia.cml`** +```txt +{ + include: [ "syslog/client.shard.cml" ], + program: { + runner: "elf", + binary: "bin/hello_fuchsia", + }, +} +``` + +Now we can compile that CML into a component manifest: + +```sh +${SDK_PATH}/tools/${ARCH}/cmc compile hello_fuchsia.cml --includepath ${SDK_PATH}/pkg -o package/meta/hello_fuchsia.cm +``` + +`--includepath` tells the compiler where to look for `include`s from our CML. +In our case, we're only using `syslog/client.shard.cml`. + +### Building and publishing a package + +Next, we'll build our package as defined by our manifest: + +```sh +${SDK_PATH}/tools/${ARCH}/pm -o hello_fuchsia -m package/hello_fuchsia.manifest build -output-package-manifest hello_fuchsia_manifest +``` + +This will produce `hello_fuchsia_manifest` which is a package manifest we can +publish directly to a repository. We can set up that repository with: + +```sh +${SDK_PATH}/tools/${ARCH}/pm newrepo -repo repo +``` + +And then publish our new package to that repository with: + +```sh +${SDK_PATH}/tools/${ARCH}/pm publish -repo repo -lp -f <(echo "hello_fuchsia_manifest") +``` + +Then we can add it to `ffx`'s package server as `hello-fuchsia` using: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm repo -r hello-fuchsia +``` + +### Starting the emulator + +Start a Fuchsia emulator in a new terminal using: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx product-bundle get workstation_eng.qemu-${ARCH} +${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless +``` + +Then, once the emulator has been started: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx target repository register +``` + +And watch the logs from the emulator in a separate terminal: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx log --since now +``` + +Finally, run the component: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx component run fuchsia-pkg://hello-fuchsia/hello_fuchsia#meta/hello_fuchsia.cm +``` + +On reruns of the component, the `--recreate` argument may also need to be +passed. + +## Testing + +### Running unit tests + +Tests can be run in the same way as a regular binary, simply by passing `--test` +to the `rustc` invocation and then repackaging and rerunning. The test harness +will run the applicable unit tests. + +Often when testing, you may want to pass additional command line arguments to +your binary. Additional arguments can be set in the component manifest: + +**`hello_fuchsia.cml`** +```txt +{ + include: [ "syslog/client.shard.cml" ], + program: { + runner: "elf", + binary: "bin/hello_fuchsia", + args: ["it_works"], + }, +} +``` + +This will pass the argument `it_works` to the binary, filtering the tests to +only those tests that match the pattern. There are many more configuration +options available in CML including environment variables. More documentation is +available on the [Fuchsia devsite](https://fuchsia.dev/reference/cml). + +### Running the compiler test suite + +Running the Rust test suite on Fuchsia is [not currently supported], but work is +underway to enable it. + +[not currently supported]: https://fxbug.dev/105393 diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 69d66693f752e..547d6696a431d 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -311,7 +311,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: w, "

\ {name}\ -

\n{}", + {}", ITEM_TABLE_OPEN, id = cx.derive_id(my_section.id().to_owned()), name = my_section.name(), @@ -415,10 +415,10 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: write!( w, "
\ - {name}\ - {visibility_emoji}\ - {unsafety_flag}\ - {stab_tags}\ + {name}\ + {visibility_emoji}\ + {unsafety_flag}\ + {stab_tags}\
\
{docs}
", name = myitem.name.unwrap(), @@ -1126,7 +1126,8 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean: write!( w, "

\ - Fields

" + Fields\ + " ); for (field, ty) in fields { let name = field.name.expect("union field name"); @@ -1238,7 +1239,8 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: write!( w, "

\ - Variants{}

", + Variants{}\ + ", document_non_exhaustive_header(it) ); document_non_exhaustive(w, it); @@ -1294,9 +1296,9 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: w, "
\ \ - \ - {f}: {t}\ - ", + \ + {f}: {t}\ + ", id = id, f = field.name.unwrap(), t = ty.print(cx) diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 9a551b68279d6..8e25f6764a9c5 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -82,10 +82,10 @@ {%- else -%} {#- -#} {%- endif -%} -
+ {#- -#} {#- -#} -

- +

{#- -#} + {#- -#} {#- -#} @@ -122,12 +122,12 @@

{#- -#} {#- -#}
{#- -#} -
+
{#- -#} {#- -#} Change settings {#- -#} {#- -#} -
+
{#- -#} {#- -#} {#- -#} {#- -#} @@ -143,6 +143,6 @@

data-resource-suffix="{{page.resource_suffix}}" {# -#} data-rustdoc-version="{{rustdoc_version}}" {# -#} > {#- -#} - + {#- -#} {#- -#} {#- -#} diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html index 62b1b7ca7292a..c755157d27687 100644 --- a/src/librustdoc/html/templates/print_item.html +++ b/src/librustdoc/html/templates/print_item.html @@ -1,4 +1,4 @@ -
+
{#- -#}

{#- -#} {#- -#} {{-typ-}} @@ -27,4 +27,4 @@

{#- -#} [] {#- -#} {#- -#} {#- -#} -

+
{#- -#} diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr index 7f51a48111b78..b36f4dab8291d 100644 --- a/src/test/ui/index-help.stderr +++ b/src/test/ui/index-help.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `[{integer}]` cannot be indexed by `i32` - --> $DIR/index-help.rs:3:5 + --> $DIR/index-help.rs:3:7 | LL | x[0i32]; - | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr index 0a24855a6a79c..fbff20f8deeab 100644 --- a/src/test/ui/indexing-requires-a-uint.stderr +++ b/src/test/ui/indexing-requires-a-uint.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `[{integer}]` cannot be indexed by `u8` - --> $DIR/indexing-requires-a-uint.rs:6:5 + --> $DIR/indexing-requires-a-uint.rs:6:9 | LL | [0][0u8]; - | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8` = help: the trait `SliceIndex<[T]>` is implemented for `usize` diff --git a/src/test/ui/integral-indexing.stderr b/src/test/ui/integral-indexing.stderr index be3398552dc0a..3f9094d124eea 100644 --- a/src/test/ui/integral-indexing.stderr +++ b/src/test/ui/integral-indexing.stderr @@ -1,78 +1,78 @@ error[E0277]: the type `[isize]` cannot be indexed by `u8` - --> $DIR/integral-indexing.rs:6:5 + --> $DIR/integral-indexing.rs:6:7 | LL | v[3u8]; - | ^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `u8` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `Vec` error[E0277]: the type `[isize]` cannot be indexed by `i8` - --> $DIR/integral-indexing.rs:7:5 + --> $DIR/integral-indexing.rs:7:7 | LL | v[3i8]; - | ^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `i8` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `Vec` error[E0277]: the type `[isize]` cannot be indexed by `u32` - --> $DIR/integral-indexing.rs:8:5 + --> $DIR/integral-indexing.rs:8:7 | LL | v[3u32]; - | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `u32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `Vec` error[E0277]: the type `[isize]` cannot be indexed by `i32` - --> $DIR/integral-indexing.rs:9:5 + --> $DIR/integral-indexing.rs:9:7 | LL | v[3i32]; - | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `i32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `Vec` error[E0277]: the type `[u8]` cannot be indexed by `u8` - --> $DIR/integral-indexing.rs:12:5 + --> $DIR/integral-indexing.rs:12:18 | LL | s.as_bytes()[3u8]; - | ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `u8` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `[u8]` error[E0277]: the type `[u8]` cannot be indexed by `i8` - --> $DIR/integral-indexing.rs:13:5 + --> $DIR/integral-indexing.rs:13:18 | LL | s.as_bytes()[3i8]; - | ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `i8` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `[u8]` error[E0277]: the type `[u8]` cannot be indexed by `u32` - --> $DIR/integral-indexing.rs:14:5 + --> $DIR/integral-indexing.rs:14:18 | LL | s.as_bytes()[3u32]; - | ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `u32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `[u8]` error[E0277]: the type `[u8]` cannot be indexed by `i32` - --> $DIR/integral-indexing.rs:15:5 + --> $DIR/integral-indexing.rs:15:18 | LL | s.as_bytes()[3i32]; - | ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `i32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` diff --git a/src/test/ui/let-else/let-else-temp-borrowck.rs b/src/test/ui/let-else/let-else-temp-borrowck.rs new file mode 100644 index 0000000000000..3910d35e77676 --- /dev/null +++ b/src/test/ui/let-else/let-else-temp-borrowck.rs @@ -0,0 +1,26 @@ +// run-pass +// +// from issue #93951, where borrowck complained the temporary that `foo(&x)` was stored in was to +// be dropped sometime after `x` was. It then suggested adding a semicolon that was already there. + +#![feature(let_else)] +use std::fmt::Debug; + +fn foo<'a>(x: &'a str) -> Result { + Ok(x) +} + +fn let_else() { + let x = String::from("Hey"); + let Ok(_) = foo(&x) else { return }; +} + +fn if_let() { + let x = String::from("Hey"); + let _ = if let Ok(s) = foo(&x) { s } else { return }; +} + +fn main() { + let_else(); + if_let(); +} diff --git a/src/test/ui/let-else/let-else-temporary-lifetime.rs b/src/test/ui/let-else/let-else-temporary-lifetime.rs index 624c2ea37a70b..9c86901b97f03 100644 --- a/src/test/ui/let-else/let-else-temporary-lifetime.rs +++ b/src/test/ui/let-else/let-else-temporary-lifetime.rs @@ -1,6 +1,8 @@ // run-pass #![feature(let_else)] +use std::fmt::Display; +use std::rc::Rc; use std::sync::atomic::{AtomicU8, Ordering}; static TRACKER: AtomicU8 = AtomicU8::new(0); @@ -17,9 +19,70 @@ impl Drop for Droppy { } } +fn foo<'a>(x: &'a str) -> Result { + Ok(x) +} + fn main() { assert_eq!(TRACKER.load(Ordering::Acquire), 0); let 0 = Droppy::default().inner else { return }; assert_eq!(TRACKER.load(Ordering::Acquire), 1); println!("Should have dropped 👆"); + + { + // cf. https://github.com/rust-lang/rust/pull/99518#issuecomment-1191520030 + struct Foo<'a>(&'a mut u32); + + impl<'a> Drop for Foo<'a> { + fn drop(&mut self) { + *self.0 = 0; + } + } + let mut foo = 0; + let Foo(0) = Foo(&mut foo) else { + *&mut foo = 1; + todo!() + }; + } + { + let x = String::from("Hey"); + + let Ok(s) = foo(&x) else { panic!() }; + assert_eq!(s.to_string(), x); + } + { + // test let-else drops temps after statement + let rc = Rc::new(0); + let 0 = *rc.clone() else { unreachable!() }; + Rc::try_unwrap(rc).unwrap(); + } + { + let mut rc = Rc::new(0); + let mut i = 0; + loop { + if i > 3 { + break; + } + let 1 = *rc.clone() else { + if let Ok(v) = Rc::try_unwrap(rc) { + rc = Rc::new(v); + } else { + panic!() + } + i += 1; + continue + }; + } + } + { + // test let-else drops temps before else block + // NOTE: this test has to be the last block in the `main` + // body. + let rc = Rc::new(0); + let 1 = *rc.clone() else { + Rc::try_unwrap(rc).unwrap(); + return; + }; + unreachable!(); + } } diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr index ae7d2e1d82393..72f67a685156d 100644 --- a/src/test/ui/on-unimplemented/slice-index.stderr +++ b/src/test/ui/on-unimplemented/slice-index.stderr @@ -1,18 +1,18 @@ error[E0277]: the type `[i32]` cannot be indexed by `i32` - --> $DIR/slice-index.rs:8:5 + --> $DIR/slice-index.rs:8:7 | LL | x[1i32]; - | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[i32]>` is not implemented for `i32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `[i32]` error[E0277]: the type `[i32]` cannot be indexed by `RangeTo` - --> $DIR/slice-index.rs:9:5 + --> $DIR/slice-index.rs:9:7 | LL | x[..1i32]; - | ^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo` = help: the following other types implement trait `SliceIndex`: diff --git a/src/test/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs b/src/test/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs new file mode 100644 index 0000000000000..033dcdfc08db0 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs @@ -0,0 +1,9 @@ +// check-pass + +#![feature(target_feature_11)] + +struct S(T) +where + [T; (|| {}, 1).1]: Copy; + +fn main() {} diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr index 45450788b9cbd..9079a18d6a67b 100644 --- a/src/test/ui/str/str-idx.stderr +++ b/src/test/ui/str/str-idx.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-idx.rs:3:17 + --> $DIR/str-idx.rs:3:19 | LL | let _: u8 = s[4]; - | ^^^^ string indices are ranges of `usize` + | ^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` @@ -47,10 +47,10 @@ LL | pub const unsafe fn get_unchecked>(&self, i: | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_unchecked` error[E0277]: the type `str` cannot be indexed by `char` - --> $DIR/str-idx.rs:6:17 + --> $DIR/str-idx.rs:6:19 | LL | let _: u8 = s['c']; - | ^^^^^^ string indices are ranges of `usize` + | ^^^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `char` = note: required because of the requirements on the impl of `Index` for `str` diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index 9ae085630279e..2d062e56a9bdd 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -25,10 +25,10 @@ LL | s[1..2] = bot(); = note: the left-hand-side of an assignment must have a statically known size error[E0277]: the type `str` cannot be indexed by `usize` - --> $DIR/str-mut-idx.rs:7:5 + --> $DIR/str-mut-idx.rs:7:7 | LL | s[1usize] = bot(); - | ^^^^^^^^^ string indices are ranges of `usize` + | ^^^^^^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` @@ -71,10 +71,10 @@ LL | pub const unsafe fn get_unchecked_mut>( | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_unchecked_mut` error[E0277]: the type `str` cannot be indexed by `char` - --> $DIR/str-mut-idx.rs:13:5 + --> $DIR/str-mut-idx.rs:13:7 | LL | s['c']; - | ^^^^^^ string indices are ranges of `usize` + | ^^^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `char` = note: required because of the requirements on the impl of `Index` for `str` diff --git a/src/test/ui/suggestions/pattern-slice-vec.fixed b/src/test/ui/suggestions/pattern-slice-vec.fixed index 447337c39c4c4..f8144641f3c31 100644 --- a/src/test/ui/suggestions/pattern-slice-vec.fixed +++ b/src/test/ui/suggestions/pattern-slice-vec.fixed @@ -24,4 +24,8 @@ fn main() { //~^ ERROR: expected an array or slice _ => {} } + + let [..] = vec![1, 2, 3][..]; + //~^ ERROR: expected an array or slice + //~| HELP: consider slicing here } diff --git a/src/test/ui/suggestions/pattern-slice-vec.rs b/src/test/ui/suggestions/pattern-slice-vec.rs index 1153ca026bb2f..444687c85789e 100644 --- a/src/test/ui/suggestions/pattern-slice-vec.rs +++ b/src/test/ui/suggestions/pattern-slice-vec.rs @@ -24,4 +24,8 @@ fn main() { //~^ ERROR: expected an array or slice _ => {} } + + let [..] = vec![1, 2, 3]; + //~^ ERROR: expected an array or slice + //~| HELP: consider slicing here } diff --git a/src/test/ui/suggestions/pattern-slice-vec.stderr b/src/test/ui/suggestions/pattern-slice-vec.stderr index 403a816ba11ff..f69e7de971a96 100644 --- a/src/test/ui/suggestions/pattern-slice-vec.stderr +++ b/src/test/ui/suggestions/pattern-slice-vec.stderr @@ -31,6 +31,14 @@ LL | LL | [5] => {} | ^^^ pattern cannot match with input type `Vec<_>` -error: aborting due to 4 previous errors +error[E0529]: expected an array or slice, found `Vec<{integer}>` + --> $DIR/pattern-slice-vec.rs:28:9 + | +LL | let [..] = vec![1, 2, 3]; + | ^^^^ ------------- help: consider slicing here: `vec![1, 2, 3][..]` + | | + | pattern cannot match with input type `Vec<{integer}>` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0529`. diff --git a/src/test/ui/suggestions/suggest-dereferencing-index.fixed b/src/test/ui/suggestions/suggest-dereferencing-index.fixed new file mode 100644 index 0000000000000..dd4ae4eb14c30 --- /dev/null +++ b/src/test/ui/suggestions/suggest-dereferencing-index.fixed @@ -0,0 +1,7 @@ +// run-rustfix +#![allow(unused_variables)] + +fn main() { + let i: &usize = &1; + let one_item_please: i32 = [1, 2, 3][*i]; //~ ERROR the type `[{integer}]` cannot be indexed by `&usize` +} diff --git a/src/test/ui/suggestions/suggest-dereferencing-index.rs b/src/test/ui/suggestions/suggest-dereferencing-index.rs new file mode 100644 index 0000000000000..82ebacc49f235 --- /dev/null +++ b/src/test/ui/suggestions/suggest-dereferencing-index.rs @@ -0,0 +1,7 @@ +// run-rustfix +#![allow(unused_variables)] + +fn main() { + let i: &usize = &1; + let one_item_please: i32 = [1, 2, 3][i]; //~ ERROR the type `[{integer}]` cannot be indexed by `&usize` +} diff --git a/src/test/ui/suggestions/suggest-dereferencing-index.stderr b/src/test/ui/suggestions/suggest-dereferencing-index.stderr new file mode 100644 index 0000000000000..c8b87af7bd80c --- /dev/null +++ b/src/test/ui/suggestions/suggest-dereferencing-index.stderr @@ -0,0 +1,17 @@ +error[E0277]: the type `[{integer}]` cannot be indexed by `&usize` + --> $DIR/suggest-dereferencing-index.rs:6:42 + | +LL | let one_item_please: i32 = [1, 2, 3][i]; + | ^ slice indices are of type `usize` or ranges of `usize` + | + = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize` + = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = note: required because of the requirements on the impl of `Index<&usize>` for `[{integer}]` +help: dereference this index + | +LL | let one_item_please: i32 = [1, 2, 3][*i]; + | + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.