diff options
264 files changed, 2450 insertions, 1840 deletions
diff --git a/Cargo.lock b/Cargo.lock index 2d3bc59dddb..1c1607e4c1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4411,6 +4411,7 @@ dependencies = [ name = "rustc_mir_build" version = "0.0.0" dependencies = [ + "either", "itertools", "rustc_apfloat", "rustc_arena", diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 3cb56a7d312..5008069542f 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -27,7 +27,7 @@ features = ['unprefixed_malloc_on_supported_platforms'] [features] # tidy-alphabetical-start -jemalloc = ['jemalloc-sys'] +jemalloc = ['dep:jemalloc-sys'] llvm = ['rustc_driver_impl/llvm'] max_level_info = ['rustc_driver_impl/max_level_info'] rustc_use_parallel_compiler = ['rustc_driver_impl/rustc_use_parallel_compiler'] diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index 7ba58406ef1..29766fc9d87 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -34,7 +34,7 @@ fn main() { // See the comment at the top of this file for an explanation of this. - #[cfg(feature = "jemalloc-sys")] + #[cfg(feature = "jemalloc")] { use std::os::raw::{c_int, c_void}; diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml index 5031e7a6705..7448f066d0a 100644 --- a/compiler/rustc_abi/Cargo.toml +++ b/compiler/rustc_abi/Cargo.toml @@ -21,10 +21,10 @@ default = ["nightly", "randomize"] # rust-analyzer depends on this crate and we therefore require it to built on a stable toolchain # without depending on rustc_data_structures, rustc_macros and rustc_serialize nightly = [ - "rustc_data_structures", + "dep:rustc_data_structures", + "dep:rustc_macros", + "dep:rustc_serialize", "rustc_index/nightly", - "rustc_macros", - "rustc_serialize", ] -randomize = ["rand", "rand_xoshiro", "nightly"] +randomize = ["dep:rand", "dep:rand_xoshiro", "nightly"] # tidy-alphabetical-end diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index efe19566152..9478da236c3 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -699,8 +699,7 @@ impl Token { false } - /// Would `maybe_whole_expr` in `parser.rs` return `Ok(..)`? - /// That is, is this a pre-parsed expression dropped into the token stream + /// Is this a pre-parsed expression dropped into the token stream /// (which happens while parsing the result of macro expansion)? pub fn is_whole_expr(&self) -> bool { if let Interpolated(nt) = &self.kind diff --git a/compiler/rustc_ast_ir/Cargo.toml b/compiler/rustc_ast_ir/Cargo.toml index a78c91e0615..1905574073f 100644 --- a/compiler/rustc_ast_ir/Cargo.toml +++ b/compiler/rustc_ast_ir/Cargo.toml @@ -14,8 +14,8 @@ rustc_span = { path = "../rustc_span", optional = true } [features] default = ["nightly"] nightly = [ - "rustc_serialize", - "rustc_data_structures", - "rustc_macros", - "rustc_span", + "dep:rustc_serialize", + "dep:rustc_data_structures", + "dep:rustc_macros", + "dep:rustc_span", ] diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index c7f6840e401..f7e4bba3712 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -205,9 +205,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { is_loop_move = true; } + let mut has_suggest_reborrow = false; if !seen_spans.contains(&move_span) { if !closure { - self.suggest_ref_or_clone(mpi, &mut err, &mut in_pattern, move_spans); + self.suggest_ref_or_clone( + mpi, + &mut err, + &mut in_pattern, + move_spans, + moved_place.as_ref(), + &mut has_suggest_reborrow, + ); } let msg_opt = CapturedMessageOpt { @@ -215,6 +223,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { is_loop_message, is_move_msg, is_loop_move, + has_suggest_reborrow, maybe_reinitialized_locations_is_empty: maybe_reinitialized_locations .is_empty(), }; @@ -259,17 +268,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { if is_loop_move & !in_pattern && !matches!(use_spans, UseSpans::ClosureUse { .. }) { if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() { // We have a `&mut` ref, we need to reborrow on each iteration (#62112). - err.span_suggestion_verbose( - span.shrink_to_lo(), - format!( - "consider creating a fresh reborrow of {} here", - self.describe_place(moved_place) - .map(|n| format!("`{n}`")) - .unwrap_or_else(|| "the mutable reference".to_string()), - ), - "&mut *", - Applicability::MachineApplicable, - ); + self.suggest_reborrow(&mut err, span, moved_place); } } @@ -346,6 +345,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { err: &mut Diag<'infcx>, in_pattern: &mut bool, move_spans: UseSpans<'tcx>, + moved_place: PlaceRef<'tcx>, + has_suggest_reborrow: &mut bool, ) { let move_span = match move_spans { UseSpans::ClosureUse { capture_kind_span, .. } => capture_kind_span, @@ -435,20 +436,44 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { let parent = self.infcx.tcx.parent_hir_node(expr.hir_id); let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind - && let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id) { - (def_id.as_local(), args, 1) + (typeck.type_dependent_def_id(parent_expr.hir_id), args, 1) } else if let hir::Node::Expr(parent_expr) = parent && let hir::ExprKind::Call(call, args) = parent_expr.kind && let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind() { - (def_id.as_local(), args, 0) + (Some(*def_id), args, 0) } else { (None, &[][..], 0) }; + + // If the moved value is a mut reference, it is used in a + // generic function and it's type is a generic param, it can be + // reborrowed to avoid moving. + // for example: + // struct Y(u32); + // x's type is '& mut Y' and it is used in `fn generic<T>(x: T) {}`. + if let Some(def_id) = def_id + && self.infcx.tcx.def_kind(def_id).is_fn_like() + && let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id) + && let ty::Param(_) = + self.infcx.tcx.fn_sig(def_id).skip_binder().skip_binder().inputs() + [pos + offset] + .kind() + { + let place = &self.move_data.move_paths[mpi].place; + let ty = place.ty(self.body, self.infcx.tcx).ty; + if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() { + *has_suggest_reborrow = true; + self.suggest_reborrow(err, expr.span, moved_place); + return; + } + } + let mut can_suggest_clone = true; if let Some(def_id) = def_id - && let node = self.infcx.tcx.hir_node_by_def_id(def_id) + && let Some(local_def_id) = def_id.as_local() + && let node = self.infcx.tcx.hir_node_by_def_id(local_def_id) && let Some(fn_sig) = node.fn_sig() && let Some(ident) = node.ident() && let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id) @@ -622,6 +647,25 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { } } + pub fn suggest_reborrow( + &self, + err: &mut Diag<'infcx>, + span: Span, + moved_place: PlaceRef<'tcx>, + ) { + err.span_suggestion_verbose( + span.shrink_to_lo(), + format!( + "consider creating a fresh reborrow of {} here", + self.describe_place(moved_place) + .map(|n| format!("`{n}`")) + .unwrap_or_else(|| "the mutable reference".to_string()), + ), + "&mut *", + Applicability::MachineApplicable, + ); + } + fn report_use_of_uninitialized( &self, mpi: MovePathIndex, diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index b7fbb71a0cf..f97459d16ba 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -768,10 +768,11 @@ struct CapturedMessageOpt { is_loop_message: bool, is_move_msg: bool, is_loop_move: bool, + has_suggest_reborrow: bool, maybe_reinitialized_locations_is_empty: bool, } -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { /// Finds the spans associated to a move or copy of move_place at location. pub(super) fn move_spans( &self, @@ -997,7 +998,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable fn explain_captures( &mut self, - err: &mut Diag<'_>, + err: &mut Diag<'infcx>, span: Span, move_span: Span, move_spans: UseSpans<'tcx>, @@ -1009,6 +1010,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { is_loop_message, is_move_msg, is_loop_move, + has_suggest_reborrow, maybe_reinitialized_locations_is_empty, } = msg_opt; if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = move_spans { @@ -1182,18 +1184,15 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { if let ty::Ref(_, _, hir::Mutability::Mut) = moved_place.ty(self.body, self.infcx.tcx).ty.kind() { - // If we are in a loop this will be suggested later. - if !is_loop_move { - err.span_suggestion_verbose( + // Suggest `reborrow` in other place for following situations: + // 1. If we are in a loop this will be suggested later. + // 2. If the moved value is a mut reference, it is used in a + // generic function and the corresponding arg's type is generic param. + if !is_loop_move && !has_suggest_reborrow { + self.suggest_reborrow( + err, move_span.shrink_to_lo(), - format!( - "consider creating a fresh reborrow of {} here", - self.describe_place(moved_place.as_ref()) - .map(|n| format!("`{n}`")) - .unwrap_or_else(|| "the mutable reference".to_string()), - ), - "&mut *", - Applicability::MachineApplicable, + moved_place.as_ref(), ); } } diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 4b6c1b29f28..fcf23aa4785 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -554,6 +554,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { is_loop_message: false, is_move_msg: false, is_loop_move: false, + has_suggest_reborrow: false, maybe_reinitialized_locations_is_empty: true, }; if let Some(use_spans) = use_spans { diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 02b9c2d48b1..ea4a94e57b3 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -309,7 +309,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { } impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.type_checker.infcx.tcx } @@ -370,7 +370,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx // shouldn't ever fail. Instead, it unconditionally emits an // alias-relate goal. assert!(!self.type_checker.infcx.next_trait_solver()); - self.tcx().dcx().span_delayed_bug( + self.cx().dcx().span_delayed_bug( self.span(), "failure to relate an opaque to itself should result in an error later on", ); @@ -540,7 +540,7 @@ impl<'bccx, 'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for NllTypeRelating &mut self, obligations: impl IntoIterator<Item: ty::Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>, ) { - let tcx = self.tcx(); + let tcx = self.cx(); let param_env = self.param_env(); self.register_goals( obligations.into_iter().map(|to_pred| Goal::new(tcx, param_env, to_pred)), @@ -559,7 +559,7 @@ impl<'bccx, 'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for NllTypeRelating .into_iter() .map(|goal| { Obligation::new( - self.tcx(), + self.cx(), ObligationCause::dummy_with_span(self.span()), goal.param_env, goal.predicate, diff --git a/compiler/rustc_codegen_gcc/.rustfmt.toml b/compiler/rustc_codegen_gcc/.rustfmt.toml index 2a35f0230c6..725aec25a07 100644 --- a/compiler/rustc_codegen_gcc/.rustfmt.toml +++ b/compiler/rustc_codegen_gcc/.rustfmt.toml @@ -1 +1,3 @@ +version = "Two" use_small_heuristics = "Max" +merge_derives = false diff --git a/compiler/rustc_codegen_gcc/build_system/src/clone_gcc.rs b/compiler/rustc_codegen_gcc/build_system/src/clone_gcc.rs index aee46afaeb0..cbf590c0c32 100644 --- a/compiler/rustc_codegen_gcc/build_system/src/clone_gcc.rs +++ b/compiler/rustc_codegen_gcc/build_system/src/clone_gcc.rs @@ -34,7 +34,7 @@ impl Args { "--out-path" => match args.next() { Some(path) if !path.is_empty() => out_path = Some(path), _ => { - return Err("Expected an argument after `--out-path`, found nothing".into()) + return Err("Expected an argument after `--out-path`, found nothing".into()); } }, "--help" => { diff --git a/compiler/rustc_codegen_gcc/build_system/src/config.rs b/compiler/rustc_codegen_gcc/build_system/src/config.rs index 965aedd8be8..bbb711c8428 100644 --- a/compiler/rustc_codegen_gcc/build_system/src/config.rs +++ b/compiler/rustc_codegen_gcc/build_system/src/config.rs @@ -54,7 +54,7 @@ impl ConfigFile { config.gcc_path = Some(value.as_str().to_string()) } ("gcc-path", _) => { - return failed_config_parsing(config_file, "Expected a string for `gcc-path`") + return failed_config_parsing(config_file, "Expected a string for `gcc-path`"); } ("download-gccjit", TomlValue::Boolean(value)) => { config.download_gccjit = Some(*value) @@ -63,7 +63,7 @@ impl ConfigFile { return failed_config_parsing( config_file, "Expected a boolean for `download-gccjit`", - ) + ); } _ => return failed_config_parsing(config_file, &format!("Unknown key `{}`", key)), } @@ -73,7 +73,7 @@ impl ConfigFile { return failed_config_parsing( config_file, "At least one of `gcc-path` or `download-gccjit` value must be set", - ) + ); } (Some(_), Some(true)) => { println!( @@ -144,7 +144,7 @@ impl ConfigInfo { _ => { return Err( "Expected a value after `--target-triple`, found nothing".to_string() - ) + ); } }, "--out-dir" => match args.next() { @@ -158,7 +158,7 @@ impl ConfigInfo { self.config_file = Some(arg.to_string()); } _ => { - return Err("Expected a value after `--config-file`, found nothing".to_string()) + return Err("Expected a value after `--config-file`, found nothing".to_string()); } }, "--release-sysroot" => self.sysroot_release_channel = true, @@ -169,7 +169,7 @@ impl ConfigInfo { self.cg_gcc_path = Some(arg.into()); } _ => { - return Err("Expected a value after `--cg_gcc-path`, found nothing".to_string()) + return Err("Expected a value after `--cg_gcc-path`, found nothing".to_string()); } }, "--use-backend" => match args.next() { @@ -277,7 +277,7 @@ impl ConfigInfo { self.gcc_path = match gcc_path { Some(path) => path, None => { - return Err(format!("missing `gcc-path` value from `{}`", config_file.display(),)) + return Err(format!("missing `gcc-path` value from `{}`", config_file.display(),)); } }; Ok(()) diff --git a/compiler/rustc_codegen_gcc/build_system/src/test.rs b/compiler/rustc_codegen_gcc/build_system/src/test.rs index 8d088a3aac3..06f28d13fb3 100644 --- a/compiler/rustc_codegen_gcc/build_system/src/test.rs +++ b/compiler/rustc_codegen_gcc/build_system/src/test.rs @@ -109,7 +109,7 @@ impl TestArg { test_arg.flags.extend_from_slice(&["--features".into(), feature]); } _ => { - return Err("Expected an argument after `--features`, found nothing".into()) + return Err("Expected an argument after `--features`, found nothing".into()); } }, "--use-system-gcc" => { @@ -458,11 +458,7 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result<PathBuf, String> { .map_err(|error| format!("Failed to retrieve cargo path: {:?}", error)) .and_then(|cargo| { let cargo = cargo.trim().to_owned(); - if cargo.is_empty() { - Err(format!("`cargo` path is empty")) - } else { - Ok(cargo) - } + if cargo.is_empty() { Err(format!("`cargo` path is empty")) } else { Ok(cargo) } })?; let rustc = String::from_utf8( run_command_with_env(&[&"rustup", &toolchain, &"which", &"rustc"], rust_dir, Some(env))? @@ -471,11 +467,7 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result<PathBuf, String> { .map_err(|error| format!("Failed to retrieve rustc path: {:?}", error)) .and_then(|rustc| { let rustc = rustc.trim().to_owned(); - if rustc.is_empty() { - Err(format!("`rustc` path is empty")) - } else { - Ok(rustc) - } + if rustc.is_empty() { Err(format!("`rustc` path is empty")) } else { Ok(rustc) } })?; let llvm_filecheck = match run_command_with_env( &[ diff --git a/compiler/rustc_codegen_gcc/build_system/src/utils.rs b/compiler/rustc_codegen_gcc/build_system/src/utils.rs index 3bba8df6c65..e338d1b4992 100644 --- a/compiler/rustc_codegen_gcc/build_system/src/utils.rs +++ b/compiler/rustc_codegen_gcc/build_system/src/utils.rs @@ -175,11 +175,7 @@ pub fn cargo_install(to_install: &str) -> Result<(), String> { pub fn get_os_name() -> Result<String, String> { let output = run_command(&[&"uname"], None)?; let name = std::str::from_utf8(&output.stdout).unwrap_or("").trim().to_string(); - if !name.is_empty() { - Ok(name) - } else { - Err("Failed to retrieve the OS name".to_string()) - } + if !name.is_empty() { Ok(name) } else { Err("Failed to retrieve the OS name".to_string()) } } #[derive(Default, PartialEq)] diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 166dd080cf2..0a99e7213be 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -26,11 +26,7 @@ impl<'a, 'gcc, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } else { false }; - if on_stack { - param.to_lvalue().get_address(None) - } else { - param.to_rvalue() - } + if on_stack { param.to_lvalue().get_address(None) } else { param.to_rvalue() } } } diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index aa485846cd4..1da691252ab 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -858,11 +858,7 @@ fn modifier_to_gcc( InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => modifier, InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) | InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => { - if modifier == Some('v') { - None - } else { - modifier - } + if modifier == Some('v') { None } else { modifier } } InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => { unreachable!("clobber-only") diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 307348f595d..b9e4bd79fe1 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1043,11 +1043,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let llty = place.layout.scalar_pair_element_gcc_type(self, i); let load = self.load(llty, llptr, align); scalar_load_metadata(self, load, scalar); - if scalar.is_bool() { - self.trunc(load, self.type_i1()) - } else { - load - } + if scalar.is_bool() { self.trunc(load, self.type_i1()) } else { load } }; OperandValue::Pair( @@ -1795,18 +1791,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX. let int_max = |signed: bool, int_width: u64| -> u128 { let shift_amount = 128 - int_width; - if signed { - i128::MAX as u128 >> shift_amount - } else { - u128::MAX >> shift_amount - } + if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount } }; let int_min = |signed: bool, int_width: u64| -> i128 { - if signed { - i128::MIN >> (128 - int_width) - } else { - 0 - } + if signed { i128::MIN >> (128 - int_width) } else { 0 } }; let compute_clamp_bounds_single = |signed: bool, int_width: u64| -> (u128, u128) { diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 19333689aaa..70f0dc37e39 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -58,11 +58,7 @@ pub fn type_is_pointer(typ: Type<'_>) -> bool { impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn const_null(&self, typ: Type<'gcc>) -> RValue<'gcc> { - if type_is_pointer(typ) { - self.context.new_null(typ) - } else { - self.const_int(typ, 0) - } + if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) } } fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> { diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 822f5c2c44a..35e9a3b7dc2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -37,13 +37,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn eval_unevaluated_mir_constant_to_valtree( &self, constant: &mir::ConstOperand<'tcx>, - ) -> Result<Option<ty::ValTree<'tcx>>, ErrorHandled> { + ) -> Result<Result<ty::ValTree<'tcx>, Ty<'tcx>>, ErrorHandled> { let uv = match self.monomorphize(constant.const_) { mir::Const::Unevaluated(uv, _) => uv.shrink(), mir::Const::Ty(_, c) => match c.kind() { // A constant that came from a const generic but was then used as an argument to old-style // simd_shuffle (passing as argument instead of as a generic param). - rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Some(valtree)), + rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Ok(valtree)), other => span_bug!(constant.span, "{other:#?}"), }, // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate @@ -70,6 +70,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let val = self .eval_unevaluated_mir_constant_to_valtree(constant) .ok() + .map(|x| x.ok()) .flatten() .map(|val| { let field_ty = ty.builtin_index().unwrap(); diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 4ae4816e33a..3a6dc81eff1 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -27,15 +27,15 @@ pub(crate) use valtrees::{eval_to_valtree, valtree_to_const_value}; // We forbid type-level constants that contain more than `VALTREE_MAX_NODES` nodes. const VALTREE_MAX_NODES: usize = 100000; -pub(crate) enum ValTreeCreationError { +pub(crate) enum ValTreeCreationError<'tcx> { NodesOverflow, /// Values of this type, or this particular value, are not supported as valtrees. - NonSupportedType, + NonSupportedType(Ty<'tcx>), } -pub(crate) type ValTreeCreationResult<'tcx> = Result<ty::ValTree<'tcx>, ValTreeCreationError>; +pub(crate) type ValTreeCreationResult<'tcx> = Result<ty::ValTree<'tcx>, ValTreeCreationError<'tcx>>; -impl From<InterpErrorInfo<'_>> for ValTreeCreationError { - fn from(err: InterpErrorInfo<'_>) -> Self { +impl<'tcx> From<InterpErrorInfo<'tcx>> for ValTreeCreationError<'tcx> { + fn from(err: InterpErrorInfo<'tcx>) -> Self { ty::tls::with(|tcx| { bug!( "Unexpected Undefined Behavior error during valtree construction: {}", diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 2e8ad445cf5..3bc01510730 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -120,13 +120,13 @@ fn const_to_valtree_inner<'tcx>( // We could allow wide raw pointers where both sides are integers in the future, // but for now we reject them. if matches!(val.layout.abi, Abi::ScalarPair(..)) { - return Err(ValTreeCreationError::NonSupportedType); + return Err(ValTreeCreationError::NonSupportedType(ty)); } let val = val.to_scalar(); // We are in the CTFE machine, so ptr-to-int casts will fail. // This can only be `Ok` if `val` already is an integer. let Ok(val) = val.try_to_scalar_int() else { - return Err(ValTreeCreationError::NonSupportedType); + return Err(ValTreeCreationError::NonSupportedType(ty)); }; // It's just a ScalarInt! Ok(ty::ValTree::Leaf(val)) @@ -134,7 +134,7 @@ fn const_to_valtree_inner<'tcx>( // Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to // agree with runtime equality tests. - ty::FnPtr(_) => Err(ValTreeCreationError::NonSupportedType), + ty::FnPtr(_) => Err(ValTreeCreationError::NonSupportedType(ty)), ty::Ref(_, _, _) => { let derefd_place = ecx.deref_pointer(place)?; @@ -148,7 +148,7 @@ fn const_to_valtree_inner<'tcx>( // resolving their backing type, even if we can do that at const eval time. We may // hypothetically be able to allow `dyn StructuralPartialEq` trait objects in the future, // but it is unclear if this is useful. - ty::Dynamic(..) => Err(ValTreeCreationError::NonSupportedType), + ty::Dynamic(..) => Err(ValTreeCreationError::NonSupportedType(ty)), ty::Tuple(elem_tys) => { branches(ecx, place, elem_tys.len(), None, num_nodes) @@ -156,7 +156,7 @@ fn const_to_valtree_inner<'tcx>( ty::Adt(def, _) => { if def.is_union() { - return Err(ValTreeCreationError::NonSupportedType); + return Err(ValTreeCreationError::NonSupportedType(ty)); } else if def.variants().is_empty() { bug!("uninhabited types should have errored and never gotten converted to valtree") } @@ -180,7 +180,7 @@ fn const_to_valtree_inner<'tcx>( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) => Err(ValTreeCreationError::NonSupportedType), + | ty::CoroutineWitness(..) => Err(ValTreeCreationError::NonSupportedType(ty)), } } @@ -251,7 +251,7 @@ pub(crate) fn eval_to_valtree<'tcx>( let valtree_result = const_to_valtree_inner(&ecx, &place, &mut num_nodes); match valtree_result { - Ok(valtree) => Ok(Some(valtree)), + Ok(valtree) => Ok(Ok(valtree)), Err(err) => { let did = cid.instance.def_id(); let global_const_id = cid.display(tcx); @@ -262,7 +262,7 @@ pub(crate) fn eval_to_valtree<'tcx>( tcx.dcx().emit_err(MaxNumNodesInConstErr { span, global_const_id }); Err(handled.into()) } - ValTreeCreationError::NonSupportedType => Ok(None), + ValTreeCreationError::NonSupportedType(ty) => Ok(Err(ty)), } } } diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index e5e733439ea..3794a6e043c 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -56,5 +56,5 @@ portable-atomic = "1.5.1" [features] # tidy-alphabetical-start -rustc_use_parallel_compiler = ["indexmap/rustc-rayon", "rustc-rayon"] +rustc_use_parallel_compiler = ["indexmap/rustc-rayon", "dep:rustc-rayon"] # tidy-alphabetical-end diff --git a/compiler/rustc_error_codes/src/error_codes/E0158.md b/compiler/rustc_error_codes/src/error_codes/E0158.md index 03b93d925c1..c31f1e13bee 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0158.md +++ b/compiler/rustc_error_codes/src/error_codes/E0158.md @@ -1,5 +1,4 @@ -An associated `const`, `const` parameter or `static` has been referenced -in a pattern. +A generic parameter or `static` has been referenced in a pattern. Erroneous code example: @@ -15,25 +14,25 @@ trait Bar { fn test<A: Bar>(arg: Foo) { match arg { - A::X => println!("A::X"), // error: E0158: associated consts cannot be - // referenced in patterns + A::X => println!("A::X"), // error: E0158: constant pattern depends + // on a generic parameter Foo::Two => println!("Two") } } ``` -Associated `const`s cannot be referenced in patterns because it is impossible +Generic parameters cannot be referenced in patterns because it is impossible for the compiler to prove exhaustiveness (that some pattern will always match). Take the above example, because Rust does type checking in the *generic* method, not the *monomorphized* specific instance. So because `Bar` could have -theoretically infinite implementations, there's no way to always be sure that +theoretically arbitrary implementations, there's no way to always be sure that `A::X` is `Foo::One`. So this code must be rejected. Even if code can be proven exhaustive by a programmer, the compiler cannot currently prove this. -The same holds true of `const` parameters and `static`s. +The same holds true of `static`s. -If you want to match against an associated `const`, `const` parameter or -`static` consider using a guard instead: +If you want to match against a `const` that depends on a generic parameter or a +`static`, consider using a guard instead: ``` trait Trait { diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index dbbd948fd70..2964ac8cc58 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -119,6 +119,8 @@ impl MetaVarExpr { } } +/// Indicates what is placed in a `concat` parameter. For example, literals +/// (`${concat("foo", "bar")}`) or adhoc identifiers (`${concat(foo, bar)}`). #[derive(Debug, Decodable, Encodable, PartialEq)] pub(crate) enum MetaVarExprConcatElem { /// Identifier WITHOUT a preceding dollar sign, which means that this identifier should be diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 9b4dc13c703..7e2ea8de5fc 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -6,9 +6,10 @@ use crate::mbe::macro_parser::{NamedMatch, NamedMatch::*}; use crate::mbe::metavar_expr::{MetaVarExprConcatElem, RAW_IDENT_ERR}; use crate::mbe::{self, KleeneOp, MetaVarExpr}; use rustc_ast::mut_visit::{self, MutVisitor}; -use rustc_ast::token::IdentIsRaw; -use rustc_ast::token::{self, Delimiter, Token, TokenKind}; +use rustc_ast::token::{self, Delimiter, Nonterminal, Token, TokenKind}; +use rustc_ast::token::{IdentIsRaw, Lit, LitKind}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; +use rustc_ast::ExprKind; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{pluralize, Diag, DiagCtxtHandle, PResult}; use rustc_parse::lexer::nfc_normalize; @@ -17,7 +18,7 @@ use rustc_session::parse::ParseSess; use rustc_session::parse::SymbolGallery; use rustc_span::hygiene::{LocalExpnId, Transparency}; use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent}; -use rustc_span::{with_metavar_spans, Span, SyntaxContext}; +use rustc_span::{with_metavar_spans, Span, Symbol, SyntaxContext}; use smallvec::{smallvec, SmallVec}; use std::mem; @@ -691,12 +692,12 @@ fn transcribe_metavar_expr<'a>( MetaVarExpr::Concat(ref elements) => { let mut concatenated = String::new(); for element in elements.into_iter() { - let string = match element { - MetaVarExprConcatElem::Ident(elem) => elem.to_string(), - MetaVarExprConcatElem::Literal(elem) => elem.as_str().into(), - MetaVarExprConcatElem::Var(elem) => extract_ident(dcx, *elem, interp)?, + let symbol = match element { + MetaVarExprConcatElem::Ident(elem) => elem.name, + MetaVarExprConcatElem::Literal(elem) => *elem, + MetaVarExprConcatElem::Var(elem) => extract_var_symbol(dcx, *elem, interp)?, }; - concatenated.push_str(&string); + concatenated.push_str(symbol.as_str()); } let symbol = nfc_normalize(&concatenated); let concatenated_span = visited_span(); @@ -750,32 +751,42 @@ fn transcribe_metavar_expr<'a>( Ok(()) } -/// Extracts an identifier that can be originated from a `$var:ident` variable or from a token tree. -fn extract_ident<'a>( +/// Extracts an metavariable symbol that can be an identifier, a token tree or a literal. +fn extract_var_symbol<'a>( dcx: DiagCtxtHandle<'a>, ident: Ident, interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>, -) -> PResult<'a, String> { +) -> PResult<'a, Symbol> { if let NamedMatch::MatchedSingle(pnr) = matched_from_ident(dcx, ident, interp)? { if let ParseNtResult::Ident(nt_ident, is_raw) = pnr { if let IdentIsRaw::Yes = is_raw { return Err(dcx.struct_span_err(ident.span, RAW_IDENT_ERR)); } - return Ok(nt_ident.to_string()); + return Ok(nt_ident.name); } - if let ParseNtResult::Tt(TokenTree::Token( - Token { kind: TokenKind::Ident(token_ident, is_raw), .. }, - _, - )) = pnr - { - if let IdentIsRaw::Yes = is_raw { - return Err(dcx.struct_span_err(ident.span, RAW_IDENT_ERR)); + + if let ParseNtResult::Tt(TokenTree::Token(Token { kind, .. }, _)) = pnr { + if let TokenKind::Ident(symbol, is_raw) = kind { + if let IdentIsRaw::Yes = is_raw { + return Err(dcx.struct_span_err(ident.span, RAW_IDENT_ERR)); + } + return Ok(*symbol); } - return Ok(token_ident.to_string()); + + if let TokenKind::Literal(Lit { kind: LitKind::Str, symbol, suffix: None }) = kind { + return Ok(*symbol); + } + } + + if let ParseNtResult::Nt(nt) = pnr + && let Nonterminal::NtLiteral(expr) = &**nt + && let ExprKind::Lit(Lit { kind: LitKind::Str, symbol, suffix: None }) = &expr.kind + { + return Ok(*symbol); } } - Err(dcx.struct_span_err( - ident.span, - "`${concat(..)}` currently only accepts identifiers or meta-variables as parameters", - )) + Err(dcx + .struct_err("metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`") + .with_note("currently only string literals are supported") + .with_span(ident.span)) } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 5e595488ea7..968f38cf05d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1257,14 +1257,12 @@ pub fn prohibit_assoc_item_constraint( }; // Now emit the suggestion - if let Ok(suggestion) = tcx.sess.source_map().span_to_snippet(removal_span) { - e.span_suggestion_verbose( - removal_span, - format!("consider removing this associated item {}", constraint.kind.descr()), - suggestion, - Applicability::MaybeIncorrect, - ); - } + e.span_suggestion_verbose( + removal_span, + format!("consider removing this associated item {}", constraint.kind.descr()), + "", + Applicability::MaybeIncorrect, + ); }; // Suggest replacing the associated item binding with a generic argument. @@ -1340,11 +1338,13 @@ pub fn prohibit_assoc_item_constraint( format!("<{lifetimes}{type_with_constraints}>"), ) }; - let suggestions = - vec![param_decl, (constraint.span, format!("{}", matching_param.name))]; + let suggestions = vec![ + param_decl, + (constraint.span.with_lo(constraint.ident.span.hi()), String::new()), + ]; err.multipart_suggestion_verbose( - format!("declare the type parameter right after the `impl` keyword"), + "declare the type parameter right after the `impl` keyword", suggestions, Applicability::MaybeIncorrect, ); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index b6b1bf34653..2b4025ca808 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1105,7 +1105,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { "".to_string() }; - labels.push((provided_span, format!("unexpected argument{provided_ty_name}"))); + let idx = if provided_arg_tys.len() == 1 { + "".to_string() + } else { + format!(" #{}", arg_idx.as_usize() + 1) + }; + labels.push(( + provided_span, + format!("unexpected argument{idx}{provided_ty_name}"), + )); let mut span = provided_span; if span.can_be_used_for_suggestions() && error_span.can_be_used_for_suggestions() @@ -1186,7 +1194,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { "".to_string() }; - labels.push((span, format!("an argument{rendered} is missing"))); + labels.push(( + span, + format!( + "argument #{}{rendered} is missing", + expected_idx.as_usize() + 1 + ), + )); + suggestion_text = match suggestion_text { SuggestionText::None => SuggestionText::Provide(false), SuggestionText::Provide(_) => SuggestionText::Provide(true), diff --git a/compiler/rustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml index 3a4c813b5d4..92ea3f278dc 100644 --- a/compiler/rustc_index/Cargo.toml +++ b/compiler/rustc_index/Cargo.toml @@ -15,5 +15,9 @@ smallvec = "1.8.1" [features] # tidy-alphabetical-start default = ["nightly"] -nightly = ["rustc_serialize", "rustc_macros", "rustc_index_macros/nightly"] +nightly = [ + "dep:rustc_serialize", + "dep:rustc_macros", + "rustc_index_macros/nightly", +] # tidy-alphabetical-end diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index b866c8b8433..346ce945bf9 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -1,4 +1,4 @@ -#[cfg(feature = "rustc_serialize")] +#[cfg(feature = "nightly")] use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::borrow::{Borrow, BorrowMut}; @@ -322,14 +322,14 @@ impl<I: Idx, T, const N: usize> From<[T; N]> for IndexVec<I, T> { } } -#[cfg(feature = "rustc_serialize")] +#[cfg(feature = "nightly")] impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for IndexVec<I, T> { fn encode(&self, s: &mut S) { Encodable::encode(&self.raw, s); } } -#[cfg(feature = "rustc_serialize")] +#[cfg(feature = "nightly")] impl<D: Decoder, I: Idx, T: Decodable<D>> Decodable<D> for IndexVec<I, T> { fn decode(d: &mut D) -> Self { IndexVec::from_raw(Vec::<T>::decode(d)) diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index 7a5e7159920..c279195a7e9 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -225,6 +225,8 @@ infer_outlives_content = lifetime of reference outlives lifetime of borrowed con infer_precise_capturing_existing = add `{$new_lifetime}` to the `use<...>` bound to explicitly capture it infer_precise_capturing_new = add a `use<...>` bound to explicitly capture `{$new_lifetime}` +infer_precise_capturing_new_but_apit = add a `use<...>` bound to explicitly capture `{$new_lifetime}` after turning all argument-position `impl Trait` into type parameters, noting that this possibly affects the API of this crate + infer_prlf_defined_with_sub = the lifetime `{$sub_symbol}` defined here... infer_prlf_defined_without_sub = the lifetime defined here... infer_prlf_known_limitation = this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) @@ -387,6 +389,9 @@ infer_type_annotations_needed = {$source_kind -> .label = type must be known at this point infer_types_declared_different = these two types are declared with different lifetimes... + +infer_warn_removing_apit_params = you could use a `use<...>` bound to explicitly capture `{$new_lifetime}`, but argument-position `impl Trait`s are not nameable + infer_where_copy_predicates = copy the `where` clause predicates from the trait infer_where_remove = remove the `where` clause diff --git a/compiler/rustc_infer/src/error_reporting/infer/mod.rs b/compiler/rustc_infer/src/error_reporting/infer/mod.rs index ddd5818203c..a4af721cf75 100644 --- a/compiler/rustc_infer/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_infer/src/error_reporting/infer/mod.rs @@ -1930,7 +1930,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { struct SameTypeModuloInfer<'a, 'tcx>(&'a InferCtxt<'tcx>); impl<'tcx> TypeRelation<TyCtxt<'tcx>> for SameTypeModuloInfer<'_, 'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.0.tcx } diff --git a/compiler/rustc_infer/src/error_reporting/infer/region.rs b/compiler/rustc_infer/src/error_reporting/infer/region.rs index 093d2d3d743..5d41bb5d271 100644 --- a/compiler/rustc_infer/src/error_reporting/infer/region.rs +++ b/compiler/rustc_infer/src/error_reporting/infer/region.rs @@ -1269,9 +1269,13 @@ fn suggest_precise_capturing<'tcx>( captured_lifetime: ty::Region<'tcx>, diag: &mut Diag<'_>, ) { - let hir::OpaqueTy { bounds, .. } = + let hir::OpaqueTy { bounds, origin, .. } = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); + let hir::OpaqueTyOrigin::FnReturn(fn_def_id) = *origin else { + return; + }; + let new_lifetime = Symbol::intern(&captured_lifetime.to_string()); if let Some((args, span)) = bounds.iter().find_map(|bound| match bound { @@ -1306,6 +1310,7 @@ fn suggest_precise_capturing<'tcx>( let variances = tcx.variances_of(opaque_def_id); let mut generics = tcx.generics_of(opaque_def_id); + let mut synthetics = vec![]; loop { for param in &generics.own_params { if variances[param.index as usize] == ty::Bivariant { @@ -1317,9 +1322,7 @@ fn suggest_precise_capturing<'tcx>( captured_lifetimes.insert(param.name); } ty::GenericParamDefKind::Type { synthetic: true, .. } => { - // FIXME: We can't provide a good suggestion for - // `use<...>` if we have an APIT. Bail for now. - return; + synthetics.push((tcx.def_span(param.def_id), param.name)); } ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => { @@ -1340,17 +1343,86 @@ fn suggest_precise_capturing<'tcx>( return; } - let concatenated_bounds = captured_lifetimes - .into_iter() - .chain(captured_non_lifetimes) - .map(|sym| sym.to_string()) - .collect::<Vec<_>>() - .join(", "); - - diag.subdiagnostic(errors::AddPreciseCapturing::New { - span: tcx.def_span(opaque_def_id).shrink_to_hi(), - new_lifetime, - concatenated_bounds, - }); + if synthetics.is_empty() { + let concatenated_bounds = captured_lifetimes + .into_iter() + .chain(captured_non_lifetimes) + .map(|sym| sym.to_string()) + .collect::<Vec<_>>() + .join(", "); + + diag.subdiagnostic(errors::AddPreciseCapturing::New { + span: tcx.def_span(opaque_def_id).shrink_to_hi(), + new_lifetime, + concatenated_bounds, + }); + } else { + let mut next_fresh_param = || { + ["T", "U", "V", "W", "X", "Y", "A", "B", "C"] + .into_iter() + .map(Symbol::intern) + .chain((0..).map(|i| Symbol::intern(&format!("T{i}")))) + .find(|s| captured_non_lifetimes.insert(*s)) + .unwrap() + }; + + let mut new_params = String::new(); + let mut suggs = vec![]; + let mut apit_spans = vec![]; + + for (i, (span, name)) in synthetics.into_iter().enumerate() { + apit_spans.push(span); + + let fresh_param = next_fresh_param(); + + // Suggest renaming. + suggs.push((span, fresh_param.to_string())); + + // Super jank. Turn `impl Trait` into `T: Trait`. + // + // This currently involves stripping the `impl` from the name of + // the parameter, since APITs are always named after how they are + // rendered in the AST. This sucks! But to recreate the bound list + // from the APIT itself would be miserable, so we're stuck with + // this for now! + if i > 0 { + new_params += ", "; + } + let name_as_bounds = name.as_str().trim_start_matches("impl").trim_start(); + new_params += fresh_param.as_str(); + new_params += ": "; + new_params += name_as_bounds; + } + + let Some(generics) = tcx.hir().get_generics(fn_def_id) else { + // This shouldn't happen, but don't ICE. + return; + }; + + // Add generics or concatenate to the end of the list. + suggs.push(if let Some(params_span) = generics.span_for_param_suggestion() { + (params_span, format!(", {new_params}")) + } else { + (generics.span, format!("<{new_params}>")) + }); + + let concatenated_bounds = captured_lifetimes + .into_iter() + .chain(captured_non_lifetimes) + .map(|sym| sym.to_string()) + .collect::<Vec<_>>() + .join(", "); + + suggs.push(( + tcx.def_span(opaque_def_id).shrink_to_hi(), + format!(" + use<{concatenated_bounds}>"), + )); + + diag.subdiagnostic(errors::AddPreciseCapturingAndParams { + suggs, + new_lifetime, + apit_spans, + }); + } } } diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index f849a1a7322..2ce712e0bff 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1609,3 +1609,25 @@ pub enum AddPreciseCapturing { post: &'static str, }, } + +pub struct AddPreciseCapturingAndParams { + pub suggs: Vec<(Span, String)>, + pub new_lifetime: Symbol, + pub apit_spans: Vec<Span>, +} + +impl Subdiagnostic for AddPreciseCapturingAndParams { + fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( + self, + diag: &mut Diag<'_, G>, + _f: &F, + ) { + diag.arg("new_lifetime", self.new_lifetime); + diag.multipart_suggestion_verbose( + fluent::infer_precise_capturing_new_but_apit, + self.suggs, + Applicability::MaybeIncorrect, + ); + diag.span_note(self.apit_spans, fluent::infer_warn_removing_apit_params); + } +} diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index cfef1f13015..c9073d8c23e 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1427,17 +1427,17 @@ impl<'tcx> InferCtxt<'tcx> { span: Span, ) -> Result<ty::Const<'tcx>, ErrorHandled> { match self.const_eval_resolve(param_env, unevaluated, span) { - Ok(Some(val)) => Ok(ty::Const::new_value( + Ok(Ok(val)) => Ok(ty::Const::new_value( self.tcx, val, self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args), )), - Ok(None) => { + Ok(Err(bad_ty)) => { let tcx = self.tcx; let def_id = unevaluated.def; span_bug!( tcx.def_span(def_id), - "unable to construct a constant value for the unevaluated constant {:?}", + "unable to construct a valtree for the unevaluated constant {:?}: type {bad_ty} is not valtree-compatible", unevaluated ); } diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index 978b92fd898..d60d9113d91 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -137,7 +137,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx> "MatchAgainstHigherRankedOutlives" } - fn tcx(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index fe3b8d60fb9..ace439545b8 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -372,7 +372,7 @@ impl<'tcx> Generalizer<'_, 'tcx> { let is_nested_alias = mem::replace(&mut self.in_alias, true); let result = match self.relate(alias, alias) { - Ok(alias) => Ok(alias.to_ty(self.tcx())), + Ok(alias) => Ok(alias.to_ty(self.cx())), Err(e) => { if is_nested_alias { return Err(e); @@ -397,7 +397,7 @@ impl<'tcx> Generalizer<'_, 'tcx> { } impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -417,7 +417,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> { // (e.g., #41849). relate::relate_args_invariantly(self, a_arg, b_arg) } else { - let tcx = self.tcx(); + let tcx = self.cx(); let opt_variances = tcx.variances_of(item_def_id); relate::relate_args_with_variances( self, @@ -525,7 +525,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> { } debug!("replacing original vid={:?} with new={:?}", vid, new_var_id); - Ok(Ty::new_var(self.tcx(), new_var_id)) + Ok(Ty::new_var(self.cx(), new_var_id)) } } } @@ -654,7 +654,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> { { variable_table.union(vid, new_var_id); } - Ok(ty::Const::new_var(self.tcx(), new_var_id)) + Ok(ty::Const::new_var(self.cx(), new_var_id)) } } } @@ -672,7 +672,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> { args, args, )?; - Ok(ty::Const::new_unevaluated(self.tcx(), ty::UnevaluatedConst { def, args })) + Ok(ty::Const::new_unevaluated(self.cx(), ty::UnevaluatedConst { def, args })) } ty::ConstKind::Placeholder(placeholder) => { if self.for_universe.can_name(placeholder.universe) { diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index 5bb8a113e17..819a47fcf93 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -27,7 +27,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> { "Glb" } - fn tcx(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } @@ -61,7 +61,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> { let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone())); // GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8 Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions( - self.tcx(), + self.cx(), origin, a, b, diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index 94c1464817f..56d325c5dc1 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -27,7 +27,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> { "Lub" } - fn tcx(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } @@ -61,7 +61,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> { let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone())); // LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8 Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions( - self.tcx(), + self.cx(), origin, a, b, diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index e206f530519..97bd858defb 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -32,7 +32,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> { "TypeRelating" } - fn tcx(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.fields.infcx.tcx } @@ -48,7 +48,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> { // (e.g., #41849). relate_args_invariantly(self, a_arg, b_arg) } else { - let tcx = self.tcx(); + let tcx = self.cx(); let opt_variances = tcx.variances_of(item_def_id); relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, false) } @@ -88,7 +88,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> { // can't make progress on `A <: B` if both A and B are // type variables, so record an obligation. self.fields.goals.push(Goal::new( - self.tcx(), + self.cx(), self.fields.param_env, ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: true, @@ -101,7 +101,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> { // can't make progress on `B <: A` if both A and B are // type variables, so record an obligation. self.fields.goals.push(Goal::new( - self.tcx(), + self.cx(), self.fields.param_env, ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: false, @@ -134,7 +134,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> { (&ty::Error(e), _) | (_, &ty::Error(e)) => { infcx.set_tainted_by_errors(e); - return Ok(Ty::new_error(self.tcx(), e)); + return Ok(Ty::new_error(self.cx(), e)); } ( diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 4b3b0728f38..b5abf145d6b 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -53,6 +53,11 @@ tracing = "0.1" [features] # tidy-alphabetical-start -llvm = ['rustc_codegen_llvm'] -rustc_use_parallel_compiler = ['rustc-rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler', 'rustc_errors/rustc_use_parallel_compiler'] +llvm = ['dep:rustc_codegen_llvm'] +rustc_use_parallel_compiler = [ + 'dep:rustc-rayon', + 'dep:rustc-rayon-core', + 'rustc_query_impl/rustc_use_parallel_compiler', + 'rustc_errors/rustc_use_parallel_compiler' +] # tidy-alphabetical-end diff --git a/compiler/rustc_macros/src/lift.rs b/compiler/rustc_macros/src/lift.rs index d41ceb29816..627f4088d5f 100644 --- a/compiler/rustc_macros/src/lift.rs +++ b/compiler/rustc_macros/src/lift.rs @@ -45,7 +45,7 @@ pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStre quote! { type Lifted = #lifted; - fn lift_to_tcx(self, __tcx: ::rustc_middle::ty::TyCtxt<'__lifted>) -> Option<#lifted> { + fn lift_to_interner(self, __tcx: ::rustc_middle::ty::TyCtxt<'__lifted>) -> Option<#lifted> { Some(match self { #body }) } }, diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 3dc592980fd..290ebde8712 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -40,5 +40,5 @@ tracing = "0.1" [features] # tidy-alphabetical-start -rustc_use_parallel_compiler = ["rustc-rayon-core"] +rustc_use_parallel_compiler = ["dep:rustc-rayon-core"] # tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index fcea1ea81a7..d385be007d3 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -59,7 +59,7 @@ macro_rules! TrivialLiftImpls { $( impl<'tcx> $crate::ty::Lift<$crate::ty::TyCtxt<'tcx>> for $ty { type Lifted = Self; - fn lift_to_tcx(self, _: $crate::ty::TyCtxt<'tcx>) -> Option<Self> { + fn lift_to_interner(self, _: $crate::ty::TyCtxt<'tcx>) -> Option<Self> { Some(self) } } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 6a8498abaf9..9df19565ab3 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -90,9 +90,11 @@ TrivialTypeTraversalImpls! { ErrorHandled } pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>; pub type EvalStaticInitializerRawResult<'tcx> = Result<ConstAllocation<'tcx>, ErrorHandled>; pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>; -/// `Ok(None)` indicates the constant was fine, but the valtree couldn't be constructed. -/// This is needed in `thir::pattern::lower_inline_const`. -pub type EvalToValTreeResult<'tcx> = Result<Option<ValTree<'tcx>>, ErrorHandled>; +/// `Ok(Err(ty))` indicates the constant was fine, but the valtree couldn't be constructed +/// because the value containts something of type `ty` that is not valtree-compatible. +/// The caller can then show an appropriate error; the query does not have the +/// necssary context to give good user-facing errors for this case. +pub type EvalToValTreeResult<'tcx> = Result<Result<ValTree<'tcx>, Ty<'tcx>>, ErrorHandled>; #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(InterpErrorInfo<'_>, 8); diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 301c9911b44..d9fa5b02f7f 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -157,9 +157,10 @@ impl EraseType for Result<mir::ConstValue<'_>, mir::interpret::ErrorHandled> { type Result = [u8; size_of::<Result<mir::ConstValue<'static>, mir::interpret::ErrorHandled>>()]; } -impl EraseType for Result<Option<ty::ValTree<'_>>, mir::interpret::ErrorHandled> { - type Result = - [u8; size_of::<Result<Option<ty::ValTree<'static>>, mir::interpret::ErrorHandled>>()]; +impl EraseType for Result<Result<ty::ValTree<'_>, Ty<'_>>, mir::interpret::ErrorHandled> { + type Result = [u8; size_of::< + Result<Result<ty::ValTree<'static>, Ty<'static>>, mir::interpret::ErrorHandled>, + >()]; } impl EraseType for Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop> { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index c97af68c29e..b80d00719ee 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -783,16 +783,13 @@ pub enum PatKind<'tcx> { }, /// One of the following: - /// * `&str` (represented as a valtree), which will be handled as a string pattern and thus - /// exhaustiveness checking will detect if you use the same string twice in different - /// patterns. + /// * `&str`/`&[u8]` (represented as a valtree), which will be handled as a string/slice pattern + /// and thus exhaustiveness checking will detect if you use the same string/slice twice in + /// different patterns. /// * integer, bool, char or float (represented as a valtree), which will be handled by /// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are /// much simpler. - /// * Opaque constants (represented as `mir::ConstValue`), that must not be matched - /// structurally. So anything that does not derive `PartialEq` and `Eq`. - /// - /// These are always compared with the matched place using (the semantics of) `PartialEq`. + /// * `String`, if `string_deref_patterns` is enabled. Constant { value: mir::Const<'tcx>, }, diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 32d01d07c17..4d213d14af1 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,6 +1,7 @@ use crate::middle::resolve_bound_vars as rbv; use crate::mir::interpret::{ErrorHandled, LitToConstInput, Scalar}; use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; +use either::Either; use rustc_data_structures::intern::Interned; use rustc_error_messages::MultiSpan; use rustc_hir as hir; @@ -312,14 +313,16 @@ impl<'tcx> Const<'tcx> { Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize)) } - /// Returns the evaluated constant + /// Returns the evaluated constant as a valtree; + /// if that fails due to a valtree-incompatible type, indicate which type that is + /// by returning `Err(Left(bad_type))`. #[inline] - pub fn eval( + pub fn eval_valtree( self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, span: Span, - ) -> Result<(Ty<'tcx>, ValTree<'tcx>), ErrorHandled> { + ) -> Result<(Ty<'tcx>, ValTree<'tcx>), Either<Ty<'tcx>, ErrorHandled>> { assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}"); match self.kind() { ConstKind::Unevaluated(unevaluated) => { @@ -328,27 +331,47 @@ impl<'tcx> Const<'tcx> { let (param_env, unevaluated) = unevaluated.prepare_for_eval(tcx, param_env); // try to resolve e.g. associated constants to their definition on an impl, and then // evaluate the const. - let Some(c) = tcx.const_eval_resolve_for_typeck(param_env, unevaluated, span)? - else { - // This can happen when we run on ill-typed code. - let e = tcx.dcx().span_delayed_bug( - span, - "`ty::Const::eval` called on a non-valtree-compatible type", - ); - return Err(e.into()); - }; - Ok((tcx.type_of(unevaluated.def).instantiate(tcx, unevaluated.args), c)) + match tcx.const_eval_resolve_for_typeck(param_env, unevaluated, span) { + Ok(Ok(c)) => { + Ok((tcx.type_of(unevaluated.def).instantiate(tcx, unevaluated.args), c)) + } + Ok(Err(bad_ty)) => Err(Either::Left(bad_ty)), + Err(err) => Err(Either::Right(err.into())), + } } ConstKind::Value(ty, val) => Ok((ty, val)), - ConstKind::Error(g) => Err(g.into()), + ConstKind::Error(g) => Err(Either::Right(g.into())), ConstKind::Param(_) | ConstKind::Infer(_) | ConstKind::Bound(_, _) | ConstKind::Placeholder(_) - | ConstKind::Expr(_) => Err(ErrorHandled::TooGeneric(span)), + | ConstKind::Expr(_) => Err(Either::Right(ErrorHandled::TooGeneric(span))), } } + /// Returns the evaluated constant + #[inline] + pub fn eval( + self, + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + span: Span, + ) -> Result<(Ty<'tcx>, ValTree<'tcx>), ErrorHandled> { + self.eval_valtree(tcx, param_env, span).map_err(|err| { + match err { + Either::Right(err) => err, + Either::Left(_bad_ty) => { + // This can happen when we run on ill-typed code. + let e = tcx.dcx().span_delayed_bug( + span, + "`ty::Const::eval` called on a non-valtree-compatible type", + ); + e.into() + } + } + }) + } + /// Normalizes the constant to a value or an error if possible. #[inline] pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 25070e6b042..fd41668ae44 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1484,7 +1484,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> { - value.lift_to_tcx(self) + value.lift_to_interner(self) } /// Creates a type context. To use the context call `fn enter` which @@ -2087,7 +2087,7 @@ macro_rules! nop_lift { ($set:ident; $ty:ty => $lifted:ty) => { impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty { type Lifted = $lifted; - fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { + fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { // Assert that the set has the right type. // Given an argument that has an interned type, the return type has the type of // the corresponding interner set. This won't actually return anything, we're @@ -2122,7 +2122,7 @@ macro_rules! nop_list_lift { ($set:ident; $ty:ty => $lifted:ty) => { impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> { type Lifted = &'tcx List<$lifted>; - fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { + fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { // Assert that the set has the right type. if false { let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set; @@ -2160,7 +2160,7 @@ macro_rules! nop_slice_lift { ($ty:ty => $lifted:ty) => { impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a [$ty] { type Lifted = &'tcx [$lifted]; - fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { + fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { if self.is_empty() { return Some(&[]); } diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 4bf22337991..f479b18c7c4 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -271,6 +271,19 @@ pub fn suggest_constraining_type_params<'a>( } } + // in the scenario like impl has stricter requirements than trait, + // we should not suggest restrict bound on the impl, here we double check + // the whether the param already has the constraint by checking `def_id` + let bound_trait_defs: Vec<DefId> = generics + .bounds_for_param(param.def_id) + .flat_map(|bound| { + bound.bounds.iter().flat_map(|b| b.trait_ref().and_then(|t| t.trait_def_id())) + }) + .collect(); + + constraints + .retain(|(_, def_id)| def_id.map_or(true, |def| !bound_trait_defs.contains(&def))); + if constraints.is_empty() { continue; } @@ -332,6 +345,7 @@ pub fn suggest_constraining_type_params<'a>( // -- // | // replace with: `T: Bar +` + if let Some((span, open_paren_sp)) = generics.bounds_span_for_suggestions(param.def_id) { suggest_restrict(span, true, open_paren_sp); continue; diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 5ac3168196a..10919623de7 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -308,7 +308,7 @@ impl<'tcx> GenericArg<'tcx> { impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for GenericArg<'a> { type Lifted = GenericArg<'tcx>; - fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { + fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { match self.unpack() { GenericArgKind::Lifetime(lt) => tcx.lift(lt).map(|lt| lt.into()), GenericArgKind::Type(ty) => tcx.lift(ty).map(|ty| ty.into()), diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index df080b2887b..57cd2dc73c4 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1214,11 +1214,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { && let ty::Alias(_, alias_ty) = self.tcx().fn_sig(fn_def_id).skip_binder().output().skip_binder().kind() && alias_ty.def_id == def_id + && let generics = self.tcx().generics_of(fn_def_id) + // FIXME(return_type_notation): We only support lifetime params for now. + && generics.own_params.iter().all(|param| matches!(param.kind, ty::GenericParamDefKind::Lifetime)) { - let num_args = self.tcx().generics_of(fn_def_id).count(); + let num_args = generics.count(); write!(self, " {{ ")?; self.print_def_path(fn_def_id, &args[..num_args])?; - write!(self, "() }}")?; + write!(self, "(..) }}")?; } Ok(()) diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index ebf0d7ed737..61c03922ac0 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -69,7 +69,7 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for ty::Pattern<'tcx> { if inc_a != inc_b { todo!() } - Ok(relation.tcx().mk_pat(ty::PatternKind::Range { start, end, include_end: inc_a })) + Ok(relation.cx().mk_pat(ty::PatternKind::Range { start, end, include_end: inc_a })) } } } @@ -81,7 +81,7 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate< a: Self, b: Self, ) -> RelateResult<'tcx, Self> { - let tcx = relation.tcx(); + let tcx = relation.cx(); // FIXME: this is wasteful, but want to do a perf run to see how slow it is. // We need to perform this deduplication as we sometimes generate duplicate projections diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 00ea87690c1..7cdc0e32953 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -283,7 +283,7 @@ TrivialTypeTraversalAndLiftImpls! { impl<'tcx, T: Lift<TyCtxt<'tcx>>> Lift<TyCtxt<'tcx>> for Option<T> { type Lifted = Option<T::Lifted>; - fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { + fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { Some(match self { Some(x) => Some(tcx.lift(x)?), None => None, @@ -293,7 +293,7 @@ impl<'tcx, T: Lift<TyCtxt<'tcx>>> Lift<TyCtxt<'tcx>> for Option<T> { impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Term<'a> { type Lifted = ty::Term<'tcx>; - fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { + fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { match self.unpack() { TermKind::Ty(ty) => tcx.lift(ty).map(Into::into), TermKind::Const(c) => tcx.lift(c).map(Into::into), diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 5d828d0093f..529e9cc2711 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start +either = "1.5.0" itertools = "0.12" rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 0c277811fda..281f3ef6ef3 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -4,8 +4,6 @@ mir_build_already_borrowed = cannot borrow value as mutable because it is also b mir_build_already_mut_borrowed = cannot borrow value as immutable because it is also borrowed as mutable -mir_build_assoc_const_in_pattern = associated consts cannot be referenced in patterns - mir_build_bindings_with_variant_name = pattern binding `{$name}` is named the same as one of the variants of the type `{$ty_path}` .suggestion = to match on the variant, qualify the path diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 5ccbd7c59cf..c608e5c63d8 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -71,11 +71,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { StmtKind::Expr { scope, expr } => { this.block_context.push(BlockFrame::Statement { ignores_expr_result: true }); let si = (*scope, source_info); - unpack!( - block = this.in_scope(si, LintLevel::Inherited, |this| { + block = this + .in_scope(si, LintLevel::Inherited, |this| { this.stmt_expr(block, *expr, Some(*scope)) }) - ); + .into_block(); } StmtKind::Let { remainder_scope, @@ -166,14 +166,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let dummy_place = this.temp(this.tcx.types.never, else_block_span); let failure_entry = this.cfg.start_new_block(); let failure_block; - unpack!( - failure_block = this.ast_block( + failure_block = this + .ast_block( dummy_place, failure_entry, *else_block, this.source_info(else_block_span), ) - ); + .into_block(); this.cfg.terminate( failure_block, this.source_info(else_block_span), @@ -267,8 +267,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let initializer_span = this.thir[init].span; let scope = (*init_scope, source_info); - unpack!( - block = this.in_scope(scope, *lint_level, |this| { + block = this + .in_scope(scope, *lint_level, |this| { this.declare_bindings( visibility_scope, remainder_span, @@ -279,10 +279,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.expr_into_pattern(block, &pattern, init) // irrefutable pattern }) - ) + .into_block(); } else { let scope = (*init_scope, source_info); - unpack!(this.in_scope(scope, *lint_level, |this| { + let _: BlockAnd<()> = this.in_scope(scope, *lint_level, |this| { this.declare_bindings( visibility_scope, remainder_span, @@ -291,7 +291,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None, ); block.unit() - })); + }); debug!("ast_block_stmts: pattern={:?}", pattern); this.visit_primary_bindings( @@ -333,7 +333,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.block_context .push(BlockFrame::TailExpr { tail_result_is_ignored, span: expr.span }); - unpack!(block = this.expr_into_dest(destination, block, expr_id)); + block = this.expr_into_dest(destination, block, expr_id).into_block(); let popped = this.block_context.pop(); assert!(popped.is_some_and(|bf| bf.is_tail_expr())); @@ -355,7 +355,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Finally, we pop all the let scopes before exiting out from the scope of block // itself. for scope in let_scope_stack.into_iter().rev() { - unpack!(block = this.pop_scope((*scope, source_info), block)); + block = this.pop_scope((*scope, source_info), block).into_block(); } // Restore the original source scope. this.source_scope = outer_source_scope; diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index c5ee6db5999..40cfe563acc 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -185,13 +185,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.cfg.push_assign(block, source_info, Place::from(result), box_); // initialize the box contents: - unpack!( - block = this.expr_into_dest( - this.tcx.mk_place_deref(Place::from(result)), - block, - value, - ) - ); + block = this + .expr_into_dest(this.tcx.mk_place_deref(Place::from(result)), block, value) + .into_block(); block.and(Rvalue::Use(Operand::Move(Place::from(result)))) } ExprKind::Cast { source } => { @@ -486,7 +482,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.and(Rvalue::Aggregate(result, operands)) } ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => { - block = unpack!(this.stmt_expr(block, expr_id, None)); + block = this.stmt_expr(block, expr_id, None).into_block(); block.and(Rvalue::Use(Operand::Constant(Box::new(ConstOperand { span: expr_span, user_ty: None, diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs index 607c7c3259c..82673582e79 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs @@ -112,7 +112,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - unpack!(block = this.expr_into_dest(temp_place, block, expr_id)); + block = this.expr_into_dest(temp_place, block, expr_id).into_block(); if let Some(temp_lifetime) = temp_lifetime { this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Value); diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 942c69b5c0a..9cd958a21da 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -82,13 +82,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Lower the condition, and have it branch into `then` and `else` blocks. let (then_block, else_block) = this.in_if_then_scope(condition_scope, then_span, |this| { - let then_blk = unpack!(this.then_else_break( - block, - cond, - Some(condition_scope), // Temp scope - source_info, - DeclareLetBindings::Yes, // Declare `let` bindings normally - )); + let then_blk = this + .then_else_break( + block, + cond, + Some(condition_scope), // Temp scope + source_info, + DeclareLetBindings::Yes, // Declare `let` bindings normally + ) + .into_block(); // Lower the `then` arm into its block. this.expr_into_dest(destination, then_blk, then) @@ -105,7 +107,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // If there is an `else` arm, lower it into `else_blk`. if let Some(else_expr) = else_opt { - unpack!(else_blk = this.expr_into_dest(destination, else_blk, else_expr)); + else_blk = this.expr_into_dest(destination, else_blk, else_expr).into_block(); } else { // There is no `else` arm, so we know both arms have type `()`. // Generate the implicit `else {}` by assigning unit. @@ -187,7 +189,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { const_: Const::from_bool(this.tcx, constant), }, ); - let mut rhs_block = unpack!(this.expr_into_dest(destination, continuation, rhs)); + let mut rhs_block = + this.expr_into_dest(destination, continuation, rhs).into_block(); // Instrument the lowered RHS's value for condition coverage. // (Does nothing if condition coverage is not enabled.) this.visit_coverage_standalone_condition(rhs, destination, &mut rhs_block); @@ -230,7 +233,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // introduce a unit temporary as the destination for the loop body. let tmp = this.get_unit_temp(); // Execute the body, branching back to the test. - let body_block_end = unpack!(this.expr_into_dest(tmp, body_block, body)); + let body_block_end = this.expr_into_dest(tmp, body_block, body).into_block(); this.cfg.goto(body_block_end, source_info, loop_block); // Loops are only exited by `break` expressions. @@ -462,7 +465,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { targets.push(target); let tmp = this.get_unit_temp(); - let target = unpack!(this.ast_block(tmp, target, block, source_info)); + let target = + this.ast_block(tmp, target, block, source_info).into_block(); this.cfg.terminate( target, source_info, @@ -502,7 +506,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // These cases don't actually need a destination ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => { - unpack!(block = this.stmt_expr(block, expr_id, None)); + block = this.stmt_expr(block, expr_id, None).into_block(); this.cfg.push_assign_unit(block, source_info, destination, this.tcx); block.unit() } @@ -511,7 +515,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::Break { .. } | ExprKind::Return { .. } | ExprKind::Become { .. } => { - unpack!(block = this.stmt_expr(block, expr_id, None)); + block = this.stmt_expr(block, expr_id, None).into_block(); // No assign, as these have type `!`. block.unit() } diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index 88b76c46c90..8e13edb4c89 100644 --- a/compiler/rustc_mir_build/src/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs @@ -44,7 +44,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if lhs_expr.ty.needs_drop(this.tcx, this.param_env) { let rhs = unpack!(block = this.as_local_rvalue(block, rhs)); let lhs = unpack!(block = this.as_place(block, lhs)); - unpack!(block = this.build_drop_and_replace(block, lhs_expr.span, lhs, rhs)); + block = + this.build_drop_and_replace(block, lhs_expr.span, lhs, rhs).into_block(); } else { let rhs = unpack!(block = this.as_local_rvalue(block, rhs)); let lhs = unpack!(block = this.as_place(block, lhs)); diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index fc4e9ebec0a..20c33745af8 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -122,8 +122,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match expr.kind { ExprKind::LogicalOp { op: op @ LogicalOp::And, lhs, rhs } => { this.visit_coverage_branch_operation(op, expr_span); - let lhs_then_block = unpack!(this.then_else_break_inner(block, lhs, args)); - let rhs_then_block = unpack!(this.then_else_break_inner(lhs_then_block, rhs, args)); + let lhs_then_block = this.then_else_break_inner(block, lhs, args).into_block(); + let rhs_then_block = + this.then_else_break_inner(lhs_then_block, rhs, args).into_block(); rhs_then_block.unit() } ExprKind::LogicalOp { op: op @ LogicalOp::Or, lhs, rhs } => { @@ -140,14 +141,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }, ) }); - let rhs_success_block = unpack!(this.then_else_break_inner( - failure_block, - rhs, - ThenElseArgs { - declare_let_bindings: DeclareLetBindings::LetNotPermitted, - ..args - }, - )); + let rhs_success_block = this + .then_else_break_inner( + failure_block, + rhs, + ThenElseArgs { + declare_let_bindings: DeclareLetBindings::LetNotPermitted, + ..args + }, + ) + .into_block(); // Make the LHS and RHS success arms converge to a common block. // (We can't just make LHS goto RHS, because `rhs_success_block` @@ -452,7 +455,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { outer_source_info: SourceInfo, fake_borrow_temps: Vec<(Place<'tcx>, Local, FakeBorrowKind)>, ) -> BlockAnd<()> { - let arm_end_blocks: Vec<_> = arm_candidates + let arm_end_blocks: Vec<BasicBlock> = arm_candidates .into_iter() .map(|(arm, candidate)| { debug!("lowering arm {:?}\ncandidate = {:?}", arm, candidate); @@ -503,6 +506,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.expr_into_dest(destination, arm_block, arm.body) }) + .into_block() }) .collect(); @@ -513,10 +517,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { outer_source_info.span.with_lo(outer_source_info.span.hi() - BytePos::from_usize(1)), ); for arm_block in arm_end_blocks { - let block = &self.cfg.basic_blocks[arm_block.0]; + let block = &self.cfg.basic_blocks[arm_block]; let last_location = block.statements.last().map(|s| s.source_info); - self.cfg.goto(unpack!(arm_block), last_location.unwrap_or(end_brace), end_block); + self.cfg.goto(arm_block, last_location.unwrap_or(end_brace), end_block); } self.source_scope = outer_source_info.scope; @@ -622,7 +626,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { OutsideGuard, ScheduleDrops::Yes, ); - unpack!(block = self.expr_into_dest(place, block, initializer_id)); + block = self.expr_into_dest(place, block, initializer_id).into_block(); // Inject a fake read, see comments on `FakeReadCause::ForLet`. let source_info = self.source_info(irrefutable_pat.span); @@ -661,7 +665,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { OutsideGuard, ScheduleDrops::Yes, ); - unpack!(block = self.expr_into_dest(place, block, initializer_id)); + block = self.expr_into_dest(place, block, initializer_id).into_block(); // Inject a fake read, see comments on `FakeReadCause::ForLet`. let pattern_source_info = self.source_info(irrefutable_pat.span); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index d29874a5ad4..5aed2537750 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -144,7 +144,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { && tcx.is_lang_item(def.did(), LangItem::String) { if !tcx.features().string_deref_patterns { - bug!( + span_bug!( + test.span, "matching on `String` went through without enabling string_deref_patterns" ); } @@ -432,40 +433,28 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - match *ty.kind() { - ty::Ref(_, deref_ty, _) => ty = deref_ty, - _ => { - // non_scalar_compare called on non-reference type - let temp = self.temp(ty, source_info.span); - self.cfg.push_assign(block, source_info, temp, Rvalue::Use(expect)); - let ref_ty = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, ty); - let ref_temp = self.temp(ref_ty, source_info.span); - - self.cfg.push_assign( - block, - source_info, - ref_temp, - Rvalue::Ref(self.tcx.lifetimes.re_erased, BorrowKind::Shared, temp), - ); - expect = Operand::Move(ref_temp); - - let ref_temp = self.temp(ref_ty, source_info.span); - self.cfg.push_assign( - block, - source_info, - ref_temp, - Rvalue::Ref(self.tcx.lifetimes.re_erased, BorrowKind::Shared, val), - ); - val = ref_temp; + // Figure out the type on which we are calling `PartialEq`. This involves an extra wrapping + // reference: we can only compare two `&T`, and then compare_ty will be `T`. + // Make sure that we do *not* call any user-defined code here. + // The only types that can end up here are string and byte literals, + // which have their comparison defined in `core`. + // (Interestingly this means that exhaustiveness analysis relies, for soundness, + // on the `PartialEq` impls for `str` and `[u8]` to b correct!) + let compare_ty = match *ty.kind() { + ty::Ref(_, deref_ty, _) + if deref_ty == self.tcx.types.str_ || deref_ty != self.tcx.types.u8 => + { + deref_ty } - } + _ => span_bug!(source_info.span, "invalid type for non-scalar compare: {}", ty), + }; let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); let method = trait_method( self.tcx, eq_def_id, sym::eq, - self.tcx.with_opt_host_effect_param(self.def_id, eq_def_id, [ty, ty]), + self.tcx.with_opt_host_effect_param(self.def_id, eq_def_id, [compare_ty, compare_ty]), ); let bool_ty = self.tcx.types.bool; diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 0f9746cb719..2793a7d8736 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -403,6 +403,15 @@ enum NeedsTemporary { #[must_use = "if you don't use one of these results, you're leaving a dangling edge"] struct BlockAnd<T>(BasicBlock, T); +impl BlockAnd<()> { + /// Unpacks `BlockAnd<()>` into a [`BasicBlock`]. + #[must_use] + fn into_block(self) -> BasicBlock { + let Self(block, ()) = self; + block + } +} + trait BlockAndExtension { fn and<T>(self, v: T) -> BlockAnd<T>; fn unit(self) -> BlockAnd<()>; @@ -426,11 +435,6 @@ macro_rules! unpack { $x = b; v }}; - - ($c:expr) => {{ - let BlockAnd(b, ()) = $c; - b - }}; } /////////////////////////////////////////////////////////////////////////// @@ -516,21 +520,22 @@ fn construct_fn<'tcx>( region::Scope { id: body.id().hir_id.local_id, data: region::ScopeData::Arguments }; let source_info = builder.source_info(span); let call_site_s = (call_site_scope, source_info); - unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| { + let _: BlockAnd<()> = builder.in_scope(call_site_s, LintLevel::Inherited, |builder| { let arg_scope_s = (arg_scope, source_info); // Attribute epilogue to function's closing brace let fn_end = span_with_body.shrink_to_hi(); - let return_block = - unpack!(builder.in_breakable_scope(None, Place::return_place(), fn_end, |builder| { + let return_block = builder + .in_breakable_scope(None, Place::return_place(), fn_end, |builder| { Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| { builder.args_and_body(START_BLOCK, arguments, arg_scope, expr) })) - })); + }) + .into_block(); let source_info = builder.source_info(fn_end); builder.cfg.terminate(return_block, source_info, TerminatorKind::Return); builder.build_drop_trees(); return_block.unit() - })); + }); let mut body = builder.finish(); @@ -579,7 +584,7 @@ fn construct_const<'a, 'tcx>( Builder::new(thir, infcx, def, hir_id, span, 0, const_ty, const_ty_span, None); let mut block = START_BLOCK; - unpack!(block = builder.expr_into_dest(Place::return_place(), block, expr)); + block = builder.expr_into_dest(Place::return_place(), block, expr).into_block(); let source_info = builder.source_info(span); builder.cfg.terminate(block, source_info, TerminatorKind::Return); @@ -961,7 +966,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Some((Some(&place), span)), ); let place_builder = PlaceBuilder::from(local); - unpack!(block = self.place_into_pattern(block, pat, place_builder, false)); + block = self.place_into_pattern(block, pat, place_builder, false).into_block(); } } self.source_scope = original_source_scope; diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 948301e2ece..b630c74a202 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -510,12 +510,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let target = self.cfg.start_new_block(); let source_info = self.source_info(span); self.cfg.terminate( - unpack!(normal_block), + normal_block.into_block(), source_info, TerminatorKind::Goto { target }, ); self.cfg.terminate( - unpack!(exit_block), + exit_block.into_block(), source_info, TerminatorKind::Goto { target }, ); @@ -552,14 +552,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let scope = IfThenScope { region_scope, else_drops: DropTree::new() }; let previous_scope = mem::replace(&mut self.scopes.if_then_scope, Some(scope)); - let then_block = unpack!(f(self)); + let then_block = f(self).into_block(); let if_then_scope = mem::replace(&mut self.scopes.if_then_scope, previous_scope).unwrap(); assert!(if_then_scope.region_scope == region_scope); - let else_block = self - .build_exit_tree(if_then_scope.else_drops, region_scope, span, None) - .map_or_else(|| self.cfg.start_new_block(), |else_block_and| unpack!(else_block_and)); + let else_block = + self.build_exit_tree(if_then_scope.else_drops, region_scope, span, None).map_or_else( + || self.cfg.start_new_block(), + |else_block_and| else_block_and.into_block(), + ); (then_block, else_block) } @@ -585,7 +587,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.push_scope(region_scope); let mut block; let rv = unpack!(block = f(self)); - unpack!(block = self.pop_scope(region_scope, block)); + block = self.pop_scope(region_scope, block).into_block(); self.source_scope = source_scope; debug!(?block); block.and(rv) @@ -657,7 +659,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { (Some(destination), Some(value)) => { debug!("stmt_expr Break val block_context.push(SubExpr)"); self.block_context.push(BlockFrame::SubExpr); - unpack!(block = self.expr_into_dest(destination, block, value)); + block = self.expr_into_dest(destination, block, value).into_block(); self.block_context.pop(); } (Some(destination), None) => { @@ -838,7 +840,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let unwind_to = if needs_cleanup { self.diverge_cleanup() } else { DropIdx::MAX }; let scope = self.scopes.scopes.last().expect("leave_top_scope called with no scopes"); - unpack!(build_scope_drops( + build_scope_drops( &mut self.cfg, &mut self.scopes.unwind_drops, scope, @@ -846,7 +848,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unwind_to, is_coroutine && needs_cleanup, self.arg_count, - )) + ) + .into_block() } /// Possibly creates a new source scope if `current_root` and `parent_root` diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 7c73d8a6d47..f6f443b64a6 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -567,13 +567,6 @@ pub(crate) struct StaticInPattern { } #[derive(Diagnostic)] -#[diag(mir_build_assoc_const_in_pattern, code = E0158)] -pub(crate) struct AssocConstInPattern { - #[primary_span] - pub(crate) span: Span, -} - -#[derive(Diagnostic)] #[diag(mir_build_const_param_in_pattern, code = E0158)] pub(crate) struct ConstParamInPattern { #[primary_span] @@ -597,7 +590,7 @@ pub(crate) struct UnreachablePattern { } #[derive(Diagnostic)] -#[diag(mir_build_const_pattern_depends_on_generic_parameter)] +#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)] pub(crate) struct ConstPatternDependsOnGenericParameter { #[primary_span] pub(crate) span: Span, diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 5745dc0969c..0d54f332585 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,42 +1,45 @@ +use either::Either; use rustc_apfloat::Float; use rustc_hir as hir; use rustc_index::Idx; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::Obligation; use rustc_middle::mir; -use rustc_middle::span_bug; +use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::thir::{FieldPat, Pat, PatKind}; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt, ValTree}; -use rustc_span::{ErrorGuaranteed, Span}; +use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; -use rustc_trait_selection::traits::{self, ObligationCause}; +use rustc_trait_selection::traits::ObligationCause; use tracing::{debug, instrument, trace}; -use std::cell::Cell; - use super::PatCtxt; use crate::errors::{ - InvalidPattern, NaNPattern, PointerPattern, TypeNotPartialEq, TypeNotStructural, UnionPattern, - UnsizedPattern, + ConstPatternDependsOnGenericParameter, CouldNotEvalConstPattern, InvalidPattern, NaNPattern, + PointerPattern, TypeNotPartialEq, TypeNotStructural, UnionPattern, UnsizedPattern, }; impl<'a, 'tcx> PatCtxt<'a, 'tcx> { - /// Converts an evaluated constant to a pattern (if possible). + /// Converts a constant to a pattern (if possible). /// This means aggregate values (like structs and enums) are converted /// to a pattern that matches the value (as if you'd compared via structural equality). /// - /// `cv` must be a valtree or a `mir::ConstValue`. + /// Only type system constants are supported, as we are using valtrees + /// as an intermediate step. Unfortunately those don't carry a type + /// so we have to carry one ourselves. #[instrument(level = "debug", skip(self), ret)] pub(super) fn const_to_pat( &self, - cv: mir::Const<'tcx>, + c: ty::Const<'tcx>, + ty: Ty<'tcx>, id: hir::HirId, span: Span, ) -> Box<Pat<'tcx>> { let infcx = self.tcx.infer_ctxt().build(); let mut convert = ConstToPat::new(self, id, span, infcx); - convert.to_pat(cv) + convert.to_pat(c, ty) } } @@ -45,23 +48,12 @@ struct ConstToPat<'tcx> { span: Span, param_env: ty::ParamEnv<'tcx>, - // This tracks if we emitted some hard error for a given const value, so that - // we will not subsequently issue an irrelevant lint for the same const - // value. - saw_const_match_error: Cell<Option<ErrorGuaranteed>>, - // inference context used for checking `T: Structural` bounds. infcx: InferCtxt<'tcx>, treat_byte_string_as_slice: bool, } -/// This error type signals that we encountered a non-struct-eq situation. -/// We will fall back to calling `PartialEq::eq` on such patterns, -/// and exhaustiveness checking will consider them as matching nothing. -#[derive(Debug)] -struct FallbackToOpaqueConst; - impl<'tcx> ConstToPat<'tcx> { fn new( pat_ctxt: &PatCtxt<'_, 'tcx>, @@ -75,7 +67,6 @@ impl<'tcx> ConstToPat<'tcx> { span, infcx, param_env: pat_ctxt.param_env, - saw_const_match_error: Cell::new(None), treat_byte_string_as_slice: pat_ctxt .typeck_results .treat_byte_string_as_slice @@ -91,116 +82,55 @@ impl<'tcx> ConstToPat<'tcx> { ty.is_structural_eq_shallow(self.infcx.tcx) } - fn to_pat(&mut self, cv: mir::Const<'tcx>) -> Box<Pat<'tcx>> { + fn to_pat(&mut self, c: ty::Const<'tcx>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> { trace!(self.treat_byte_string_as_slice); - // This method is just a wrapper handling a validity check; the heavy lifting is - // performed by the recursive `recur` method, which is not meant to be - // invoked except by this method. - // - // once indirect_structural_match is a full fledged error, this - // level of indirection can be eliminated + let pat_from_kind = |kind| Box::new(Pat { span: self.span, ty, kind }); - let have_valtree = - matches!(cv, mir::Const::Ty(_, c) if matches!(c.kind(), ty::ConstKind::Value(_, _))); - let inlined_const_as_pat = match cv { - mir::Const::Ty(_, c) => match c.kind() { - ty::ConstKind::Param(_) - | ty::ConstKind::Infer(_) - | ty::ConstKind::Bound(_, _) - | ty::ConstKind::Placeholder(_) - | ty::ConstKind::Unevaluated(_) - | ty::ConstKind::Error(_) - | ty::ConstKind::Expr(_) => { - span_bug!(self.span, "unexpected const in `to_pat`: {:?}", c.kind()) - } - ty::ConstKind::Value(ty, valtree) => { - self.recur(valtree, ty).unwrap_or_else(|_: FallbackToOpaqueConst| { - Box::new(Pat { - span: self.span, - ty: cv.ty(), - kind: PatKind::Constant { value: cv }, - }) - }) - } - }, - mir::Const::Unevaluated(_, _) => { - span_bug!(self.span, "unevaluated const in `to_pat`: {cv:?}") + // Get a valtree. If that fails, this const is definitely not valid for use as a pattern. + let valtree = match c.eval_valtree(self.tcx(), self.param_env, self.span) { + Ok((_, valtree)) => valtree, + Err(Either::Right(e)) => { + let err = match e { + ErrorHandled::Reported(..) => { + // Let's tell the use where this failing const occurs. + self.tcx().dcx().emit_err(CouldNotEvalConstPattern { span: self.span }) + } + ErrorHandled::TooGeneric(_) => self + .tcx() + .dcx() + .emit_err(ConstPatternDependsOnGenericParameter { span: self.span }), + }; + return pat_from_kind(PatKind::Error(err)); + } + Err(Either::Left(bad_ty)) => { + // The pattern cannot be turned into a valtree. + let e = match bad_ty.kind() { + ty::Adt(def, ..) => { + assert!(def.is_union()); + self.tcx().dcx().emit_err(UnionPattern { span: self.span }) + } + ty::FnPtr(..) | ty::RawPtr(..) => { + self.tcx().dcx().emit_err(PointerPattern { span: self.span }) + } + _ => self + .tcx() + .dcx() + .emit_err(InvalidPattern { span: self.span, non_sm_ty: bad_ty }), + }; + return pat_from_kind(PatKind::Error(e)); } - mir::Const::Val(_, _) => Box::new(Pat { - span: self.span, - ty: cv.ty(), - kind: PatKind::Constant { value: cv }, - }), }; - if self.saw_const_match_error.get().is_none() { - // If we were able to successfully convert the const to some pat (possibly with some - // lints, but no errors), double-check that all types in the const implement - // `PartialEq`. Even if we have a valtree, we may have found something - // in there with non-structural-equality, meaning we match using `PartialEq` - // and we hence have to check if that impl exists. - // This is all messy but not worth cleaning up: at some point we'll emit - // a hard error when we don't have a valtree or when we find something in - // the valtree that is not structural; then this can all be made a lot simpler. - - let structural = traits::search_for_structural_match_violation(self.tcx(), cv.ty()); - debug!( - "search_for_structural_match_violation cv.ty: {:?} returned: {:?}", - cv.ty(), - structural - ); - - if let Some(non_sm_ty) = structural { - if !self.type_has_partial_eq_impl(cv.ty()) { - // This is reachable and important even if we have a valtree: there might be - // non-structural things in a valtree, in which case we fall back to `PartialEq` - // comparison, in which case we better make sure the trait is implemented for - // each inner type (and not just for the surrounding type). - let e = if let ty::Adt(def, ..) = non_sm_ty.kind() { - if def.is_union() { - let err = UnionPattern { span: self.span }; - self.tcx().dcx().emit_err(err) - } else { - // fatal avoids ICE from resolution of nonexistent method (rare case). - self.tcx() - .dcx() - .emit_fatal(TypeNotStructural { span: self.span, non_sm_ty }) - } - } else { - let err = InvalidPattern { span: self.span, non_sm_ty }; - self.tcx().dcx().emit_err(err) - }; - // All branches above emitted an error. Don't print any more lints. - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - let kind = PatKind::Error(e); - return Box::new(Pat { span: self.span, ty: cv.ty(), kind }); - } else if !have_valtree { - // Not being structural prevented us from constructing a valtree, - // so this is definitely a case we want to reject. - let err = TypeNotStructural { span: self.span, non_sm_ty }; - let e = self.tcx().dcx().emit_err(err); - let kind = PatKind::Error(e); - return Box::new(Pat { span: self.span, ty: cv.ty(), kind }); - } else { - // This could be a violation in an inactive enum variant. - // Since we have a valtree, we trust that we have traversed the full valtree and - // complained about structural match violations there, so we don't - // have to check anything any more. - } - } else if !have_valtree { - // The only way valtree construction can fail without the structural match - // checker finding a violation is if there is a pointer somewhere. - let e = self.tcx().dcx().emit_err(PointerPattern { span: self.span }); - let kind = PatKind::Error(e); - return Box::new(Pat { span: self.span, ty: cv.ty(), kind }); - } + // Convert the valtree to a const. + let inlined_const_as_pat = self.valtree_to_pat(valtree, ty); + if !inlined_const_as_pat.references_error() { // Always check for `PartialEq` if we had no other errors yet. - if !self.type_has_partial_eq_impl(cv.ty()) { - let err = TypeNotPartialEq { span: self.span, non_peq_ty: cv.ty() }; + if !self.type_has_partial_eq_impl(ty) { + let err = TypeNotPartialEq { span: self.span, non_peq_ty: ty }; let e = self.tcx().dcx().emit_err(err); let kind = PatKind::Error(e); - return Box::new(Pat { span: self.span, ty: cv.ty(), kind }); + return Box::new(Pat { span: self.span, ty: ty, kind }); } } @@ -243,40 +173,31 @@ impl<'tcx> ConstToPat<'tcx> { fn field_pats( &self, vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>, - ) -> Result<Vec<FieldPat<'tcx>>, FallbackToOpaqueConst> { + ) -> Vec<FieldPat<'tcx>> { vals.enumerate() .map(|(idx, (val, ty))| { let field = FieldIdx::new(idx); // Patterns can only use monomorphic types. let ty = self.tcx().normalize_erasing_regions(self.param_env, ty); - Ok(FieldPat { field, pattern: self.recur(val, ty)? }) + FieldPat { field, pattern: self.valtree_to_pat(val, ty) } }) .collect() } // Recursive helper for `to_pat`; invoke that (instead of calling this directly). #[instrument(skip(self), level = "debug")] - fn recur( - &self, - cv: ValTree<'tcx>, - ty: Ty<'tcx>, - ) -> Result<Box<Pat<'tcx>>, FallbackToOpaqueConst> { + fn valtree_to_pat(&self, cv: ValTree<'tcx>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> { let span = self.span; let tcx = self.tcx(); let param_env = self.param_env; let kind = match ty.kind() { - ty::FnDef(..) => { - let e = tcx.dcx().emit_err(InvalidPattern { span, non_sm_ty: ty }); - self.saw_const_match_error.set(Some(e)); - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) - } ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => { + // Extremely important check for all ADTs! Make sure they opted-in to be used in + // patterns. debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,); let err = TypeNotStructural { span, non_sm_ty: ty }; let e = tcx.dcx().emit_err(err); - self.saw_const_match_error.set(Some(e)); // We errored. Signal that in the pattern, so that follow up errors can be silenced. PatKind::Error(e) } @@ -294,13 +215,9 @@ impl<'tcx> ConstToPat<'tcx> { .iter() .map(|field| field.ty(self.tcx(), args)), ), - )?, + ), } } - ty::Tuple(fields) => PatKind::Leaf { - subpatterns: self - .field_pats(cv.unwrap_branch().iter().copied().zip(fields.iter()))?, - }, ty::Adt(def, args) => { assert!(!def.is_union()); // Valtree construction would never succeed for unions. PatKind::Leaf { @@ -311,15 +228,18 @@ impl<'tcx> ConstToPat<'tcx> { .iter() .map(|field| field.ty(self.tcx(), args)), ), - )?, + ), } } + ty::Tuple(fields) => PatKind::Leaf { + subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(fields.iter())), + }, ty::Slice(elem_ty) => PatKind::Slice { prefix: cv .unwrap_branch() .iter() - .map(|val| self.recur(*val, *elem_ty)) - .collect::<Result<_, _>>()?, + .map(|val| self.valtree_to_pat(*val, *elem_ty)) + .collect(), slice: None, suffix: Box::new([]), }, @@ -327,8 +247,8 @@ impl<'tcx> ConstToPat<'tcx> { prefix: cv .unwrap_branch() .iter() - .map(|val| self.recur(*val, *elem_ty)) - .collect::<Result<_, _>>()?, + .map(|val| self.valtree_to_pat(*val, *elem_ty)) + .collect(), slice: None, suffix: Box::new([]), }, @@ -361,7 +281,7 @@ impl<'tcx> ConstToPat<'tcx> { _ => *pointee_ty, }; // References have the same valtree representation as their pointee. - let subpattern = self.recur(cv, pointee_ty)?; + let subpattern = self.valtree_to_pat(cv, pointee_ty); PatKind::Deref { subpattern } } } @@ -378,8 +298,7 @@ impl<'tcx> ConstToPat<'tcx> { // NaNs are not ever equal to anything so they make no sense as patterns. // Also see <https://github.com/rust-lang/rfcs/pull/3535>. let e = tcx.dcx().emit_err(NaNPattern { span }); - self.saw_const_match_error.set(Some(e)); - return Err(FallbackToOpaqueConst); + PatKind::Error(e) } else { PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), @@ -399,12 +318,11 @@ impl<'tcx> ConstToPat<'tcx> { _ => { let err = InvalidPattern { span, non_sm_ty: ty }; let e = tcx.dcx().emit_err(err); - self.saw_const_match_error.set(Some(e)); // We errored. Signal that in the pattern, so that follow up errors can be silenced. PatKind::Error(e) } }; - Ok(Box::new(Pat { span, ty, kind })) + Box::new(Pat { span, ty, kind }) } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index fd778ef78a3..622651800f4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -14,8 +14,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::{self as hir, ByRef, Mutability, RangeEnd}; use rustc_index::Idx; use rustc_lint as lint; -use rustc_middle::mir::interpret::{ErrorHandled, GlobalId, LitToConstError, LitToConstInput}; -use rustc_middle::mir::{self, Const}; +use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::thir::{ Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary, }; @@ -549,89 +548,36 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { _ => return pat_from_kind(self.lower_variant_or_leaf(res, id, span, ty, vec![])), }; - // Use `Reveal::All` here because patterns are always monomorphic even if their function - // isn't. - let param_env_reveal_all = self.param_env.with_reveal_all_normalized(self.tcx); - // N.B. There is no guarantee that args collected in typeck results are fully normalized, - // so they need to be normalized in order to pass to `Instance::resolve`, which will ICE - // if given unnormalized types. - let args = self - .tcx - .normalize_erasing_regions(param_env_reveal_all, self.typeck_results.node_args(id)); - let instance = match ty::Instance::try_resolve(self.tcx, param_env_reveal_all, def_id, args) - { - Ok(Some(i)) => i, - Ok(None) => { - // It should be assoc consts if there's no error but we cannot resolve it. - debug_assert!(is_associated_const); - - let e = self.tcx.dcx().emit_err(AssocConstInPattern { span }); - return pat_from_kind(PatKind::Error(e)); - } - - Err(_) => { - let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span }); - return pat_from_kind(PatKind::Error(e)); - } - }; + let args = self.typeck_results.node_args(id); + let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args }); + let pattern = self.const_to_pat(c, ty, id, span); - let cid = GlobalId { instance, promoted: None }; - // Prefer valtrees over opaque constants. - let const_value = self - .tcx - .const_eval_global_id_for_typeck(param_env_reveal_all, cid, span) - .map(|val| match val { - Some(valtree) => mir::Const::Ty(ty, ty::Const::new_value(self.tcx, valtree, ty)), - None => mir::Const::Val( - self.tcx - .const_eval_global_id(param_env_reveal_all, cid, span) - .expect("const_eval_global_id_for_typeck should have already failed"), - ty, - ), - }); - - match const_value { - Ok(const_) => { - let pattern = self.const_to_pat(const_, id, span); - - if !is_associated_const { - return pattern; - } + if !is_associated_const { + return pattern; + } - let user_provided_types = self.typeck_results().user_provided_types(); - if let Some(&user_ty) = user_provided_types.get(id) { - let annotation = CanonicalUserTypeAnnotation { - user_ty: Box::new(user_ty), - span, - inferred_ty: self.typeck_results().node_type(id), - }; - Box::new(Pat { - span, - kind: PatKind::AscribeUserType { - subpattern: pattern, - ascription: Ascription { - annotation, - // Note that use `Contravariant` here. See the - // `variance` field documentation for details. - variance: ty::Contravariant, - }, - }, - ty: const_.ty(), - }) - } else { - pattern - } - } - Err(ErrorHandled::TooGeneric(_)) => { - // While `Reported | Linted` cases will have diagnostics emitted already - // it is not true for TooGeneric case, so we need to give user more information. - let e = self.tcx.dcx().emit_err(ConstPatternDependsOnGenericParameter { span }); - pat_from_kind(PatKind::Error(e)) - } - Err(_) => { - let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span }); - pat_from_kind(PatKind::Error(e)) - } + let user_provided_types = self.typeck_results().user_provided_types(); + if let Some(&user_ty) = user_provided_types.get(id) { + let annotation = CanonicalUserTypeAnnotation { + user_ty: Box::new(user_ty), + span, + inferred_ty: self.typeck_results().node_type(id), + }; + Box::new(Pat { + span, + kind: PatKind::AscribeUserType { + subpattern: pattern, + ascription: Ascription { + annotation, + // Note that use `Contravariant` here. See the + // `variance` field documentation for details. + variance: ty::Contravariant, + }, + }, + ty, + }) + } else { + pattern } } @@ -662,7 +608,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { }; if let Some(lit_input) = lit_input { match tcx.at(expr.span).lit_to_const(lit_input) { - Ok(c) => return self.const_to_pat(Const::Ty(ty, c), id, span).kind, + Ok(c) => return self.const_to_pat(c, ty, id, span).kind, // If an error occurred, ignore that it's a literal // and leave reporting the error up to const eval of // the unevaluated constant below. @@ -675,33 +621,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { tcx.erase_regions(ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id)); let args = ty::InlineConstArgs::new(tcx, ty::InlineConstArgsParts { parent_args, ty }).args; - let uneval = mir::UnevaluatedConst { def: def_id.to_def_id(), args, promoted: None }; debug_assert!(!args.has_free_regions()); let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args }; - // First try using a valtree in order to destructure the constant into a pattern. - // FIXME: replace "try to do a thing, then fall back to another thing" - // but something more principled, like a trait query checking whether this can be turned into a valtree. - if let Ok(Some(valtree)) = self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, span) - { - let subpattern = self.const_to_pat( - Const::Ty(ty, ty::Const::new_value(self.tcx, valtree, ty)), - id, - span, - ); - PatKind::InlineConstant { subpattern, def: def_id } - } else { - // If that fails, convert it to an opaque constant pattern. - match tcx.const_eval_resolve(self.param_env, uneval, span) { - Ok(val) => self.const_to_pat(mir::Const::Val(val, ty), id, span).kind, - Err(ErrorHandled::TooGeneric(_)) => { - // If we land here it means the const can't be evaluated because it's `TooGeneric`. - let e = self.tcx.dcx().emit_err(ConstPatternDependsOnGenericParameter { span }); - PatKind::Error(e) - } - Err(ErrorHandled::Reported(err, ..)) => PatKind::Error(err.into()), - } - } + let subpattern = self.const_to_pat(ty::Const::new_unevaluated(self.tcx, ct), ty, id, span); + PatKind::InlineConstant { subpattern, def: def_id } } /// Converts literals, paths and negation of literals to patterns. @@ -729,9 +653,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let ct_ty = self.typeck_results.expr_ty(expr); let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg }; match self.tcx.at(expr.span).lit_to_const(lit_input) { - Ok(constant) => { - self.const_to_pat(Const::Ty(ct_ty, constant), expr.hir_id, lit.span).kind - } + Ok(constant) => self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind, Err(LitToConstError::Reported(e)) => PatKind::Error(e), Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"), } diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index 07cd4ae68d9..79d2107b2a0 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -20,10 +20,10 @@ tracing = "0.1" [features] default = ["nightly"] nightly = [ + "dep:rustc_data_structures", + "dep:rustc_macros", + "dep:rustc_serialize", "rustc_ast_ir/nightly", - "rustc_data_structures", "rustc_index/nightly", - "rustc_macros", - "rustc_serialize", "rustc_type_ir/nightly", ] diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 0da7fefe6ed..2fe3ab56146 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2240,11 +2240,11 @@ impl<'a> Parser<'a> { } _ => { // Otherwise, try to get a type and emit a suggestion. - if let Some(ty) = pat.to_ty() { + if let Some(_) = pat.to_ty() { err.span_suggestion_verbose( - pat.span, + pat.span.shrink_to_lo(), "explicitly ignore the parameter name", - format!("_: {}", pprust::ty_to_string(&ty)), + "_: ".to_string(), Applicability::MachineApplicable, ); err.note(rfc_note); @@ -2256,7 +2256,7 @@ impl<'a> Parser<'a> { // `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}` if first_param { - err.span_suggestion( + err.span_suggestion_verbose( self_span, "if this is a `self` type, give it a parameter name", self_sugg, @@ -2266,14 +2266,14 @@ impl<'a> Parser<'a> { // Avoid suggesting that `fn foo(HashMap<u32>)` is fixed with a change to // `fn foo(HashMap: TypeName<u32>)`. if self.token != token::Lt { - err.span_suggestion( + err.span_suggestion_verbose( param_span, "if this is a parameter name, give it a type", param_sugg, Applicability::HasPlaceholders, ); } - err.span_suggestion( + err.span_suggestion_verbose( type_span, "if this is a type, explicitly ignore the parameter name", type_sugg, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0ba8c66f48f..0e7497cea41 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -785,23 +785,14 @@ impl<'a> Parser<'a> { } }; - self.parse_and_disallow_postfix_after_cast(cast_expr) - } - - /// Parses a postfix operators such as `.`, `?`, or index (`[]`) after a cast, - /// then emits an error and returns the newly parsed tree. - /// The resulting parse tree for `&x as T[0]` has a precedence of `((&x) as T)[0]`. - fn parse_and_disallow_postfix_after_cast( - &mut self, - cast_expr: P<Expr>, - ) -> PResult<'a, P<Expr>> { - if let ExprKind::Type(_, _) = cast_expr.kind { - panic!("ExprKind::Type must not be parsed"); - } + // Try to parse a postfix operator such as `.`, `?`, or index (`[]`) + // after a cast. If one is present, emit an error then return a valid + // parse tree; For something like `&x as T[0]` will be as if it was + // written `((&x) as T)[0]`. let span = cast_expr.span; - let with_postfix = self.parse_expr_dot_or_call_with_(cast_expr, span)?; + let with_postfix = self.parse_expr_dot_or_call_with(AttrVec::new(), cast_expr, span)?; // Check if an illegal postfix operator has been added after the cast. // If the resulting expression is not a cast, it is an illegal postfix operator. @@ -885,23 +876,63 @@ impl<'a> Parser<'a> { self.collect_tokens_for_expr(attrs, |this, attrs| { let base = this.parse_expr_bottom()?; let span = this.interpolated_or_expr_span(&base); - this.parse_expr_dot_or_call_with(base, span, attrs) + this.parse_expr_dot_or_call_with(attrs, base, span) }) } pub(super) fn parse_expr_dot_or_call_with( &mut self, - e0: P<Expr>, - lo: Span, mut attrs: ast::AttrVec, + mut e: P<Expr>, + lo: Span, ) -> PResult<'a, P<Expr>> { - // Stitch the list of outer attributes onto the return value. - // A little bit ugly, but the best way given the current code - // structure - let res = ensure_sufficient_stack( - // this expr demonstrates the recursion it guards against - || self.parse_expr_dot_or_call_with_(e0, lo), - ); + let res = ensure_sufficient_stack(|| { + loop { + let has_question = + if self.prev_token.kind == TokenKind::Ident(kw::Return, IdentIsRaw::No) { + // We are using noexpect here because we don't expect a `?` directly after + // a `return` which could be suggested otherwise. + self.eat_noexpect(&token::Question) + } else { + self.eat(&token::Question) + }; + if has_question { + // `expr?` + e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e)); + continue; + } + let has_dot = + if self.prev_token.kind == TokenKind::Ident(kw::Return, IdentIsRaw::No) { + // We are using noexpect here because we don't expect a `.` directly after + // a `return` which could be suggested otherwise. + self.eat_noexpect(&token::Dot) + } else if self.token.kind == TokenKind::RArrow && self.may_recover() { + // Recovery for `expr->suffix`. + self.bump(); + let span = self.prev_token.span; + self.dcx().emit_err(errors::ExprRArrowCall { span }); + true + } else { + self.eat(&token::Dot) + }; + if has_dot { + // expr.f + e = self.parse_dot_suffix_expr(lo, e)?; + continue; + } + if self.expr_is_complete(&e) { + return Ok(e); + } + e = match self.token.kind { + token::OpenDelim(Delimiter::Parenthesis) => self.parse_expr_fn_call(lo, e), + token::OpenDelim(Delimiter::Bracket) => self.parse_expr_index(lo, e)?, + _ => return Ok(e), + } + } + }); + + // Stitch the list of outer attributes onto the return value. A little + // bit ugly, but the best way given the current code structure. if attrs.is_empty() { res } else { @@ -915,50 +946,6 @@ impl<'a> Parser<'a> { } } - fn parse_expr_dot_or_call_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> { - loop { - let has_question = - if self.prev_token.kind == TokenKind::Ident(kw::Return, IdentIsRaw::No) { - // we are using noexpect here because we don't expect a `?` directly after a `return` - // which could be suggested otherwise - self.eat_noexpect(&token::Question) - } else { - self.eat(&token::Question) - }; - if has_question { - // `expr?` - e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e)); - continue; - } - let has_dot = if self.prev_token.kind == TokenKind::Ident(kw::Return, IdentIsRaw::No) { - // we are using noexpect here because we don't expect a `.` directly after a `return` - // which could be suggested otherwise - self.eat_noexpect(&token::Dot) - } else if self.token.kind == TokenKind::RArrow && self.may_recover() { - // Recovery for `expr->suffix`. - self.bump(); - let span = self.prev_token.span; - self.dcx().emit_err(errors::ExprRArrowCall { span }); - true - } else { - self.eat(&token::Dot) - }; - if has_dot { - // expr.f - e = self.parse_dot_suffix_expr(lo, e)?; - continue; - } - if self.expr_is_complete(&e) { - return Ok(e); - } - e = match self.token.kind { - token::OpenDelim(Delimiter::Parenthesis) => self.parse_expr_fn_call(lo, e), - token::OpenDelim(Delimiter::Bracket) => self.parse_expr_index(lo, e)?, - _ => return Ok(e), - } - } - } - pub(super) fn parse_dot_suffix_expr( &mut self, lo: Span, @@ -1388,7 +1375,7 @@ impl<'a> Parser<'a> { /// Parses things like parenthesized exprs, macros, `return`, etc. /// /// N.B., this does not parse outer attributes, and is private because it only works - /// correctly if called from `parse_dot_or_call_expr()`. + /// correctly if called from `parse_expr_dot_or_call`. fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> { maybe_recover_from_interpolated_ty_qpath!(self, true); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 76857cb8504..b964e8aa665 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -128,56 +128,41 @@ impl<'a> Parser<'a> { Some(item.into_inner()) }); - let item = - self.collect_tokens_trailing_token(attrs, force_collect, |this: &mut Self, attrs| { - let item = - this.parse_item_common_(attrs, mac_allowed, attrs_allowed, fn_parse_mode); - Ok((item?, TrailingToken::None)) - })?; - - Ok(item) - } - - fn parse_item_common_( - &mut self, - mut attrs: AttrVec, - mac_allowed: bool, - attrs_allowed: bool, - fn_parse_mode: FnParseMode, - ) -> PResult<'a, Option<Item>> { - let lo = self.token.span; - let vis = self.parse_visibility(FollowedByType::No)?; - let mut def = self.parse_defaultness(); - let kind = self.parse_item_kind( - &mut attrs, - mac_allowed, - lo, - &vis, - &mut def, - fn_parse_mode, - Case::Sensitive, - )?; - if let Some((ident, kind)) = kind { - self.error_on_unconsumed_default(def, &kind); - let span = lo.to(self.prev_token.span); - let id = DUMMY_NODE_ID; - let item = Item { ident, attrs, id, kind, vis, span, tokens: None }; - return Ok(Some(item)); - } + self.collect_tokens_trailing_token(attrs, force_collect, |this, mut attrs| { + let lo = this.token.span; + let vis = this.parse_visibility(FollowedByType::No)?; + let mut def = this.parse_defaultness(); + let kind = this.parse_item_kind( + &mut attrs, + mac_allowed, + lo, + &vis, + &mut def, + fn_parse_mode, + Case::Sensitive, + )?; + if let Some((ident, kind)) = kind { + this.error_on_unconsumed_default(def, &kind); + let span = lo.to(this.prev_token.span); + let id = DUMMY_NODE_ID; + let item = Item { ident, attrs, id, kind, vis, span, tokens: None }; + return Ok((Some(item), TrailingToken::None)); + } - // At this point, we have failed to parse an item. - if !matches!(vis.kind, VisibilityKind::Inherited) { - self.dcx().emit_err(errors::VisibilityNotFollowedByItem { span: vis.span, vis }); - } + // At this point, we have failed to parse an item. + if !matches!(vis.kind, VisibilityKind::Inherited) { + this.dcx().emit_err(errors::VisibilityNotFollowedByItem { span: vis.span, vis }); + } - if let Defaultness::Default(span) = def { - self.dcx().emit_err(errors::DefaultNotFollowedByItem { span }); - } + if let Defaultness::Default(span) = def { + this.dcx().emit_err(errors::DefaultNotFollowedByItem { span }); + } - if !attrs_allowed { - self.recover_attrs_no_item(&attrs)?; - } - Ok(None) + if !attrs_allowed { + this.recover_attrs_no_item(&attrs)?; + } + Ok((None, TrailingToken::None)) + }) } /// Error in-case `default` was parsed in an in-appropriate context. diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 958458eda9a..0117f993bcb 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -101,7 +101,6 @@ pub enum TrailingToken { MaybeComma, } -/// Like `maybe_whole_expr`, but for things other than expressions. #[macro_export] macro_rules! maybe_whole { ($p:expr, $constructor:ident, |$x:ident| $e:expr) => { diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 8e8df9f0a84..245b730bbe4 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -392,9 +392,9 @@ impl<'a> Parser<'a> { // Parse `?`, `.f`, `(arg0, arg1, ...)` or `[expr]` until they've all been eaten. if let Ok(expr) = snapshot .parse_expr_dot_or_call_with( + AttrVec::new(), self.mk_expr(pat_span, ExprKind::Dummy), // equivalent to transforming the parsed pattern into an `Expr` pat_span, - AttrVec::new(), ) .map_err(|err| err.cancel()) { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 70d41de00a7..e7fcbf9c20f 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -164,7 +164,7 @@ impl<'a> Parser<'a> { }; let expr = this.with_res(Restrictions::STMT_EXPR, |this| { - this.parse_expr_dot_or_call_with(expr, lo, attrs) + this.parse_expr_dot_or_call_with(attrs, expr, lo) })?; // `DUMMY_SP` will get overwritten later in this function Ok((this.mk_stmt(rustc_span::DUMMY_SP, StmtKind::Expr(expr)), TrailingToken::None)) @@ -206,7 +206,7 @@ impl<'a> Parser<'a> { // Since none of the above applied, this is an expression statement macro. let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac)); let e = self.maybe_recover_from_bad_qpath(e)?; - let e = self.parse_expr_dot_or_call_with(e, lo, attrs)?; + let e = self.parse_expr_dot_or_call_with(attrs, e, lo)?; let e = self .parse_expr_assoc_with(0, LhsExpr::Parsed { expr: e, starts_statement: false })?; StmtKind::Expr(e) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index d4dd4dd858c..d17ee8bff50 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -462,7 +462,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { // This is a box pattern. ty::Adt(adt, ..) if adt.is_box() => Struct, ty::Ref(..) => Ref, - _ => bug!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, ty), + _ => span_bug!( + pat.span, + "pattern has unexpected type: pat: {:?}, ty: {:?}", + pat.kind, + ty.inner() + ), }; } PatKind::DerefPattern { .. } => { @@ -518,7 +523,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { .map(|ipat| self.lower_pat(&ipat.pattern).at_index(ipat.field.index())) .collect(); } - _ => bug!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, ty), + _ => span_bug!( + pat.span, + "pattern has unexpected type: pat: {:?}, ty: {}", + pat.kind, + ty.inner() + ), } } PatKind::Constant { value } => { @@ -663,7 +673,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } } } - _ => bug!("invalid type for range pattern: {}", ty.inner()), + _ => span_bug!(pat.span, "invalid type for range pattern: {}", ty.inner()), }; fields = vec![]; arity = 0; @@ -674,7 +684,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { Some(length.eval_target_usize(cx.tcx, cx.param_env) as usize) } ty::Slice(_) => None, - _ => span_bug!(pat.span, "bad ty {:?} for slice pattern", ty), + _ => span_bug!(pat.span, "bad ty {} for slice pattern", ty.inner()), }; let kind = if slice.is_some() { SliceKind::VarLen(prefix.len(), suffix.len()) diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 4d845ab0d07..2f42fa47728 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -26,5 +26,5 @@ tracing = "0.1" [features] # tidy-alphabetical-start -rustc_use_parallel_compiler = ["rustc-rayon-core"] +rustc_use_parallel_compiler = ["dep:rustc-rayon-core"] # tidy-alphabetical-end diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index e3917acce65..566223f98bf 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -371,6 +371,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; let mut suggestion = None; + let mut span = binding_span; match import.kind { ImportKind::Single { type_ns_only: true, .. } => { suggestion = Some(format!("self as {suggested_name}")) @@ -381,12 +382,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(binding_span) { if pos <= snippet.len() { - suggestion = Some(format!( - "{} as {}{}", - &snippet[..pos], - suggested_name, - if snippet.ends_with(';') { ";" } else { "" } - )) + span = binding_span + .with_lo(binding_span.lo() + BytePos(pos as u32)) + .with_hi( + binding_span.hi() + - BytePos(if snippet.ends_with(';') { 1 } else { 0 }), + ); + suggestion = Some(format!(" as {suggested_name}")); } } } @@ -402,9 +404,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } if let Some(suggestion) = suggestion { - err.subdiagnostic(ChangeImportBindingSuggestion { span: binding_span, suggestion }); + err.subdiagnostic(ChangeImportBindingSuggestion { span, suggestion }); } else { - err.subdiagnostic(ChangeImportBinding { span: binding_span }); + err.subdiagnostic(ChangeImportBinding { span }); } } diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index f67518a577e..ade26a40920 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -87,12 +87,12 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< ) -> Option<ty::Const<'tcx>> { use rustc_middle::mir::interpret::ErrorHandled; match self.const_eval_resolve(param_env, unevaluated, DUMMY_SP) { - Ok(Some(val)) => Some(ty::Const::new_value( + Ok(Ok(val)) => Some(ty::Const::new_value( self.tcx, val, self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args), )), - Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None, + Ok(Err(_)) | Err(ErrorHandled::TooGeneric(_)) => None, Err(ErrorHandled::Reported(e, _)) => Some(ty::Const::new_error(self.tcx, e.into())), } } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 1d32ef2ccd9..796f7fd5a54 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -765,8 +765,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { unevaluated, obligation.cause.span, ) { - Ok(Some(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args))), - Ok(None) => { + Ok(Ok(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args))), + Ok(Err(_)) => { let tcx = self.tcx; let reported = tcx.dcx().emit_err(UnableToConstructConstantValue { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index d28982ed849..f7eb1730582 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -16,7 +16,6 @@ pub mod query; #[allow(hidden_glob_reexports)] mod select; mod specialize; -mod structural_match; mod structural_normalize; #[allow(hidden_glob_reexports)] mod util; @@ -60,7 +59,6 @@ pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind; pub use self::specialize::{ specialization_graph, translate_args, translate_args_with_cause, OverlapError, }; -pub use self::structural_match::search_for_structural_match_violation; pub use self::structural_normalize::StructurallyNormalizeExt; pub use self::util::elaborate; pub use self::util::{expand_trait_aliases, TraitAliasExpander, TraitAliasExpansionInfo}; diff --git a/compiler/rustc_trait_selection/src/traits/select/_match.rs b/compiler/rustc_trait_selection/src/traits/select/_match.rs index 50d8e96aaf9..8676f30a53b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/_match.rs +++ b/compiler/rustc_trait_selection/src/traits/select/_match.rs @@ -36,7 +36,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> { "MatchAgainstFreshVars" } - fn tcx(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -77,7 +77,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> { Err(TypeError::Sorts(ExpectedFound::new(true, a, b))) } - (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(self.tcx(), guar)), + (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(self.cx(), guar)), _ => structurally_relate_tys(self, a, b), } diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs deleted file mode 100644 index d4535db951e..00000000000 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ /dev/null @@ -1,173 +0,0 @@ -use rustc_data_structures::fx::FxHashSet; -use rustc_hir as hir; -use rustc_middle::bug; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use std::ops::ControlFlow; - -/// This method traverses the structure of `ty`, trying to find an -/// instance of an ADT (i.e. struct or enum) that doesn't implement -/// the structural-match traits, or a generic type parameter -/// (which cannot be determined to be structural-match). -/// -/// The "structure of a type" includes all components that would be -/// considered when doing a pattern match on a constant of that -/// type. -/// -/// * This means this method descends into fields of structs/enums, -/// and also descends into the inner type `T` of `&T` and `&mut T` -/// -/// * The traversal doesn't dereference unsafe pointers (`*const T`, -/// `*mut T`), and it does not visit the type arguments of an -/// instantiated generic like `PhantomData<T>`. -/// -/// The reason we do this search is Rust currently require all ADTs -/// reachable from a constant's type to implement the -/// structural-match traits, which essentially say that -/// the implementation of `PartialEq::eq` behaves *equivalently* to a -/// comparison against the unfolded structure. -/// -/// For more background on why Rust has this requirement, and issues -/// that arose when the requirement was not enforced completely, see -/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307. -pub fn search_for_structural_match_violation<'tcx>( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, -) -> Option<Ty<'tcx>> { - ty.visit_with(&mut Search { tcx, seen: FxHashSet::default() }).break_value() -} - -/// This implements the traversal over the structure of a given type to try to -/// find instances of ADTs (specifically structs or enums) that do not implement -/// `StructuralPartialEq`. -struct Search<'tcx> { - tcx: TyCtxt<'tcx>, - - /// Tracks ADTs previously encountered during search, so that - /// we will not recur on them again. - seen: FxHashSet<hir::def_id::DefId>, -} - -impl<'tcx> Search<'tcx> { - fn type_marked_structural(&self, adt_ty: Ty<'tcx>) -> bool { - adt_ty.is_structural_eq_shallow(self.tcx) - } -} - -impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> { - type Result = ControlFlow<Ty<'tcx>>; - - fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { - debug!("Search visiting ty: {:?}", ty); - - let (adt_def, args) = match *ty.kind() { - ty::Adt(adt_def, args) => (adt_def, args), - ty::Param(_) => { - return ControlFlow::Break(ty); - } - ty::Dynamic(..) => { - return ControlFlow::Break(ty); - } - ty::Foreign(_) => { - return ControlFlow::Break(ty); - } - ty::Alias(..) => { - return ControlFlow::Break(ty); - } - ty::Closure(..) => { - return ControlFlow::Break(ty); - } - ty::CoroutineClosure(..) => { - return ControlFlow::Break(ty); - } - ty::Coroutine(..) | ty::CoroutineWitness(..) => { - return ControlFlow::Break(ty); - } - ty::FnDef(..) => { - // Types of formals and return in `fn(_) -> _` are also irrelevant; - // so we do not recur into them via `super_visit_with` - return ControlFlow::Continue(()); - } - ty::Array(_, n) - if { n.try_eval_target_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0) } => - { - // rust-lang/rust#62336: ignore type of contents - // for empty array. - return ControlFlow::Continue(()); - } - ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Str | ty::Never => { - // These primitive types are always structural match. - // - // `Never` is kind of special here, but as it is not inhabitable, this should be fine. - return ControlFlow::Continue(()); - } - - ty::FnPtr(..) => { - return ControlFlow::Continue(()); - } - - ty::RawPtr(..) => { - // structural-match ignores substructure of - // `*const _`/`*mut _`, so skip `super_visit_with`. - // - // For example, if you have: - // ``` - // struct NonStructural; - // #[derive(PartialEq, Eq)] - // struct T(*const NonStructural); - // const C: T = T(std::ptr::null()); - // ``` - // - // Even though `NonStructural` does not implement `PartialEq`, - // structural equality on `T` does not recur into the raw - // pointer. Therefore, one can still use `C` in a pattern. - return ControlFlow::Continue(()); - } - - ty::Float(_) => { - return ControlFlow::Continue(()); - } - - ty::Pat(..) | ty::Array(..) | ty::Slice(_) | ty::Ref(..) | ty::Tuple(..) => { - // First check all contained types and then tell the caller to continue searching. - return ty.super_visit_with(self); - } - ty::Infer(_) | ty::Placeholder(_) | ty::Bound(..) => { - bug!("unexpected type during structural-match checking: {:?}", ty); - } - ty::Error(_) => { - // We still want to check other types after encountering an error, - // as this may still emit relevant errors. - return ControlFlow::Continue(()); - } - }; - - if !self.seen.insert(adt_def.did()) { - debug!("Search already seen adt_def: {:?}", adt_def); - return ControlFlow::Continue(()); - } - - if !self.type_marked_structural(ty) { - debug!("Search found ty: {:?}", ty); - return ControlFlow::Break(ty); - } - - // structural-match does not care about the - // instantiation of the generics in an ADT (it - // instead looks directly at its fields outside - // this match), so we skip super_visit_with. - // - // (Must not recur on args for `PhantomData<T>` cf - // rust-lang/rust#55028 and rust-lang/rust#55837; but also - // want to skip args when only uses of generic are - // behind unsafe pointers `*const T`/`*mut T`.) - - // even though we skip super_visit_with, we must recur on - // fields of ADT. - let tcx = self.tcx; - adt_def.all_fields().map(|field| field.ty(tcx, args)).try_for_each(|field_ty| { - let ty = self.tcx.normalize_erasing_regions(ty::ParamEnv::empty(), field_ty); - debug!("structural-match ADT: field_ty={:?}, ty={:?}", field_ty, ty); - ty.visit_with(self) - }) - } -} diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index 79939d62a51..4732e968f6b 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -18,13 +18,13 @@ tracing = "0.1" [features] rustc = [ - "rustc_hir", - "rustc_infer", - "rustc_macros", - "rustc_middle", - "rustc_span", - "rustc_target", - "rustc_ast_ir", + "dep:rustc_hir", + "dep:rustc_infer", + "dep:rustc_macros", + "dep:rustc_middle", + "dep:rustc_span", + "dep:rustc_target", + "dep:rustc_ast_ir", ] [dev-dependencies] diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index e4bf6069caf..769e350b835 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -22,12 +22,12 @@ tracing = "0.1" [features] default = ["nightly"] nightly = [ + "dep:rustc_serialize", + "dep:rustc_span", + "dep:rustc_data_structures", + "dep:rustc_macros", "smallvec/may_dangle", "smallvec/union", "rustc_index/nightly", - "rustc_serialize", - "rustc_span", - "rustc_data_structures", - "rustc_macros", "rustc_ast_ir/nightly" ] diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 2531219baec..17b35a2807a 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -49,10 +49,10 @@ where { type Lifted = Binder<U, T::Lifted>; - fn lift_to_tcx(self, tcx: U) -> Option<Self::Lifted> { + fn lift_to_interner(self, cx: U) -> Option<Self::Lifted> { Some(Binder { - value: self.value.lift_to_tcx(tcx)?, - bound_vars: self.bound_vars.lift_to_tcx(tcx)?, + value: self.value.lift_to_interner(cx)?, + bound_vars: self.bound_vars.lift_to_interner(cx)?, }) } } @@ -439,11 +439,11 @@ impl<I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter> where Iter::Item: TypeFoldable<I>, { - pub fn iter_instantiated<A>(self, tcx: I, args: A) -> IterInstantiated<I, Iter, A> + pub fn iter_instantiated<A>(self, cx: I, args: A) -> IterInstantiated<I, Iter, A> where A: SliceLike<Item = I::GenericArg>, { - IterInstantiated { it: self.value.into_iter(), tcx, args } + IterInstantiated { it: self.value.into_iter(), cx, args } } /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity), @@ -455,7 +455,7 @@ where pub struct IterInstantiated<I: Interner, Iter: IntoIterator, A> { it: Iter::IntoIter, - tcx: I, + cx: I, args: A, } @@ -469,7 +469,7 @@ where fn next(&mut self) -> Option<Self::Item> { Some( EarlyBinder { value: self.it.next()?, _tcx: PhantomData } - .instantiate(self.tcx, self.args), + .instantiate(self.cx, self.args), ) } @@ -487,7 +487,7 @@ where fn next_back(&mut self) -> Option<Self::Item> { Some( EarlyBinder { value: self.it.next_back()?, _tcx: PhantomData } - .instantiate(self.tcx, self.args), + .instantiate(self.cx, self.args), ) } } @@ -507,10 +507,10 @@ where { pub fn iter_instantiated_copied( self, - tcx: I, + cx: I, args: &'s [I::GenericArg], ) -> IterInstantiatedCopied<'s, I, Iter> { - IterInstantiatedCopied { it: self.value.into_iter(), tcx, args } + IterInstantiatedCopied { it: self.value.into_iter(), cx, args } } /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity), @@ -522,7 +522,7 @@ where pub struct IterInstantiatedCopied<'a, I: Interner, Iter: IntoIterator> { it: Iter::IntoIter, - tcx: I, + cx: I, args: &'a [I::GenericArg], } @@ -535,7 +535,7 @@ where fn next(&mut self) -> Option<Self::Item> { self.it.next().map(|value| { - EarlyBinder { value: *value, _tcx: PhantomData }.instantiate(self.tcx, self.args) + EarlyBinder { value: *value, _tcx: PhantomData }.instantiate(self.cx, self.args) }) } @@ -552,7 +552,7 @@ where { fn next_back(&mut self) -> Option<Self::Item> { self.it.next_back().map(|value| { - EarlyBinder { value: *value, _tcx: PhantomData }.instantiate(self.tcx, self.args) + EarlyBinder { value: *value, _tcx: PhantomData }.instantiate(self.cx, self.args) }) } } @@ -589,11 +589,11 @@ impl<I: Interner, T: Iterator> Iterator for EarlyBinderIter<I, T> { } impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> { - pub fn instantiate<A>(self, tcx: I, args: A) -> T + pub fn instantiate<A>(self, cx: I, args: A) -> T where A: SliceLike<Item = I::GenericArg>, { - let mut folder = ArgFolder { tcx, args: args.as_slice(), binders_passed: 0 }; + let mut folder = ArgFolder { cx, args: args.as_slice(), binders_passed: 0 }; self.value.fold_with(&mut folder) } @@ -619,7 +619,7 @@ impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> { // The actual instantiation engine itself is a type folder. struct ArgFolder<'a, I: Interner> { - tcx: I, + cx: I, args: &'a [I::GenericArg], /// Number of region binders we have passed through while doing the instantiation @@ -629,7 +629,7 @@ struct ArgFolder<'a, I: Interner> { impl<'a, I: Interner> TypeFolder<I> for ArgFolder<'a, I> { #[inline] fn cx(&self) -> I { - self.tcx + self.cx } fn fold_binder<T: TypeFoldable<I>>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> { @@ -858,6 +858,6 @@ impl<'a, I: Interner> ArgFolder<'a, I> { if self.binders_passed == 0 || !region.has_escaping_bound_vars() { return region; } - ty::fold::shift_region(self.tcx, region, self.binders_passed) + ty::fold::shift_region(self.cx, region, self.binders_passed) } } diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 7b114f565f2..a9252711b2b 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -330,25 +330,25 @@ impl<I: Interner> CanonicalVarValues<I> { // Given a list of canonical variables, construct a set of values which are // the identity response. - pub fn make_identity(tcx: I, infos: I::CanonicalVars) -> CanonicalVarValues<I> { + pub fn make_identity(cx: I, infos: I::CanonicalVars) -> CanonicalVarValues<I> { CanonicalVarValues { - var_values: tcx.mk_args_from_iter(infos.iter().enumerate().map( + var_values: cx.mk_args_from_iter(infos.iter().enumerate().map( |(i, info)| -> I::GenericArg { match info.kind { CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => { - Ty::new_anon_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i)) + Ty::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i)) .into() } CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => { - Region::new_anon_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i)) + Region::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i)) .into() } CanonicalVarKind::Effect => { - Const::new_anon_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i)) + Const::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i)) .into() } CanonicalVarKind::Const(_) | CanonicalVarKind::PlaceholderConst(_) => { - Const::new_anon_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i)) + Const::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i)) .into() } } diff --git a/compiler/rustc_type_ir/src/effects.rs b/compiler/rustc_type_ir/src/effects.rs index f7942f2f982..d1c3c8e5223 100644 --- a/compiler/rustc_type_ir/src/effects.rs +++ b/compiler/rustc_type_ir/src/effects.rs @@ -10,38 +10,38 @@ pub enum EffectKind { } impl EffectKind { - pub fn try_from_def_id<I: Interner>(tcx: I, def_id: I::DefId) -> Option<EffectKind> { - if tcx.is_lang_item(def_id, EffectsMaybe) { + pub fn try_from_def_id<I: Interner>(cx: I, def_id: I::DefId) -> Option<EffectKind> { + if cx.is_lang_item(def_id, EffectsMaybe) { Some(EffectKind::Maybe) - } else if tcx.is_lang_item(def_id, EffectsRuntime) { + } else if cx.is_lang_item(def_id, EffectsRuntime) { Some(EffectKind::Runtime) - } else if tcx.is_lang_item(def_id, EffectsNoRuntime) { + } else if cx.is_lang_item(def_id, EffectsNoRuntime) { Some(EffectKind::NoRuntime) } else { None } } - pub fn to_def_id<I: Interner>(self, tcx: I) -> I::DefId { + pub fn to_def_id<I: Interner>(self, cx: I) -> I::DefId { let lang_item = match self { EffectKind::Maybe => EffectsMaybe, EffectKind::NoRuntime => EffectsNoRuntime, EffectKind::Runtime => EffectsRuntime, }; - tcx.require_lang_item(lang_item) + cx.require_lang_item(lang_item) } - pub fn try_from_ty<I: Interner>(tcx: I, ty: I::Ty) -> Option<EffectKind> { + pub fn try_from_ty<I: Interner>(cx: I, ty: I::Ty) -> Option<EffectKind> { if let crate::Adt(def, _) = ty.kind() { - Self::try_from_def_id(tcx, def.def_id()) + Self::try_from_def_id(cx, def.def_id()) } else { None } } - pub fn to_ty<I: Interner>(self, tcx: I) -> I::Ty { - I::Ty::new_adt(tcx, tcx.adt_def(self.to_def_id(tcx)), Default::default()) + pub fn to_ty<I: Interner>(self, cx: I) -> I::Ty { + I::Ty::new_adt(cx, cx.adt_def(self.to_def_id(cx)), Default::default()) } /// Returns an intersection between two effect kinds. If one effect kind diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index 0def7d12f74..7dd2f3de3f8 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -258,17 +258,17 @@ pub fn supertrait_def_ids<I: Interner>( } pub fn supertraits<I: Interner>( - tcx: I, + cx: I, trait_ref: ty::Binder<I, ty::TraitRef<I>>, ) -> FilterToTraits<I, Elaborator<I, I::Clause>> { - elaborate(tcx, [trait_ref.upcast(tcx)]).filter_only_self().filter_to_traits() + elaborate(cx, [trait_ref.upcast(cx)]).filter_only_self().filter_to_traits() } pub fn transitive_bounds<I: Interner>( - tcx: I, + cx: I, trait_refs: impl Iterator<Item = ty::Binder<I, ty::TraitRef<I>>>, ) -> FilterToTraits<I, Elaborator<I, I::Clause>> { - elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx))) + elaborate(cx, trait_refs.map(|trait_ref| trait_ref.upcast(cx))) .filter_only_self() .filter_to_traits() } diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs index 0810fa5c558..456accd1a1b 100644 --- a/compiler/rustc_type_ir/src/fast_reject.rs +++ b/compiler/rustc_type_ir/src/fast_reject.rs @@ -105,7 +105,7 @@ pub enum TreatParams { /// /// ¹ meaning that if the outermost layers are different, then the whole types are also different. pub fn simplify_type<I: Interner>( - tcx: I, + cx: I, ty: I::Ty, treat_params: TreatParams, ) -> Option<SimplifiedType<I::DefId>> { @@ -119,10 +119,10 @@ pub fn simplify_type<I: Interner>( ty::Str => Some(SimplifiedType::Str), ty::Array(..) => Some(SimplifiedType::Array), ty::Slice(..) => Some(SimplifiedType::Slice), - ty::Pat(ty, ..) => simplify_type(tcx, ty, treat_params), + ty::Pat(ty, ..) => simplify_type(cx, ty, treat_params), ty::RawPtr(_, mutbl) => Some(SimplifiedType::Ptr(mutbl)), ty::Dynamic(trait_info, ..) => match trait_info.principal_def_id() { - Some(principal_def_id) if !tcx.trait_is_auto(principal_def_id) => { + Some(principal_def_id) if !cx.trait_is_auto(principal_def_id) => { Some(SimplifiedType::Trait(principal_def_id)) } _ => Some(SimplifiedType::MarkerTraitObject), diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 09ee12d1cc3..a4d8dafb246 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -345,20 +345,20 @@ impl<I: Interner, T: TypeFoldable<I>, Ix: Idx> TypeFoldable<I> for IndexVec<Ix, // `rustc_middle/src/ty/generic_args.rs` for more details. struct Shifter<I: Interner> { - tcx: I, + cx: I, current_index: ty::DebruijnIndex, amount: u32, } impl<I: Interner> Shifter<I> { - pub fn new(tcx: I, amount: u32) -> Self { - Shifter { tcx, current_index: ty::INNERMOST, amount } + pub fn new(cx: I, amount: u32) -> Self { + Shifter { cx, current_index: ty::INNERMOST, amount } } } impl<I: Interner> TypeFolder<I> for Shifter<I> { fn cx(&self) -> I { - self.tcx + self.cx } fn fold_binder<T: TypeFoldable<I>>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> { @@ -372,7 +372,7 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> { match r.kind() { ty::ReBound(debruijn, br) if debruijn >= self.current_index => { let debruijn = debruijn.shifted_in(self.amount); - Region::new_bound(self.tcx, debruijn, br) + Region::new_bound(self.cx, debruijn, br) } _ => r, } @@ -382,7 +382,7 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> { match ty.kind() { ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => { let debruijn = debruijn.shifted_in(self.amount); - Ty::new_bound(self.tcx, debruijn, bound_ty) + Ty::new_bound(self.cx, debruijn, bound_ty) } _ if ty.has_vars_bound_at_or_above(self.current_index) => ty.super_fold_with(self), @@ -394,7 +394,7 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> { match ct.kind() { ty::ConstKind::Bound(debruijn, bound_ct) if debruijn >= self.current_index => { let debruijn = debruijn.shifted_in(self.amount); - Const::new_bound(self.tcx, debruijn, bound_ct) + Const::new_bound(self.cx, debruijn, bound_ct) } _ => ct.super_fold_with(self), } @@ -405,16 +405,16 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> { } } -pub fn shift_region<I: Interner>(tcx: I, region: I::Region, amount: u32) -> I::Region { +pub fn shift_region<I: Interner>(cx: I, region: I::Region, amount: u32) -> I::Region { match region.kind() { ty::ReBound(debruijn, br) if amount > 0 => { - Region::new_bound(tcx, debruijn.shifted_in(amount), br) + Region::new_bound(cx, debruijn.shifted_in(amount), br) } _ => region, } } -pub fn shift_vars<I: Interner, T>(tcx: I, value: T, amount: u32) -> T +pub fn shift_vars<I: Interner, T>(cx: I, value: T, amount: u32) -> T where T: TypeFoldable<I>, { @@ -424,5 +424,5 @@ where return value; } - value.fold_with(&mut Shifter::new(tcx, amount)) + value.fold_with(&mut Shifter::new(cx, amount)) } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index f05d626b470..63ad36efc85 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -475,7 +475,7 @@ pub trait Clause<I: Interner<Clause = Self>>: /// poly-trait-ref to supertraits that must hold if that /// poly-trait-ref holds. This is slightly different from a normal /// instantiation in terms of what happens with bound regions. - fn instantiate_supertrait(self, tcx: I, trait_ref: ty::Binder<I, ty::TraitRef<I>>) -> Self; + fn instantiate_supertrait(self, cx: I, trait_ref: ty::Binder<I, ty::TraitRef<I>>) -> Self; } /// Common capabilities of placeholder kinds diff --git a/compiler/rustc_type_ir/src/lift.rs b/compiler/rustc_type_ir/src/lift.rs index 839da10db5e..e5a099d1f50 100644 --- a/compiler/rustc_type_ir/src/lift.rs +++ b/compiler/rustc_type_ir/src/lift.rs @@ -17,5 +17,5 @@ /// e.g., `()` or `u8`, was interned in a different context. pub trait Lift<I>: std::fmt::Debug { type Lifted: std::fmt::Debug; - fn lift_to_tcx(self, tcx: I) -> Option<Self::Lifted>; + fn lift_to_interner(self, cx: I) -> Option<Self::Lifted>; } diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs index d8ed4770e2d..e5d18fcb3d1 100644 --- a/compiler/rustc_type_ir/src/opaque_ty.rs +++ b/compiler/rustc_type_ir/src/opaque_ty.rs @@ -22,8 +22,8 @@ pub struct OpaqueTypeKey<I: Interner> { } impl<I: Interner> OpaqueTypeKey<I> { - pub fn iter_captured_args(self, tcx: I) -> impl Iterator<Item = (usize, I::GenericArg)> { - let variances = tcx.variances_of(self.def_id.into()); + pub fn iter_captured_args(self, cx: I) -> impl Iterator<Item = (usize, I::GenericArg)> { + let variances = cx.variances_of(self.def_id.into()); std::iter::zip(self.args.iter(), variances.iter()).enumerate().filter_map( |(i, (arg, v))| match (arg.kind(), v) { (_, ty::Invariant) => Some((i, arg)), @@ -35,18 +35,18 @@ impl<I: Interner> OpaqueTypeKey<I> { pub fn fold_captured_lifetime_args( self, - tcx: I, + cx: I, mut f: impl FnMut(I::Region) -> I::Region, ) -> Self { let Self { def_id, args } = self; - let variances = tcx.variances_of(def_id.into()); + let variances = cx.variances_of(def_id.into()); let args = std::iter::zip(args.iter(), variances.iter()).map(|(arg, v)| match (arg.kind(), v) { (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg, (ty::GenericArgKind::Lifetime(lt), _) => f(lt).into(), _ => arg, }); - let args = tcx.mk_args_from_iter(args); + let args = cx.mk_args_from_iter(args); Self { def_id, args } } } diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs index 10b6f3355d9..eb84f3dd587 100644 --- a/compiler/rustc_type_ir/src/outlives.rs +++ b/compiler/rustc_type_ir/src/outlives.rs @@ -54,15 +54,15 @@ pub enum Component<I: Interner> { /// Push onto `out` all the things that must outlive `'a` for the condition /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**. pub fn push_outlives_components<I: Interner>( - tcx: I, + cx: I, ty: I::Ty, out: &mut SmallVec<[Component<I>; 4]>, ) { - ty.visit_with(&mut OutlivesCollector { tcx, out, visited: Default::default() }); + ty.visit_with(&mut OutlivesCollector { cx, out, visited: Default::default() }); } struct OutlivesCollector<'a, I: Interner> { - tcx: I, + cx: I, out: &'a mut SmallVec<[Component<I>; 4]>, visited: SsoHashSet<I::Ty>, } @@ -147,7 +147,7 @@ impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> { // OutlivesProjectionComponents. Continue walking // through and constrain Pi. let mut subcomponents = smallvec![]; - compute_alias_components_recursive(self.tcx, ty, &mut subcomponents); + compute_alias_components_recursive(self.cx, ty, &mut subcomponents); self.out.push(Component::EscapingAlias(subcomponents.into_iter().collect())); } } @@ -206,7 +206,7 @@ impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> { /// This should not be used to get the components of `parent` itself. /// Use [push_outlives_components] instead. pub fn compute_alias_components_recursive<I: Interner>( - tcx: I, + cx: I, alias_ty: I::Ty, out: &mut SmallVec<[Component<I>; 4]>, ) { @@ -215,9 +215,9 @@ pub fn compute_alias_components_recursive<I: Interner>( }; let opt_variances = - if kind == ty::Opaque { Some(tcx.variances_of(alias_ty.def_id)) } else { None }; + if kind == ty::Opaque { Some(cx.variances_of(alias_ty.def_id)) } else { None }; - let mut visitor = OutlivesCollector { tcx, out, visited: Default::default() }; + let mut visitor = OutlivesCollector { cx, out, visited: Default::default() }; for (index, child) in alias_ty.args.iter().enumerate() { if opt_variances.and_then(|variances| variances.get(index)) == Some(ty::Bivariant) { diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index e5bcbc67f94..e03f521c5b1 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -34,8 +34,8 @@ where { type Lifted = OutlivesPredicate<U, A::Lifted>; - fn lift_to_tcx(self, tcx: U) -> Option<Self::Lifted> { - Some(OutlivesPredicate(self.0.lift_to_tcx(tcx)?, self.1.lift_to_tcx(tcx)?)) + fn lift_to_interner(self, cx: U) -> Option<Self::Lifted> { + Some(OutlivesPredicate(self.0.lift_to_interner(cx)?, self.1.lift_to_interner(cx)?)) } } @@ -267,25 +267,23 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> { /// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`), /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example). - pub fn with_self_ty(&self, tcx: I, self_ty: I::Ty) -> I::Clause { + pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> I::Clause { match self.skip_binder() { - ExistentialPredicate::Trait(tr) => { - self.rebind(tr).with_self_ty(tcx, self_ty).upcast(tcx) - } + ExistentialPredicate::Trait(tr) => self.rebind(tr).with_self_ty(cx, self_ty).upcast(cx), ExistentialPredicate::Projection(p) => { - self.rebind(p.with_self_ty(tcx, self_ty)).upcast(tcx) + self.rebind(p.with_self_ty(cx, self_ty)).upcast(cx) } ExistentialPredicate::AutoTrait(did) => { - let generics = tcx.generics_of(did); + let generics = cx.generics_of(did); let trait_ref = if generics.count() == 1 { - ty::TraitRef::new(tcx, did, [self_ty]) + ty::TraitRef::new(cx, did, [self_ty]) } else { // If this is an ill-formed auto trait, then synthesize // new error args for the missing generics. - let err_args = GenericArgs::extend_with_error(tcx, did, &[self_ty.into()]); - ty::TraitRef::new_from_args(tcx, did, err_args) + let err_args = GenericArgs::extend_with_error(cx, did, &[self_ty.into()]); + ty::TraitRef::new_from_args(cx, did, err_args) }; - self.rebind(trait_ref).upcast(tcx) + self.rebind(trait_ref).upcast(cx) } } } @@ -345,8 +343,8 @@ impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> { /// we convert the principal trait-ref into a normal trait-ref, /// you must give *some* self type. A common choice is `mk_err()` /// or some placeholder type. - pub fn with_self_ty(&self, tcx: I, self_ty: I::Ty) -> ty::Binder<I, TraitRef<I>> { - self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty)) + pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, TraitRef<I>> { + self.map_bound(|trait_ref| trait_ref.with_self_ty(cx, self_ty)) } } @@ -406,8 +404,8 @@ impl<I: Interner> ExistentialProjection<I> { } impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> { - pub fn with_self_ty(&self, tcx: I, self_ty: I::Ty) -> ty::Binder<I, ProjectionPredicate<I>> { - self.map_bound(|p| p.with_self_ty(tcx, self_ty)) + pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, ProjectionPredicate<I>> { + self.map_bound(|p| p.with_self_ty(cx, self_ty)) } pub fn item_def_id(&self) -> I::DefId { @@ -669,21 +667,21 @@ impl<I: Interner> ProjectionPredicate<I> { impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> { /// Returns the `DefId` of the trait of the associated item being projected. #[inline] - pub fn trait_def_id(&self, tcx: I) -> I::DefId { - self.skip_binder().projection_term.trait_def_id(tcx) + pub fn trait_def_id(&self, cx: I) -> I::DefId { + self.skip_binder().projection_term.trait_def_id(cx) } /// Get the trait ref required for this projection to be well formed. /// Note that for generic associated types the predicates of the associated /// type also need to be checked. #[inline] - pub fn required_poly_trait_ref(&self, tcx: I) -> ty::Binder<I, TraitRef<I>> { + pub fn required_poly_trait_ref(&self, cx: I) -> ty::Binder<I, TraitRef<I>> { // Note: unlike with `TraitRef::to_poly_trait_ref()`, // `self.0.trait_ref` is permitted to have escaping regions. // This is because here `self` has a `Binder` and so does our // return value, so we are preserving the number of binding // levels. - self.map_bound(|predicate| predicate.projection_term.trait_ref(tcx)) + self.map_bound(|predicate| predicate.projection_term.trait_ref(cx)) } pub fn term(&self) -> ty::Binder<I, I::Term> { diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 0439e7f857f..a8f48d14af5 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -56,7 +56,7 @@ impl<I: Interner> VarianceDiagInfo<I> { } pub trait TypeRelation<I: Interner>: Sized { - fn tcx(&self) -> I; + fn cx(&self) -> I; /// Returns a static string we can use for printouts. fn tag(&self) -> &'static str; @@ -80,8 +80,8 @@ pub trait TypeRelation<I: Interner>: Sized { item_def_id, a_arg, b_arg ); - let tcx = self.tcx(); - let opt_variances = tcx.variances_of(item_def_id); + let cx = self.cx(); + let opt_variances = cx.variances_of(item_def_id); relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true) } @@ -128,7 +128,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>( a_arg: I::GenericArgs, b_arg: I::GenericArgs, ) -> RelateResult<I, I::GenericArgs> { - relation.tcx().mk_args_from_iter(iter::zip(a_arg.iter(), b_arg.iter()).map(|(a, b)| { + relation.cx().mk_args_from_iter(iter::zip(a_arg.iter(), b_arg.iter()).map(|(a, b)| { relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b) })) } @@ -141,14 +141,13 @@ pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>( b_arg: I::GenericArgs, fetch_ty_for_diag: bool, ) -> RelateResult<I, I::GenericArgs> { - let tcx = relation.tcx(); + let cx = relation.cx(); let mut cached_ty = None; let params = iter::zip(a_arg.iter(), b_arg.iter()).enumerate().map(|(i, (a, b))| { let variance = variances.get(i).unwrap(); let variance_info = if variance == ty::Invariant && fetch_ty_for_diag { - let ty = - *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, a_arg)); + let ty = *cached_ty.get_or_insert_with(|| cx.type_of(ty_def_id).instantiate(cx, a_arg)); VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } } else { VarianceDiagInfo::default() @@ -156,7 +155,7 @@ pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>( relation.relate_with_variance(variance, variance_info, a, b) }); - tcx.mk_args_from_iter(params) + cx.mk_args_from_iter(params) } impl<I: Interner> Relate<I> for ty::FnSig<I> { @@ -165,7 +164,7 @@ impl<I: Interner> Relate<I> for ty::FnSig<I> { a: ty::FnSig<I>, b: ty::FnSig<I>, ) -> RelateResult<I, ty::FnSig<I>> { - let tcx = relation.tcx(); + let cx = relation.cx(); if a.c_variadic != b.c_variadic { return Err(TypeError::VariadicMismatch({ @@ -210,7 +209,7 @@ impl<I: Interner> Relate<I> for ty::FnSig<I> { r => r, }); Ok(ty::FnSig { - inputs_and_output: tcx.mk_type_list_from_iter(inputs_and_output)?, + inputs_and_output: cx.mk_type_list_from_iter(inputs_and_output)?, c_variadic: a.c_variadic, safety, abi, @@ -245,11 +244,11 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> { ExpectedFound::new(true, a, b) })) } else { - let args = match a.kind(relation.tcx()) { + let args = match a.kind(relation.cx()) { ty::Opaque => relate_args_with_variances( relation, a.def_id, - relation.tcx().variances_of(a.def_id), + relation.cx().variances_of(a.def_id), a.args, b.args, false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle @@ -258,7 +257,7 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> { relate_args_invariantly(relation, a.args, b.args)? } }; - Ok(ty::AliasTy::new_from_args(relation.tcx(), a.def_id, args)) + Ok(ty::AliasTy::new_from_args(relation.cx(), a.def_id, args)) } } } @@ -276,11 +275,11 @@ impl<I: Interner> Relate<I> for ty::AliasTerm<I> { ExpectedFound::new(true, a, b) })) } else { - let args = match a.kind(relation.tcx()) { + let args = match a.kind(relation.cx()) { ty::AliasTermKind::OpaqueTy => relate_args_with_variances( relation, a.def_id, - relation.tcx().variances_of(a.def_id), + relation.cx().variances_of(a.def_id), a.args, b.args, false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle @@ -293,7 +292,7 @@ impl<I: Interner> Relate<I> for ty::AliasTerm<I> { relate_args_invariantly(relation, a.args, b.args)? } }; - Ok(ty::AliasTerm::new_from_args(relation.tcx(), a.def_id, args)) + Ok(ty::AliasTerm::new_from_args(relation.cx(), a.def_id, args)) } } } @@ -343,7 +342,7 @@ impl<I: Interner> Relate<I> for ty::TraitRef<I> { })) } else { let args = relate_args_invariantly(relation, a.args, b.args)?; - Ok(ty::TraitRef::new_from_args(relation.tcx(), a.def_id, args)) + Ok(ty::TraitRef::new_from_args(relation.cx(), a.def_id, args)) } } } @@ -377,7 +376,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( a: I::Ty, b: I::Ty, ) -> RelateResult<I, I::Ty> { - let tcx = relation.tcx(); + let cx = relation.cx(); match (a.kind(), b.kind()) { (ty::Infer(_), _) | (_, ty::Infer(_)) => { // The caller should handle these cases! @@ -388,7 +387,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( panic!("bound types encountered in structurally_relate_tys") } - (ty::Error(guar), _) | (_, ty::Error(guar)) => Ok(Ty::new_error(tcx, guar)), + (ty::Error(guar), _) | (_, ty::Error(guar)) => Ok(Ty::new_error(cx, guar)), (ty::Never, _) | (ty::Char, _) @@ -412,16 +411,16 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( (ty::Adt(a_def, a_args), ty::Adt(b_def, b_args)) if a_def == b_def => { let args = relation.relate_item_args(a_def.def_id(), a_args, b_args)?; - Ok(Ty::new_adt(tcx, a_def, args)) + Ok(Ty::new_adt(cx, a_def, args)) } - (ty::Foreign(a_id), ty::Foreign(b_id)) if a_id == b_id => Ok(Ty::new_foreign(tcx, a_id)), + (ty::Foreign(a_id), ty::Foreign(b_id)) if a_id == b_id => Ok(Ty::new_foreign(cx, a_id)), (ty::Dynamic(a_obj, a_region, a_repr), ty::Dynamic(b_obj, b_region, b_repr)) if a_repr == b_repr => { Ok(Ty::new_dynamic( - tcx, + cx, relation.relate(a_obj, b_obj)?, relation.relate(a_region, b_region)?, a_repr, @@ -433,7 +432,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( // the (anonymous) type of the same coroutine expression. So // all of their regions should be equated. let args = relate_args_invariantly(relation, a_args, b_args)?; - Ok(Ty::new_coroutine(tcx, a_id, args)) + Ok(Ty::new_coroutine(cx, a_id, args)) } (ty::CoroutineWitness(a_id, a_args), ty::CoroutineWitness(b_id, b_args)) @@ -443,7 +442,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( // the (anonymous) type of the same coroutine expression. So // all of their regions should be equated. let args = relate_args_invariantly(relation, a_args, b_args)?; - Ok(Ty::new_coroutine_witness(tcx, a_id, args)) + Ok(Ty::new_coroutine_witness(cx, a_id, args)) } (ty::Closure(a_id, a_args), ty::Closure(b_id, b_args)) if a_id == b_id => { @@ -451,14 +450,14 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( // the (anonymous) type of the same closure expression. So // all of their regions should be equated. let args = relate_args_invariantly(relation, a_args, b_args)?; - Ok(Ty::new_closure(tcx, a_id, args)) + Ok(Ty::new_closure(cx, a_id, args)) } (ty::CoroutineClosure(a_id, a_args), ty::CoroutineClosure(b_id, b_args)) if a_id == b_id => { let args = relate_args_invariantly(relation, a_args, b_args)?; - Ok(Ty::new_coroutine_closure(tcx, a_id, args)) + Ok(Ty::new_coroutine_closure(cx, a_id, args)) } (ty::RawPtr(a_ty, a_mutbl), ty::RawPtr(b_ty, b_mutbl)) => { @@ -475,7 +474,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( let ty = relation.relate_with_variance(variance, info, a_ty, b_ty)?; - Ok(Ty::new_ptr(tcx, ty, a_mutbl)) + Ok(Ty::new_ptr(cx, ty, a_mutbl)) } (ty::Ref(a_r, a_ty, a_mutbl), ty::Ref(b_r, b_ty, b_mutbl)) => { @@ -493,18 +492,18 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( let r = relation.relate(a_r, b_r)?; let ty = relation.relate_with_variance(variance, info, a_ty, b_ty)?; - Ok(Ty::new_ref(tcx, r, ty, a_mutbl)) + Ok(Ty::new_ref(cx, r, ty, a_mutbl)) } (ty::Array(a_t, sz_a), ty::Array(b_t, sz_b)) => { let t = relation.relate(a_t, b_t)?; match relation.relate(sz_a, sz_b) { - Ok(sz) => Ok(Ty::new_array_with_const_len(tcx, t, sz)), + Ok(sz) => Ok(Ty::new_array_with_const_len(cx, t, sz)), Err(err) => { // Check whether the lengths are both concrete/known values, // but are unequal, for better diagnostics. - let sz_a = sz_a.try_to_target_usize(tcx); - let sz_b = sz_b.try_to_target_usize(tcx); + let sz_a = sz_a.try_to_target_usize(cx); + let sz_b = sz_b.try_to_target_usize(cx); match (sz_a, sz_b) { (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err( @@ -518,13 +517,13 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( (ty::Slice(a_t), ty::Slice(b_t)) => { let t = relation.relate(a_t, b_t)?; - Ok(Ty::new_slice(tcx, t)) + Ok(Ty::new_slice(cx, t)) } (ty::Tuple(as_), ty::Tuple(bs)) => { if as_.len() == bs.len() { Ok(Ty::new_tup_from_iter( - tcx, + cx, iter::zip(as_.iter(), bs.iter()).map(|(a, b)| relation.relate(a, b)), )?) } else if !(as_.is_empty() || bs.is_empty()) { @@ -536,25 +535,25 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( (ty::FnDef(a_def_id, a_args), ty::FnDef(b_def_id, b_args)) if a_def_id == b_def_id => { let args = relation.relate_item_args(a_def_id, a_args, b_args)?; - Ok(Ty::new_fn_def(tcx, a_def_id, args)) + Ok(Ty::new_fn_def(cx, a_def_id, args)) } (ty::FnPtr(a_fty), ty::FnPtr(b_fty)) => { let fty = relation.relate(a_fty, b_fty)?; - Ok(Ty::new_fn_ptr(tcx, fty)) + Ok(Ty::new_fn_ptr(cx, fty)) } // Alias tend to mostly already be handled downstream due to normalization. (ty::Alias(a_kind, a_data), ty::Alias(b_kind, b_data)) => { let alias_ty = relation.relate(a_data, b_data)?; assert_eq!(a_kind, b_kind); - Ok(Ty::new_alias(tcx, a_kind, alias_ty)) + Ok(Ty::new_alias(cx, a_kind, alias_ty)) } (ty::Pat(a_ty, a_pat), ty::Pat(b_ty, b_pat)) => { let ty = relation.relate(a_ty, b_ty)?; let pat = relation.relate(a_pat, b_pat)?; - Ok(Ty::new_pat(tcx, ty, pat)) + Ok(Ty::new_pat(cx, ty, pat)) } _ => Err(TypeError::Sorts(ExpectedFound::new(true, a, b))), @@ -573,11 +572,11 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>( mut b: I::Const, ) -> RelateResult<I, I::Const> { debug!("{}.structurally_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b); - let tcx = relation.tcx(); + let cx = relation.cx(); - if tcx.features().generic_const_exprs() { - a = tcx.expand_abstract_consts(a); - b = tcx.expand_abstract_consts(b); + if cx.features().generic_const_exprs() { + a = cx.expand_abstract_consts(a); + b = cx.expand_abstract_consts(b); } debug!("{}.structurally_relate_consts(normed_a = {:?}, normed_b = {:?})", relation.tag(), a, b); @@ -607,8 +606,8 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>( // be stabilized. (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => { if cfg!(debug_assertions) { - let a_ty = tcx.type_of(au.def).instantiate(tcx, au.args); - let b_ty = tcx.type_of(bu.def).instantiate(tcx, bu.args); + let a_ty = cx.type_of(au.def).instantiate(cx, au.args); + let b_ty = cx.type_of(bu.def).instantiate(cx, bu.args); assert_eq!(a_ty, b_ty); } @@ -618,11 +617,11 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>( au.args, bu.args, )?; - return Ok(Const::new_unevaluated(tcx, ty::UnevaluatedConst { def: au.def, args })); + return Ok(Const::new_unevaluated(cx, ty::UnevaluatedConst { def: au.def, args })); } (ty::ConstKind::Expr(ae), ty::ConstKind::Expr(be)) => { let expr = relation.relate(ae, be)?; - return Ok(Const::new_expr(tcx, expr)); + return Ok(Const::new_expr(cx, expr)); } _ => false, }; diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 7934f996f0b..2449ac47db6 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -106,13 +106,13 @@ pub struct Goal<I: Interner, P> { } impl<I: Interner, P> Goal<I, P> { - pub fn new(tcx: I, param_env: I::ParamEnv, predicate: impl Upcast<I, P>) -> Goal<I, P> { - Goal { param_env, predicate: predicate.upcast(tcx) } + pub fn new(cx: I, param_env: I::ParamEnv, predicate: impl Upcast<I, P>) -> Goal<I, P> { + Goal { param_env, predicate: predicate.upcast(cx) } } /// Updates the goal to one with a different `predicate` but the same `param_env`. - pub fn with<Q>(self, tcx: I, predicate: impl Upcast<I, Q>) -> Goal<I, Q> { - Goal { param_env: self.param_env, predicate: predicate.upcast(tcx) } + pub fn with<Q>(self, cx: I, predicate: impl Upcast<I, Q>) -> Goal<I, Q> { + Goal { param_env: self.param_env, predicate: predicate.upcast(cx) } } } diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index 24a7c0c67e9..6c5bbbfd59b 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -136,9 +136,9 @@ pub struct ClosureArgsParts<I: Interner> { impl<I: Interner> ClosureArgs<I> { /// Construct `ClosureArgs` from `ClosureArgsParts`, containing `Args` /// for the closure parent, alongside additional closure-specific components. - pub fn new(tcx: I, parts: ClosureArgsParts<I>) -> ClosureArgs<I> { + pub fn new(cx: I, parts: ClosureArgsParts<I>) -> ClosureArgs<I> { ClosureArgs { - args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([ + args: cx.mk_args_from_iter(parts.parent_args.iter().chain([ parts.closure_kind_ty.into(), parts.closure_sig_as_fn_ptr_ty.into(), parts.tupled_upvars_ty.into(), @@ -258,9 +258,9 @@ pub struct CoroutineClosureArgsParts<I: Interner> { } impl<I: Interner> CoroutineClosureArgs<I> { - pub fn new(tcx: I, parts: CoroutineClosureArgsParts<I>) -> CoroutineClosureArgs<I> { + pub fn new(cx: I, parts: CoroutineClosureArgsParts<I>) -> CoroutineClosureArgs<I> { CoroutineClosureArgs { - args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([ + args: cx.mk_args_from_iter(parts.parent_args.iter().chain([ parts.closure_kind_ty.into(), parts.signature_parts_ty.into(), parts.tupled_upvars_ty.into(), @@ -409,14 +409,14 @@ impl<I: Interner> CoroutineClosureSignature<I> { /// When the kind and upvars are known, use the other helper functions. pub fn to_coroutine( self, - tcx: I, + cx: I, parent_args: I::GenericArgsSlice, coroutine_kind_ty: I::Ty, coroutine_def_id: I::DefId, tupled_upvars_ty: I::Ty, ) -> I::Ty { let coroutine_args = ty::CoroutineArgs::new( - tcx, + cx, ty::CoroutineArgsParts { parent_args, kind_ty: coroutine_kind_ty, @@ -428,7 +428,7 @@ impl<I: Interner> CoroutineClosureSignature<I> { }, ); - Ty::new_coroutine(tcx, coroutine_def_id, coroutine_args.args) + Ty::new_coroutine(cx, coroutine_def_id, coroutine_args.args) } /// Given known upvars and a [`ClosureKind`](ty::ClosureKind), compute the coroutine @@ -438,7 +438,7 @@ impl<I: Interner> CoroutineClosureSignature<I> { /// that the `ClosureKind` is actually supported by the coroutine-closure. pub fn to_coroutine_given_kind_and_upvars( self, - tcx: I, + cx: I, parent_args: I::GenericArgsSlice, coroutine_def_id: I::DefId, goal_kind: ty::ClosureKind, @@ -447,7 +447,7 @@ impl<I: Interner> CoroutineClosureSignature<I> { coroutine_captures_by_ref_ty: I::Ty, ) -> I::Ty { let tupled_upvars_ty = Self::tupled_upvars_by_closure_kind( - tcx, + cx, goal_kind, self.tupled_inputs_ty, closure_tupled_upvars_ty, @@ -456,9 +456,9 @@ impl<I: Interner> CoroutineClosureSignature<I> { ); self.to_coroutine( - tcx, + cx, parent_args, - Ty::from_coroutine_closure_kind(tcx, goal_kind), + Ty::from_coroutine_closure_kind(cx, goal_kind), coroutine_def_id, tupled_upvars_ty, ) @@ -474,7 +474,7 @@ impl<I: Interner> CoroutineClosureSignature<I> { /// lifetimes are related to the lifetime of the borrow on the closure made for /// the call. This allows borrowck to enforce the self-borrows correctly. pub fn tupled_upvars_by_closure_kind( - tcx: I, + cx: I, kind: ty::ClosureKind, tupled_inputs_ty: I::Ty, closure_tupled_upvars_ty: I::Ty, @@ -488,12 +488,12 @@ impl<I: Interner> CoroutineClosureSignature<I> { }; let coroutine_captures_by_ref_ty = sig.output().skip_binder().fold_with(&mut FoldEscapingRegions { - interner: tcx, + interner: cx, region: env_region, debruijn: ty::INNERMOST, }); Ty::new_tup_from_iter( - tcx, + cx, tupled_inputs_ty .tuple_fields() .iter() @@ -501,7 +501,7 @@ impl<I: Interner> CoroutineClosureSignature<I> { ) } ty::ClosureKind::FnOnce => Ty::new_tup_from_iter( - tcx, + cx, tupled_inputs_ty .tuple_fields() .iter() @@ -615,9 +615,9 @@ pub struct CoroutineArgsParts<I: Interner> { impl<I: Interner> CoroutineArgs<I> { /// Construct `CoroutineArgs` from `CoroutineArgsParts`, containing `Args` /// for the coroutine parent, alongside additional coroutine-specific components. - pub fn new(tcx: I, parts: CoroutineArgsParts<I>) -> CoroutineArgs<I> { + pub fn new(cx: I, parts: CoroutineArgsParts<I>) -> CoroutineArgs<I> { CoroutineArgs { - args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([ + args: cx.mk_args_from_iter(parts.parent_args.iter().chain([ parts.kind_ty.into(), parts.resume_ty.into(), parts.yield_ty.into(), diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index 000bcf2d3b2..f5b90424afb 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -71,7 +71,7 @@ fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { wc.push(parse_quote! { #ty: ::rustc_type_ir::lift::Lift<J, Lifted = #lifted_ty> }); let bind = &bindings[index]; quote! { - #bind.lift_to_tcx(interner)? + #bind.lift_to_interner(interner)? } }) }); @@ -89,7 +89,7 @@ fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { quote! { type Lifted = #lifted_ty; - fn lift_to_tcx( + fn lift_to_interner( self, interner: J, ) -> Option<Self::Lifted> { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 720da0feece..c4c63883389 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -947,7 +947,6 @@ extern "rust-intrinsic" { #[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")] #[rustc_nounwind] pub fn unreachable() -> !; - } /// Informs the optimizer that a condition is always true. @@ -1018,78 +1017,40 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn breakpoint(); - /// The size of a type in bytes. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// More specifically, this is the offset in bytes between successive - /// items of the same type, including alignment padding. - /// - /// The stabilized version of this intrinsic is [`core::mem::size_of`]. + #[cfg(bootstrap)] #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn size_of<T>() -> usize; - /// The minimum alignment of a type. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is [`core::mem::align_of`]. + #[cfg(bootstrap)] #[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn min_align_of<T>() -> usize; - /// The preferred alignment of a type. - /// - /// This intrinsic does not have a stable counterpart. - /// It's "tracking issue" is [#91971](https://github.com/rust-lang/rust/issues/91971). + + #[cfg(bootstrap)] #[rustc_const_unstable(feature = "const_pref_align_of", issue = "91971")] #[rustc_nounwind] pub fn pref_align_of<T>() -> usize; - /// The size of the referenced value in bytes. - /// - /// The stabilized version of this intrinsic is [`crate::mem::size_of_val`]. + #[cfg(bootstrap)] #[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")] #[rustc_nounwind] pub fn size_of_val<T: ?Sized>(_: *const T) -> usize; - /// The required alignment of the referenced value. - /// - /// The stabilized version of this intrinsic is [`core::mem::align_of_val`]. + + #[cfg(bootstrap)] #[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")] #[rustc_nounwind] pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize; - /// Gets a static string slice containing the name of a type. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is [`core::any::type_name`]. + #[cfg(bootstrap)] #[rustc_const_unstable(feature = "const_type_name", issue = "63084")] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn type_name<T: ?Sized>() -> &'static str; - /// Gets an identifier which is globally unique to the specified type. This - /// function will return the same value for a type regardless of whichever - /// crate it is invoked in. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is [`core::any::TypeId::of`]. + #[cfg(bootstrap)] #[rustc_const_unstable(feature = "const_type_id", issue = "77125")] #[rustc_safe_intrinsic] #[rustc_nounwind] @@ -2424,15 +2385,7 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant; - /// Returns the number of variants of the type `T` cast to a `usize`; - /// if `T` has no variants, returns `0`. Uninhabited variants will be counted. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The to-be-stabilized version of this intrinsic is [`crate::mem::variant_count`]. + #[cfg(bootstrap)] #[rustc_const_unstable(feature = "variant_count", issue = "73662")] #[rustc_safe_intrinsic] #[rustc_nounwind] @@ -2773,8 +2726,11 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) // Runtime NOP } -/// `ptr` must point to a vtable. /// The intrinsic will return the size stored in that vtable. +/// +/// # Safety +/// +/// `ptr` must point to a vtable. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] @@ -2783,8 +2739,11 @@ pub unsafe fn vtable_size(_ptr: *const ()) -> usize { unreachable!() } -/// `ptr` must point to a vtable. /// The intrinsic will return the alignment stored in that vtable. +/// +/// # Safety +/// +/// `ptr` must point to a vtable. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] @@ -2793,6 +2752,150 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize { unreachable!() } +/// The size of a type in bytes. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// More specifically, this is the offset in bytes between successive +/// items of the same type, including alignment padding. +/// +/// The stabilized version of this intrinsic is [`core::mem::size_of`]. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[cfg(not(bootstrap))] +pub const fn size_of<T>() -> usize { + unreachable!() +} + +/// The minimum alignment of a type. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is [`core::mem::align_of`]. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[cfg(not(bootstrap))] +pub const fn min_align_of<T>() -> usize { + unreachable!() +} + +/// The preferred alignment of a type. +/// +/// This intrinsic does not have a stable counterpart. +/// It's "tracking issue" is [#91971](https://github.com/rust-lang/rust/issues/91971). +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "const_pref_align_of", issue = "91971")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[cfg(not(bootstrap))] +pub const unsafe fn pref_align_of<T>() -> usize { + unreachable!() +} + +/// Returns the number of variants of the type `T` cast to a `usize`; +/// if `T` has no variants, returns `0`. Uninhabited variants will be counted. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The to-be-stabilized version of this intrinsic is [`crate::mem::variant_count`]. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "variant_count", issue = "73662")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[cfg(not(bootstrap))] +pub const fn variant_count<T>() -> usize { + unreachable!() +} + +/// The size of the referenced value in bytes. +/// +/// The stabilized version of this intrinsic is [`crate::mem::size_of_val`]. +/// +/// # Safety +/// +/// See [`crate::mem::size_of_val_raw`] for safety conditions. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[cfg(not(bootstrap))] +pub const unsafe fn size_of_val<T: ?Sized>(_ptr: *const T) -> usize { + unreachable!() +} + +/// The required alignment of the referenced value. +/// +/// The stabilized version of this intrinsic is [`core::mem::align_of_val`]. +/// +/// # Safety +/// +/// See [`crate::mem::align_of_val_raw`] for safety conditions. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[cfg(not(bootstrap))] +pub const unsafe fn min_align_of_val<T: ?Sized>(_ptr: *const T) -> usize { + unreachable!() +} + +/// Gets a static string slice containing the name of a type. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is [`core::any::type_name`]. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "const_type_name", issue = "63084")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[cfg(not(bootstrap))] +pub const fn type_name<T: ?Sized>() -> &'static str { + unreachable!() +} + +/// Gets an identifier which is globally unique to the specified type. This +/// function will return the same value for a type regardless of whichever +/// crate it is invoked in. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is [`core::any::TypeId::of`]. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "const_type_id", issue = "77125")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[cfg(not(bootstrap))] +pub const fn type_id<T: ?Sized + 'static>() -> u128 { + unreachable!() +} + /// Lowers in MIR to `Rvalue::Aggregate` with `AggregateKind::RawPtr`. /// /// This is used to implement functions like `slice::from_raw_parts_mut` and diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index eb86bf66206..06f205c0f26 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -5,6 +5,7 @@ use crate::hash::{Hash, Hasher}; use crate::intrinsics::aggregate_raw_ptr; use crate::intrinsics::ptr_metadata; use crate::marker::Freeze; +use crate::ptr::NonNull; /// Provides the pointer metadata type of any pointed-to type. /// @@ -153,7 +154,7 @@ pub const fn from_raw_parts_mut<T: ?Sized>( /// compare equal (since identical vtables can be deduplicated within a codegen unit). #[lang = "dyn_metadata"] pub struct DynMetadata<Dyn: ?Sized> { - _vtable_ptr: &'static VTable, + _vtable_ptr: NonNull<VTable>, _phantom: crate::marker::PhantomData<Dyn>, } @@ -166,15 +167,18 @@ extern "C" { } impl<Dyn: ?Sized> DynMetadata<Dyn> { - /// One of the things that rustc_middle does with this being a lang item is - /// give it `FieldsShape::Primitive`, which means that as far as codegen can - /// tell, it *is* a reference, and thus doesn't have any fields. - /// That means we can't use field access, and have to transmute it instead. + /// When `DynMetadata` appears as the metadata field of a wide pointer, the rustc_middle layout + /// computation does magic and the resulting layout is *not* a `FieldsShape::Aggregate`, instead + /// it is a `FieldsShape::Primitive`. This means that the same type can have different layout + /// depending on whether it appears as the metadata field of a wide pointer or as a stand-alone + /// type, which understandably confuses codegen and leads to ICEs when trying to project to a + /// field of `DynMetadata`. To work around that issue, we use `transmute` instead of using a + /// field projection. #[inline] fn vtable_ptr(self) -> *const VTable { // SAFETY: this layout assumption is hard-coded into the compiler. // If it's somehow not a size match, the transmute will error. - unsafe { crate::mem::transmute::<Self, &'static VTable>(self) } + unsafe { crate::mem::transmute::<Self, *const VTable>(self) } } /// Returns the size of the type associated with this vtable. diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 972b6015932..ba519afc62b 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -230,7 +230,7 @@ macro_rules! eprintln { /// ```rust /// let a = 2; /// let b = dbg!(a * 2) + 1; -/// // ^-- prints: [src/main.rs:2] a * 2 = 4 +/// // ^-- prints: [src/main.rs:2:9] a * 2 = 4 /// assert_eq!(b, 5); /// ``` /// @@ -281,7 +281,7 @@ macro_rules! eprintln { /// This prints to [stderr]: /// /// ```text,ignore -/// [src/main.rs:4] n.checked_sub(4) = None +/// [src/main.rs:2:22] n.checked_sub(4) = None /// ``` /// /// Naive factorial implementation: @@ -301,15 +301,15 @@ macro_rules! eprintln { /// This prints to [stderr]: /// /// ```text,ignore -/// [src/main.rs:3] n <= 1 = false -/// [src/main.rs:3] n <= 1 = false -/// [src/main.rs:3] n <= 1 = false -/// [src/main.rs:3] n <= 1 = true -/// [src/main.rs:4] 1 = 1 -/// [src/main.rs:5] n * factorial(n - 1) = 2 -/// [src/main.rs:5] n * factorial(n - 1) = 6 -/// [src/main.rs:5] n * factorial(n - 1) = 24 -/// [src/main.rs:11] factorial(4) = 24 +/// [src/main.rs:2:8] n <= 1 = false +/// [src/main.rs:2:8] n <= 1 = false +/// [src/main.rs:2:8] n <= 1 = false +/// [src/main.rs:2:8] n <= 1 = true +/// [src/main.rs:3:9] 1 = 1 +/// [src/main.rs:7:9] n * factorial(n - 1) = 2 +/// [src/main.rs:7:9] n * factorial(n - 1) = 6 +/// [src/main.rs:7:9] n * factorial(n - 1) = 24 +/// [src/main.rs:9:1] factorial(4) = 24 /// ``` /// /// The `dbg!(..)` macro moves the input: diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index a1f83029d27..5833c597256 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -24,9 +24,14 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; /// passed as an argument, it is not captured or consumed, and it never has the /// value `-1`. /// -/// This type's `.to_owned()` implementation returns another `BorrowedFd` -/// rather than an `OwnedFd`. It just makes a trivial copy of the raw file -/// descriptor, which is then borrowed under the same lifetime. +/// This type does not have a [`ToOwned`][crate::borrow::ToOwned] +/// implementation. Calling `.to_owned()` on a variable of this type will call +/// it on `&BorrowedFd` and use `Clone::clone()` like `ToOwned` does for all +/// types implementing `Clone`. The result will be descriptor borrowed under +/// the same lifetime. +/// +/// To obtain an [`OwnedFd`], you can use [`BorrowedFd::try_clone_to_owned`] +/// instead, but this is not supported on all platforms. #[derive(Copy, Clone)] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(0)] @@ -50,6 +55,8 @@ pub struct BorrowedFd<'fd> { /// descriptor, so it can be used in FFI in places where a file descriptor is /// passed as a consumed argument or returned as an owned value, and it never /// has the value `-1`. +/// +/// You can use [`AsFd::as_fd`] to obtain a [`BorrowedFd`]. #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(0)] // libstd/os/raw/mod.rs assures me that every libstd-supported platform has a diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index 2e5bd85327a..0db08c1a926 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -44,6 +44,7 @@ mod imp { use crate::ops::Range; use crate::ptr; use crate::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering}; + use crate::sync::OnceLock; use crate::sys::pal::unix::os; use crate::thread; @@ -306,9 +307,8 @@ mod imp { ret } - unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> { - let page_size = PAGE_SIZE.load(Ordering::Relaxed); - let stackptr = get_stack_start()?; + fn stack_start_aligned(page_size: usize) -> Option<*mut libc::c_void> { + let stackptr = unsafe { get_stack_start()? }; let stackaddr = stackptr.addr(); // Ensure stackaddr is page aligned! A parent process might @@ -325,104 +325,133 @@ mod imp { }) } + #[forbid(unsafe_op_in_unsafe_fn)] unsafe fn install_main_guard() -> Option<Range<usize>> { let page_size = PAGE_SIZE.load(Ordering::Relaxed); - if cfg!(all(target_os = "linux", not(target_env = "musl"))) { - // Linux doesn't allocate the whole stack right away, and - // the kernel has its own stack-guard mechanism to fault - // when growing too close to an existing mapping. If we map - // our own guard, then the kernel starts enforcing a rather - // large gap above that, rendering much of the possible - // stack space useless. See #43052. - // - // Instead, we'll just note where we expect rlimit to start - // faulting, so our handler can report "stack overflow", and - // trust that the kernel's own stack guard will work. - let stackptr = get_stack_start_aligned()?; - let stackaddr = stackptr.addr(); - Some(stackaddr - page_size..stackaddr) - } else if cfg!(all(target_os = "linux", target_env = "musl")) { - // For the main thread, the musl's pthread_attr_getstack - // returns the current stack size, rather than maximum size - // it can eventually grow to. It cannot be used to determine - // the position of kernel's stack guard. - None - } else if cfg!(target_os = "freebsd") { - // FreeBSD's stack autogrows, and optionally includes a guard page - // at the bottom. If we try to remap the bottom of the stack - // ourselves, FreeBSD's guard page moves upwards. So we'll just use - // the builtin guard page. - let stackptr = get_stack_start_aligned()?; - let guardaddr = stackptr.addr(); - // Technically the number of guard pages is tunable and controlled - // by the security.bsd.stack_guard_page sysctl. - // By default it is 1, checking once is enough since it is - // a boot time config value. - static PAGES: crate::sync::OnceLock<usize> = crate::sync::OnceLock::new(); - - let pages = PAGES.get_or_init(|| { - use crate::sys::weak::dlsym; - dlsym!(fn sysctlbyname(*const libc::c_char, *mut libc::c_void, *mut libc::size_t, *const libc::c_void, libc::size_t) -> libc::c_int); - let mut guard: usize = 0; - let mut size = crate::mem::size_of_val(&guard); - let oid = crate::ffi::CStr::from_bytes_with_nul( - b"security.bsd.stack_guard_page\0", - ) - .unwrap(); - match sysctlbyname.get() { - Some(fcn) => { - if fcn(oid.as_ptr(), core::ptr::addr_of_mut!(guard) as *mut _, core::ptr::addr_of_mut!(size) as *mut _, crate::ptr::null_mut(), 0) == 0 { - guard - } else { - 1 - } - }, - _ => 1, - } - }); - Some(guardaddr..guardaddr + pages * page_size) - } else if cfg!(any(target_os = "openbsd", target_os = "netbsd")) { - // OpenBSD stack already includes a guard page, and stack is - // immutable. - // NetBSD stack includes the guard page. - // - // We'll just note where we expect rlimit to start - // faulting, so our handler can report "stack overflow", and - // trust that the kernel's own stack guard will work. - let stackptr = get_stack_start_aligned()?; - let stackaddr = stackptr.addr(); - Some(stackaddr - page_size..stackaddr) - } else { - // Reallocate the last page of the stack. - // This ensures SIGBUS will be raised on - // stack overflow. - // Systems which enforce strict PAX MPROTECT do not allow - // to mprotect() a mapping with less restrictive permissions - // than the initial mmap() used, so we mmap() here with - // read/write permissions and only then mprotect() it to - // no permissions at all. See issue #50313. - let stackptr = get_stack_start_aligned()?; - let result = mmap64( + + unsafe { + // this way someone on any unix-y OS can check that all these compile + if cfg!(all(target_os = "linux", not(target_env = "musl"))) { + install_main_guard_linux(page_size) + } else if cfg!(all(target_os = "linux", target_env = "musl")) { + install_main_guard_linux_musl(page_size) + } else if cfg!(target_os = "freebsd") { + install_main_guard_freebsd(page_size) + } else if cfg!(any(target_os = "netbsd", target_os = "openbsd")) { + install_main_guard_bsds(page_size) + } else { + install_main_guard_default(page_size) + } + } + } + + #[forbid(unsafe_op_in_unsafe_fn)] + unsafe fn install_main_guard_linux(page_size: usize) -> Option<Range<usize>> { + // Linux doesn't allocate the whole stack right away, and + // the kernel has its own stack-guard mechanism to fault + // when growing too close to an existing mapping. If we map + // our own guard, then the kernel starts enforcing a rather + // large gap above that, rendering much of the possible + // stack space useless. See #43052. + // + // Instead, we'll just note where we expect rlimit to start + // faulting, so our handler can report "stack overflow", and + // trust that the kernel's own stack guard will work. + let stackptr = stack_start_aligned(page_size)?; + let stackaddr = stackptr.addr(); + Some(stackaddr - page_size..stackaddr) + } + + #[forbid(unsafe_op_in_unsafe_fn)] + unsafe fn install_main_guard_linux_musl(_page_size: usize) -> Option<Range<usize>> { + // For the main thread, the musl's pthread_attr_getstack + // returns the current stack size, rather than maximum size + // it can eventually grow to. It cannot be used to determine + // the position of kernel's stack guard. + None + } + + #[forbid(unsafe_op_in_unsafe_fn)] + unsafe fn install_main_guard_freebsd(page_size: usize) -> Option<Range<usize>> { + // FreeBSD's stack autogrows, and optionally includes a guard page + // at the bottom. If we try to remap the bottom of the stack + // ourselves, FreeBSD's guard page moves upwards. So we'll just use + // the builtin guard page. + let stackptr = stack_start_aligned(page_size)?; + let guardaddr = stackptr.addr(); + // Technically the number of guard pages is tunable and controlled + // by the security.bsd.stack_guard_page sysctl. + // By default it is 1, checking once is enough since it is + // a boot time config value. + static PAGES: OnceLock<usize> = OnceLock::new(); + + let pages = PAGES.get_or_init(|| { + use crate::sys::weak::dlsym; + dlsym!(fn sysctlbyname(*const libc::c_char, *mut libc::c_void, *mut libc::size_t, *const libc::c_void, libc::size_t) -> libc::c_int); + let mut guard: usize = 0; + let mut size = mem::size_of_val(&guard); + let oid = c"security.bsd.stack_guard_page"; + match sysctlbyname.get() { + Some(fcn) if unsafe { + fcn(oid.as_ptr(), + ptr::addr_of_mut!(guard).cast(), + ptr::addr_of_mut!(size), + ptr::null_mut(), + 0) == 0 + } => guard, + _ => 1, + } + }); + Some(guardaddr..guardaddr + pages * page_size) + } + + #[forbid(unsafe_op_in_unsafe_fn)] + unsafe fn install_main_guard_bsds(page_size: usize) -> Option<Range<usize>> { + // OpenBSD stack already includes a guard page, and stack is + // immutable. + // NetBSD stack includes the guard page. + // + // We'll just note where we expect rlimit to start + // faulting, so our handler can report "stack overflow", and + // trust that the kernel's own stack guard will work. + let stackptr = stack_start_aligned(page_size)?; + let stackaddr = stackptr.addr(); + Some(stackaddr - page_size..stackaddr) + } + + #[forbid(unsafe_op_in_unsafe_fn)] + unsafe fn install_main_guard_default(page_size: usize) -> Option<Range<usize>> { + // Reallocate the last page of the stack. + // This ensures SIGBUS will be raised on + // stack overflow. + // Systems which enforce strict PAX MPROTECT do not allow + // to mprotect() a mapping with less restrictive permissions + // than the initial mmap() used, so we mmap() here with + // read/write permissions and only then mprotect() it to + // no permissions at all. See issue #50313. + let stackptr = stack_start_aligned(page_size)?; + let result = unsafe { + mmap64( stackptr, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0, - ); - if result != stackptr || result == MAP_FAILED { - panic!("failed to allocate a guard page: {}", io::Error::last_os_error()); - } + ) + }; + if result != stackptr || result == MAP_FAILED { + panic!("failed to allocate a guard page: {}", io::Error::last_os_error()); + } - let result = mprotect(stackptr, page_size, PROT_NONE); - if result != 0 { - panic!("failed to protect the guard page: {}", io::Error::last_os_error()); - } + let result = unsafe { mprotect(stackptr, page_size, PROT_NONE) }; + if result != 0 { + panic!("failed to protect the guard page: {}", io::Error::last_os_error()); + } - let guardaddr = stackptr.addr(); + let guardaddr = stackptr.addr(); - Some(guardaddr..guardaddr + page_size) - } + Some(guardaddr..guardaddr + page_size) } #[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))] diff --git a/library/std/src/sys/sync/once/mod.rs b/library/std/src/sys/sync/once/mod.rs index 61b29713fa1..0e38937b121 100644 --- a/library/std/src/sys/sync/once/mod.rs +++ b/library/std/src/sys/sync/once/mod.rs @@ -9,6 +9,7 @@ cfg_if::cfg_if! { if #[cfg(any( + all(target_os = "windows", not(target_vendor="win7")), target_os = "linux", target_os = "android", all(target_arch = "wasm32", target_feature = "atomics"), diff --git a/rustfmt.toml b/rustfmt.toml index e060fd8fe8b..8c1d3b94f19 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -31,7 +31,6 @@ ignore = [ "library/backtrace", "library/portable-simd", "library/stdarch", - "compiler/rustc_codegen_gcc", "src/doc/book", "src/doc/edition-guide", "src/doc/embedded-book", @@ -50,4 +49,8 @@ ignore = [ # These are ignored by a standard cargo fmt run. "compiler/rustc_codegen_cranelift/scripts", "compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs", # uses edition 2024 + "compiler/rustc_codegen_gcc/tests", + # Code automatically generated and included. + "compiler/rustc_codegen_gcc/src/intrinsic/archs.rs", + "compiler/rustc_codegen_gcc/example", ] diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 40f42171411..fad4b5af095 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -27,8 +27,11 @@ do shift done +# MacOS reports "arm64" while Linux reports "aarch64". Commonize this. +machine="$(uname -m | sed 's/arm64/aarch64/')" + script_dir="`dirname $script`" -docker_dir="${script_dir}/host-$(uname -m)" +docker_dir="${script_dir}/host-${machine}" ci_dir="`dirname $script_dir`" src_dir="`dirname $ci_dir`" root_dir="`dirname $src_dir`" @@ -68,7 +71,7 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then # Include the architecture in the hash key, since our Linux CI does not # only run in x86_64 machines. - uname -m >> $hash_key + echo "$machine" >> $hash_key # Include cache version. Can be used to manually bust the Docker cache. echo "2" >> $hash_key @@ -178,7 +181,7 @@ elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then build \ --rm \ -t rust-ci \ - -f "host-$(uname -m)/$image/Dockerfile" \ + -f "host-${machine}/$image/Dockerfile" \ - else echo Invalid image: $image @@ -201,7 +204,7 @@ else else continue fi - echo "Note: the current host architecture is $(uname -m)" + echo "Note: the current host architecture is $machine" done exit 1 diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md index dce50ebf29c..f42b9cb5978 100644 --- a/src/doc/style-guide/src/README.md +++ b/src/doc/style-guide/src/README.md @@ -117,8 +117,7 @@ fn baz() {} In various cases, the default Rust style specifies to sort things. If not otherwise specified, such sorting should be "version sorting", which ensures that (for instance) `x8` comes before `x16` even though the character `1` comes -before the character `8`. (If not otherwise specified, version-sorting is -lexicographical.) +before the character `8`. For the purposes of the Rust style, to compare two strings for version-sorting: @@ -132,12 +131,13 @@ For the purposes of the Rust style, to compare two strings for version-sorting: these strings, treat the chunks as equal (moving on to the next chunk) but remember which string had more leading zeroes. - To compare two chunks if both are not numeric, compare them by Unicode - character lexicographically, except that `_` (underscore) sorts immediately - after ` ` (space) but before any other character. (This treats underscore as - a word separator, as commonly used in identifiers.) - - If the use of version sorting specifies further modifiers, such as sorting - non-lowercase before lowercase, apply those modifiers to the lexicographic - sort in this step. + character lexicographically, with two exceptions: + - `_` (underscore) sorts immediately after ` ` (space) but before any other + character. (This treats underscore as a word separator, as commonly used in + identifiers.) + - Unless otherwise specified, version-sorting should sort non-lowercase + characters (characters that can start an `UpperCamelCase` identifier) + before lowercase characters. - If the comparison reaches the end of the string and considers each pair of chunks equal: - If one of the numeric comparisons noted the earliest point at which one @@ -157,7 +157,17 @@ leading zeroes. As an example, version-sorting will sort the following strings in the order given: -- `_ZYWX` +- `_ZYXW` +- `_abcd` +- `A2` +- `ABCD` +- `Z_YXW` +- `ZY_XW` +- `ZY_XW` +- `ZYXW` +- `ZYXW_` +- `a1` +- `abcd` - `u_zzz` - `u8` - `u16` @@ -190,11 +200,7 @@ given: - `x86_64` - `x86_128` - `x87` -- `Z_YWX` -- `ZY_WX` -- `ZYW_X` -- `ZYWX` -- `ZYWX_` +- `zyxw` ### [Module-level items](items.md) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index c0628691b77..8e1b1d80fb6 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -489,10 +489,8 @@ foo::{ A *group* of imports is a set of imports on the same or sequential lines. One or more blank lines or other items (e.g., a function) separate groups of imports. -Within a group of imports, imports must be version-sorted, except that -non-lowercase characters (characters that can start an `UpperCamelCase` -identifier) must be sorted before lowercase characters. Groups of imports must -not be merged or re-ordered. +Within a group of imports, imports must be version-sorted. Groups of imports +must not be merged or re-ordered. E.g., input: @@ -520,9 +518,7 @@ re-ordering. ### Ordering list import Names in a list import must be version-sorted, except that: -- `self` and `super` always come first if present, -- non-lowercase characters (characters that can start an `UpperCamelCase` - identifier) must be sorted before lowercase characters, and +- `self` and `super` always come first if present, and - groups and glob imports always come last if present. This applies recursively. For example, `a::*` comes before `b::a` but `a::b` diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 4c0ba75d261..cb8b82e8bde 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -15,6 +15,7 @@ --desktop-sidebar-width: 200px; --src-sidebar-width: 300px; --desktop-sidebar-z-index: 100; + --sidebar-elems-left-padding: 24px; } /* See FiraSans-LICENSE.txt for the Fira Sans license. */ @@ -559,8 +560,11 @@ ul.block, .block li { .sidebar > h2 a { display: block; padding: 0.25rem; /* 4px */ - margin-left: -0.25rem; margin-right: 0.25rem; + /* extend click target to far edge of screen (mile wide bar) */ + border-left: solid var(--sidebar-elems-left-padding) transparent; + margin-left: calc(-0.25rem - var(--sidebar-elems-left-padding)); + background-clip: border-box; } .sidebar h2 { @@ -578,7 +582,7 @@ ul.block, .block li { .sidebar-elems, .sidebar > .version, .sidebar > h2 { - padding-left: 24px; + padding-left: var(--sidebar-elems-left-padding); } .sidebar a { @@ -632,13 +636,56 @@ ul.block, .block li { .sidebar-crate .logo-container { /* The logo is expected to have 8px "slop" along its edges, so we can optically center it. */ - margin: 0 -16px 0 -16px; + margin: 0 calc(-16px - var(--sidebar-elems-left-padding)); + padding: 0 var(--sidebar-elems-left-padding); text-align: center; } +.sidebar-crate .logo-container img { + /* When in a horizontal logo lockup, the highlight color of the crate name menu item + extends underneath the actual logo (in a vertical lockup, that background highlight + extends to the left edge of the screen). + + To prevent a weird-looking colored band from appearing under the logo, cover it up + with the sidebar's background. Additionally, the crate name extends slightly above + the logo, so that its highlight has a bit of space to let the ascenders breath while + also having those ascenders meet exactly with the top of the logo. + + In ANSI art, make it look like this: + | ┌─────┐ + | (R) │ std │ + | └─────┘ + + Not like this (which would happen without the z-index): + | ┌────────┐ + | (│ std │ + | └────────┘ + + Not like this (which would happen without the background): + | ┌────────┐ + | (R) std │ + | └────────┘ + + Nor like this (which would happen without the negative margin): + | ─────────┐ + | (R) │ std │ + | └─────┘ + */ + margin-top: -16px; + border-top: solid 16px transparent; + box-sizing: content-box; + position: relative; + background-color: var(--sidebar-background-color); + background-clip: border-box; + z-index: 1; +} + .sidebar-crate h2 a { display: block; - margin: 0 calc(-24px + 0.25rem) 0 -0.2rem; + /* extend click target to far edge of screen (mile wide bar) */ + border-left: solid var(--sidebar-elems-left-padding) transparent; + background-clip: border-box; + margin: 0 calc(-24px + 0.25rem) 0 calc(-0.2rem - var(--sidebar-elems-left-padding)); /* Align the sidebar crate link with the search bar, which have different font sizes. diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 09225ac3246..6f5505e8a63 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -235,7 +235,7 @@ impl<'tcx> NonCopyConst<'tcx> { fn is_value_unfrozen_raw( cx: &LateContext<'tcx>, - result: Result<Option<ty::ValTree<'tcx>>, ErrorHandled>, + result: Result<Result<ty::ValTree<'tcx>, Ty<'tcx>>, ErrorHandled>, ty: Ty<'tcx>, ) -> bool { result.map_or_else( diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index b15705e8965..e6a45f57de6 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -61,7 +61,7 @@ pub use env::{env_var, env_var_os}; pub use run::{cmd, run, run_fail, run_with_args}; /// Helpers for checking target information. -pub use targets::{is_darwin, is_msvc, is_windows, target, uname}; +pub use targets::{is_darwin, is_msvc, is_windows, llvm_components_contain, target, uname}; /// Helpers for building names of output artifacts that are potentially target-specific. pub use artifact_names::{ diff --git a/src/tools/run-make-support/src/targets.rs b/src/tools/run-make-support/src/targets.rs index 42d4a45680d..5dcb0b83430 100644 --- a/src/tools/run-make-support/src/targets.rs +++ b/src/tools/run-make-support/src/targets.rs @@ -28,6 +28,13 @@ pub fn is_darwin() -> bool { target().contains("darwin") } +/// Check if `component` is within `LLVM_COMPONENTS` +#[must_use] +pub fn llvm_components_contain(component: &str) -> bool { + // `LLVM_COMPONENTS` is a space-separated list of words + env_var("LLVM_COMPONENTS").split_whitespace().find(|s| s == &component).is_some() +} + /// Run `uname`. This assumes that `uname` is available on the platform! #[track_caller] #[must_use] diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 282b615c5bf..745f00c4f52 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -1,5 +1,4 @@ run-make/archive-duplicate-names/Makefile -run-make/atomic-lock-free/Makefile run-make/branch-protection-check-IBT/Makefile run-make/c-dynamic-dylib/Makefile run-make/c-dynamic-rlib/Makefile @@ -24,13 +23,8 @@ run-make/emit-to-stdout/Makefile run-make/export-executable-symbols/Makefile run-make/extern-diff-internal-name/Makefile run-make/extern-flag-disambiguates/Makefile -run-make/extern-fn-explicit-align/Makefile run-make/extern-fn-generic/Makefile -run-make/extern-fn-mangle/Makefile run-make/extern-fn-reachable/Makefile -run-make/extern-fn-struct-passing-abi/Makefile -run-make/extern-fn-with-extern-types/Makefile -run-make/extern-fn-with-packed-struct/Makefile run-make/extern-fn-with-union/Makefile run-make/extern-multiple-copies/Makefile run-make/extern-multiple-copies2/Makefile @@ -45,7 +39,6 @@ run-make/issue-107094/Makefile run-make/issue-14698/Makefile run-make/issue-15460/Makefile run-make/issue-22131/Makefile -run-make/issue-25581/Makefile run-make/issue-26006/Makefile run-make/issue-28595/Makefile run-make/issue-33329/Makefile @@ -67,7 +60,6 @@ run-make/link-path-order/Makefile run-make/linkage-attr-on-static/Makefile run-make/long-linker-command-lines-cmd-exe/Makefile run-make/long-linker-command-lines/Makefile -run-make/longjmp-across-rust/Makefile run-make/lto-linkage-used-attr/Makefile run-make/lto-no-link-whole-rlib/Makefile run-make/lto-smoke-c/Makefile @@ -110,7 +102,6 @@ run-make/simd-ffi/Makefile run-make/split-debuginfo/Makefile run-make/stable-symbol-names/Makefile run-make/static-dylib-by-default/Makefile -run-make/static-extern-type/Makefile run-make/staticlib-blank-lib/Makefile run-make/staticlib-dylib-linkage/Makefile run-make/symbol-mangling-hashed/Makefile diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 3c7284ce6db..57310977704 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -3449,7 +3449,6 @@ ui/pattern/issue-6449.rs ui/pattern/issue-66270-pat-struct-parser-recovery.rs ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs ui/pattern/issue-67776-match-same-name-enum-variant-refs.rs -ui/pattern/issue-68393-let-pat-assoc-constant.rs ui/pattern/issue-72565.rs ui/pattern/issue-72574-1.rs ui/pattern/issue-72574-2.rs diff --git a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-abort.diff index 801e28ff2f4..069a82b9521 100644 --- a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-abort.diff @@ -3,8 +3,8 @@ fn non_const() -> usize { let mut _0: usize; - let _1: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; - let mut _2: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; + let _1: fn() -> usize {std::intrinsics::size_of::<T>}; + let mut _2: fn() -> usize {std::intrinsics::size_of::<T>}; scope 1 { debug size_of_t => _1; } diff --git a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff index 801e28ff2f4..069a82b9521 100644 --- a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff @@ -3,8 +3,8 @@ fn non_const() -> usize { let mut _0: usize; - let _1: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; - let mut _2: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; + let _1: fn() -> usize {std::intrinsics::size_of::<T>}; + let mut _2: fn() -> usize {std::intrinsics::size_of::<T>}; scope 1 { debug size_of_t => _1; } diff --git a/tests/run-make/atomic-lock-free/Makefile b/tests/run-make/atomic-lock-free/Makefile deleted file mode 100644 index 37e59624a25..00000000000 --- a/tests/run-make/atomic-lock-free/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -include ../tools.mk - -# This tests ensure that atomic types are never lowered into runtime library calls that are not -# guaranteed to be lock-free. - -all: -ifeq ($(UNAME),Linux) -ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86) - $(RUSTC) --target=i686-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add - $(RUSTC) --target=x86_64-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add -endif -ifeq ($(filter arm,$(LLVM_COMPONENTS)),arm) - $(RUSTC) --target=arm-unknown-linux-gnueabi atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add - $(RUSTC) --target=arm-unknown-linux-gnueabihf atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add - $(RUSTC) --target=armv7-unknown-linux-gnueabihf atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add - $(RUSTC) --target=thumbv7neon-unknown-linux-gnueabihf atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add -endif -ifeq ($(filter aarch64,$(LLVM_COMPONENTS)),aarch64) - $(RUSTC) --target=aarch64-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add -endif -ifeq ($(filter mips,$(LLVM_COMPONENTS)),mips) - $(RUSTC) --target=mips-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add - $(RUSTC) --target=mipsel-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add -endif -ifeq ($(filter powerpc,$(LLVM_COMPONENTS)),powerpc) - $(RUSTC) --target=powerpc-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add - $(RUSTC) --target=powerpc-unknown-linux-gnuspe atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add - $(RUSTC) --target=powerpc64-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add - $(RUSTC) --target=powerpc64le-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add -endif -ifeq ($(filter systemz,$(LLVM_COMPONENTS)),systemz) - $(RUSTC) --target=s390x-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add -endif -endif diff --git a/tests/run-make/atomic-lock-free/rmake.rs b/tests/run-make/atomic-lock-free/rmake.rs new file mode 100644 index 00000000000..77e136e8487 --- /dev/null +++ b/tests/run-make/atomic-lock-free/rmake.rs @@ -0,0 +1,52 @@ +// This tests ensure that atomic types are never lowered into runtime library calls that are not +// guaranteed to be lock-free. + +//@ only-linux + +use run_make_support::{llvm_components_contain, llvm_readobj, rustc}; + +fn compile(target: &str) { + rustc().input("atomic_lock_free.rs").target(target).run(); +} + +fn check() { + llvm_readobj() + .symbols() + .input("libatomic_lock_free.rlib") + .run() + .assert_stdout_not_contains("__atomic_fetch_add"); +} + +fn compile_and_check(target: &str) { + compile(target); + check(); +} + +fn main() { + if llvm_components_contain("x86") { + compile_and_check("i686-unknown-linux-gnu"); + compile_and_check("x86_64-unknown-linux-gnu"); + } + if llvm_components_contain("arm") { + compile_and_check("arm-unknown-linux-gnueabi"); + compile_and_check("arm-unknown-linux-gnueabihf"); + compile_and_check("armv7-unknown-linux-gnueabihf"); + compile_and_check("thumbv7neon-unknown-linux-gnueabihf"); + } + if llvm_components_contain("aarch64") { + compile_and_check("aarch64-unknown-linux-gnu"); + } + if llvm_components_contain("mips") { + compile_and_check("mips-unknown-linux-gnu"); + compile_and_check("mipsel-unknown-linux-gnu"); + } + if llvm_components_contain("powerpc") { + compile_and_check("powerpc-unknown-linux-gnu"); + compile_and_check("powerpc-unknown-linux-gnuspe"); + compile_and_check("powerpc64-unknown-linux-gnu"); + compile_and_check("powerpc64le-unknown-linux-gnu"); + } + if llvm_components_contain("systemz") { + compile_and_check("s390x-unknown-linux-gnu"); + } +} diff --git a/tests/run-make/extern-fn-explicit-align/Makefile b/tests/run-make/extern-fn-explicit-align/Makefile deleted file mode 100644 index 3cbbf383996..00000000000 --- a/tests/run-make/extern-fn-explicit-align/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: $(call NATIVE_STATICLIB,test) - $(RUSTC) test.rs - $(call RUN,test) || exit 1 diff --git a/tests/run-make/extern-fn-explicit-align/rmake.rs b/tests/run-make/extern-fn-explicit-align/rmake.rs new file mode 100644 index 00000000000..fb153f92103 --- /dev/null +++ b/tests/run-make/extern-fn-explicit-align/rmake.rs @@ -0,0 +1,17 @@ +// The compiler's rules of alignment for indirectly passed values in a 16-byte aligned argument, +// in a C external function, used to be arbitrary. Unexpected behavior would occasionally occur +// and cause memory corruption. This was fixed in #112157, streamlining the way alignment occurs, +// and this test reproduces the case featured in the issue, checking that it compiles and executes +// successfully. +// See https://github.com/rust-lang/rust/issues/80127 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, run, rustc}; + +fn main() { + build_native_static_lib("test"); + rustc().input("test.rs").run(); + run("test"); +} diff --git a/tests/run-make/extern-fn-mangle/Makefile b/tests/run-make/extern-fn-mangle/Makefile deleted file mode 100644 index 3cbbf383996..00000000000 --- a/tests/run-make/extern-fn-mangle/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: $(call NATIVE_STATICLIB,test) - $(RUSTC) test.rs - $(call RUN,test) || exit 1 diff --git a/tests/run-make/extern-fn-mangle/rmake.rs b/tests/run-make/extern-fn-mangle/rmake.rs new file mode 100644 index 00000000000..3db8b2a0db0 --- /dev/null +++ b/tests/run-make/extern-fn-mangle/rmake.rs @@ -0,0 +1,16 @@ +// In this test, the functions foo() and bar() must avoid being mangled, as +// the external C function depends on them to return the correct sum of 3 + 5 = 8. +// This test therefore checks that the compiled and executed program respects the +// #[no_mangle] flags successfully. +// See https://github.com/rust-lang/rust/pull/15831 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, run, rustc}; + +fn main() { + build_native_static_lib("test"); + rustc().input("test.rs").run(); + run("test"); +} diff --git a/tests/run-make/extern-fn-slice-no-ice/rmake.rs b/tests/run-make/extern-fn-slice-no-ice/rmake.rs new file mode 100644 index 00000000000..1f1bbd33127 --- /dev/null +++ b/tests/run-make/extern-fn-slice-no-ice/rmake.rs @@ -0,0 +1,17 @@ +// Slices were broken when implicated in foreign-function interface (FFI) with +// a C library, with something as simple as measuring the length or returning +// an item at a certain index of a slice would cause an internal compiler error (ICE). +// This was fixed in #25653, and this test checks that slices in Rust-C FFI can be part +// of a program that compiles and executes successfully. +// See https://github.com/rust-lang/rust/issues/25581 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, run, rustc}; + +fn main() { + build_native_static_lib("test"); + rustc().input("test.rs").run(); + run("test"); +} diff --git a/tests/run-make/issue-25581/test.c b/tests/run-make/extern-fn-slice-no-ice/test.c index 52fbf78510a..52fbf78510a 100644 --- a/tests/run-make/issue-25581/test.c +++ b/tests/run-make/extern-fn-slice-no-ice/test.c diff --git a/tests/run-make/issue-25581/test.rs b/tests/run-make/extern-fn-slice-no-ice/test.rs index ba6749c9722..ba6749c9722 100644 --- a/tests/run-make/issue-25581/test.rs +++ b/tests/run-make/extern-fn-slice-no-ice/test.rs diff --git a/tests/run-make/extern-fn-struct-passing-abi/Makefile b/tests/run-make/extern-fn-struct-passing-abi/Makefile deleted file mode 100644 index 3cbbf383996..00000000000 --- a/tests/run-make/extern-fn-struct-passing-abi/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: $(call NATIVE_STATICLIB,test) - $(RUSTC) test.rs - $(call RUN,test) || exit 1 diff --git a/tests/run-make/extern-fn-struct-passing-abi/rmake.rs b/tests/run-make/extern-fn-struct-passing-abi/rmake.rs new file mode 100644 index 00000000000..5c4ddb7f58e --- /dev/null +++ b/tests/run-make/extern-fn-struct-passing-abi/rmake.rs @@ -0,0 +1,16 @@ +// Functions with more than 6 arguments using foreign function interfaces (FFI) with C libraries +// would have their arguments unexpectedly swapped, causing unexpected behaviour in Rust-C FFI +// programs. This test compiles and executes Rust code with bulky functions of up to 7 arguments +// and uses assertions to check for unexpected swaps. +// See https://github.com/rust-lang/rust/issues/25594 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, run, rustc}; + +fn main() { + build_native_static_lib("test"); + rustc().input("test.rs").run(); + run("test"); +} diff --git a/tests/run-make/extern-fn-with-extern-types/Makefile b/tests/run-make/extern-fn-with-extern-types/Makefile deleted file mode 100644 index 07ec503aaae..00000000000 --- a/tests/run-make/extern-fn-with-extern-types/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: $(call NATIVE_STATICLIB,ctest) - $(RUSTC) test.rs - $(call RUN,test) || exit 1 diff --git a/tests/run-make/extern-fn-with-extern-types/rmake.rs b/tests/run-make/extern-fn-with-extern-types/rmake.rs new file mode 100644 index 00000000000..02521ae2cdb --- /dev/null +++ b/tests/run-make/extern-fn-with-extern-types/rmake.rs @@ -0,0 +1,16 @@ +// This test checks the functionality of foreign function interface (FFI) where Rust +// must call upon a C library defining functions, where these functions also use custom +// types defined by the C file. In addition to compilation being successful, the binary +// should also successfully execute. +// See https://github.com/rust-lang/rust/pull/44295 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, run, rustc}; + +fn main() { + build_native_static_lib("ctest"); + rustc().input("test.rs").run(); + run("test"); +} diff --git a/tests/run-make/extern-fn-with-packed-struct/Makefile b/tests/run-make/extern-fn-with-packed-struct/Makefile deleted file mode 100644 index 3cbbf383996..00000000000 --- a/tests/run-make/extern-fn-with-packed-struct/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: $(call NATIVE_STATICLIB,test) - $(RUSTC) test.rs - $(call RUN,test) || exit 1 diff --git a/tests/run-make/extern-fn-with-packed-struct/rmake.rs b/tests/run-make/extern-fn-with-packed-struct/rmake.rs new file mode 100644 index 00000000000..e6d8cecd24a --- /dev/null +++ b/tests/run-make/extern-fn-with-packed-struct/rmake.rs @@ -0,0 +1,17 @@ +// Packed structs, in C, occupy less bytes in memory, but are more +// vulnerable to alignment errors. Passing them around in a Rust-C foreign +// function interface (FFI) would cause unexpected behavior, until this was +// fixed in #16584. This test checks that a Rust program with a C library +// compiles and executes successfully, even with usage of a packed struct. +// See https://github.com/rust-lang/rust/issues/16574 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, run, rustc}; + +fn main() { + build_native_static_lib("test"); + rustc().input("test.rs").run(); + run("test"); +} diff --git a/tests/run-make/issue-25581/Makefile b/tests/run-make/issue-25581/Makefile deleted file mode 100644 index 3cbbf383996..00000000000 --- a/tests/run-make/issue-25581/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: $(call NATIVE_STATICLIB,test) - $(RUSTC) test.rs - $(call RUN,test) || exit 1 diff --git a/tests/run-make/longjmp-across-rust/Makefile b/tests/run-make/longjmp-across-rust/Makefile deleted file mode 100644 index 5fd2d4f855f..00000000000 --- a/tests/run-make/longjmp-across-rust/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: $(call NATIVE_STATICLIB,foo) - $(RUSTC) main.rs - $(call RUN,main) diff --git a/tests/run-make/longjmp-across-rust/rmake.rs b/tests/run-make/longjmp-across-rust/rmake.rs new file mode 100644 index 00000000000..90a527077d2 --- /dev/null +++ b/tests/run-make/longjmp-across-rust/rmake.rs @@ -0,0 +1,18 @@ +// longjmp, an error handling function used in C, is useful +// for jumping out of nested call chains... but it used to accidentally +// trigger Rust's cleanup system in a way that caused an unexpected abortion +// of the program. After this was fixed in #48572, this test compiles and executes +// a program that jumps between Rust and its C library, with longjmp included. For +// the test to succeed, no unexpected abortion should occur. +// See https://github.com/rust-lang/rust/pull/48572 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, run, rustc}; + +fn main() { + build_native_static_lib("foo"); + rustc().input("main.rs").run(); + run("main"); +} diff --git a/tests/run-make/static-extern-type/Makefile b/tests/run-make/static-extern-type/Makefile deleted file mode 100644 index 77897154322..00000000000 --- a/tests/run-make/static-extern-type/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: $(call NATIVE_STATICLIB,define-foo) - $(RUSTC) -ldefine-foo use-foo.rs - $(call RUN,use-foo) || exit 1 diff --git a/tests/run-make/static-extern-type/rmake.rs b/tests/run-make/static-extern-type/rmake.rs new file mode 100644 index 00000000000..d30153f9c68 --- /dev/null +++ b/tests/run-make/static-extern-type/rmake.rs @@ -0,0 +1,16 @@ +// Static variables coming from a C library through foreign function interface (FFI) are unsized +// at compile time - and assuming they are sized used to cause an internal compiler error (ICE). +// After this was fixed in #58192, this test checks that external statics can be safely used in +// a program that both compiles and executes successfully. +// See https://github.com/rust-lang/rust/issues/57876 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, run, rustc}; + +fn main() { + build_native_static_lib("define-foo"); + rustc().arg("-ldefine-foo").input("use-foo.rs").run(); + run("use-foo"); +} diff --git a/tests/rustdoc-gui/huge-logo.goml b/tests/rustdoc-gui/huge-logo.goml index e4e5cb1ec74..d207ab5bb37 100644 --- a/tests/rustdoc-gui/huge-logo.goml +++ b/tests/rustdoc-gui/huge-logo.goml @@ -3,9 +3,11 @@ go-to: "file://" + |DOC_PATH| + "/huge_logo/index.html" set-window-size: (1280, 1024) -// offsetWidth = width of sidebar -assert-property: (".sidebar-crate .logo-container", {"offsetWidth": "48", "offsetHeight": 48}) -assert-property: (".sidebar-crate .logo-container img", {"offsetWidth": "48", "offsetHeight": 48}) +// offsetWidth = width of sidebar + left and right margins +assert-property: (".sidebar-crate .logo-container", {"offsetWidth": "96", "offsetHeight": 48}) +// offsetWidth = width of sidebar, offsetHeight = height + top padding +assert-property: (".sidebar-crate .logo-container img", {"offsetWidth": "48", "offsetHeight": 64}) +assert-css: (".sidebar-crate .logo-container img", {"border-top-width": "16px", "margin-top": "-16px"}) set-window-size: (400, 600) // offset = size + margin diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml index 452545958f9..56453517a55 100644 --- a/tests/rustdoc-gui/sidebar.goml +++ b/tests/rustdoc-gui/sidebar.goml @@ -179,3 +179,18 @@ assert-property: (".sidebar .sidebar-crate h2 a", { "offsetTop": |index_sidebar_y|, "offsetLeft": |index_sidebar_x|, }) + +// Check that the sidebar links touch the left side of the box +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +assert-position: (".sidebar .block a", {"x": -4}) +assert-position: (".sidebar-crate > h2 > a", {"x": -3}) + +// Check that the main sidebar links touch the left side of the box +// but the crate name doesn't, because the logo takes that space +go-to: "file://" + |DOC_PATH| + "/huge_logo/index.html" +assert-position: (".sidebar .block a", {"x": -4}) +// when side-by-side, it's not line wrapped +assert-position-false: (".sidebar-crate > h2 > a", {"x": -3}) +// when line-wrapped, see that it becomes flush-left again +drag-and-drop: ((205, 100), (108, 100)) +assert-position: (".sidebar-crate > h2 > a", {"x": -3}) diff --git a/tests/rustdoc-ui/ice-unresolved-import-100241.stderr b/tests/rustdoc-ui/ice-unresolved-import-100241.stderr new file mode 100644 index 00000000000..57fbbb59c8d --- /dev/null +++ b/tests/rustdoc-ui/ice-unresolved-import-100241.stderr @@ -0,0 +1,11 @@ +error[E0432]: unresolved import `inner` + --> $DIR/ice-unresolved-import-100241.rs:9:13 + | +LL | pub use inner::S; + | ^^^^^ maybe a missing crate `inner`? + | + = help: consider adding `extern crate inner` to use the `inner` crate + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0432`. diff --git a/tests/rustdoc-ui/invalid_associated_const.stderr b/tests/rustdoc-ui/invalid_associated_const.stderr index 6e5ddc44982..66f8ffe6d72 100644 --- a/tests/rustdoc-ui/invalid_associated_const.stderr +++ b/tests/rustdoc-ui/invalid_associated_const.stderr @@ -6,8 +6,9 @@ LL | type A: S<C<X = 0i32> = 34>; | help: consider removing this associated item binding | -LL | type A: S<C<X = 0i32> = 34>; - | ~~~~~~~~~~ +LL - type A: S<C<X = 0i32> = 34>; +LL + type A: S<C = 34>; + | error[E0229]: associated item constraints are not allowed here --> $DIR/invalid_associated_const.rs:4:17 @@ -18,8 +19,9 @@ LL | type A: S<C<X = 0i32> = 34>; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider removing this associated item binding | -LL | type A: S<C<X = 0i32> = 34>; - | ~~~~~~~~~~ +LL - type A: S<C<X = 0i32> = 34>; +LL + type A: S<C = 34>; + | error: aborting due to 2 previous errors diff --git a/tests/rustdoc-ui/issue-102467.stderr b/tests/rustdoc-ui/issue-102467.stderr index 99f91102319..5fcdba782e7 100644 --- a/tests/rustdoc-ui/issue-102467.stderr +++ b/tests/rustdoc-ui/issue-102467.stderr @@ -6,8 +6,9 @@ LL | type A: S<C<X = 0i32> = 34>; | help: consider removing this associated item binding | -LL | type A: S<C<X = 0i32> = 34>; - | ~~~~~~~~~~ +LL - type A: S<C<X = 0i32> = 34>; +LL + type A: S<C = 34>; + | error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102467.rs:7:17 @@ -18,8 +19,9 @@ LL | type A: S<C<X = 0i32> = 34>; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider removing this associated item binding | -LL | type A: S<C<X = 0i32> = 34>; - | ~~~~~~~~~~ +LL - type A: S<C<X = 0i32> = 34>; +LL + type A: S<C = 34>; + | error: aborting due to 2 previous errors diff --git a/tests/ui/anon-params/anon-params-denied-2018.stderr b/tests/ui/anon-params/anon-params-denied-2018.stderr index bb60c898e81..2d6356ffcb1 100644 --- a/tests/ui/anon-params/anon-params-denied-2018.stderr +++ b/tests/ui/anon-params/anon-params-denied-2018.stderr @@ -48,7 +48,7 @@ LL | fn foo_with_qualified_path(<Bar as T>::Baz); help: explicitly ignore the parameter name | LL | fn foo_with_qualified_path(_: <Bar as T>::Baz); - | ~~~~~~~~~~~~~~~~~~ + | ++ error: expected one of `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)` --> $DIR/anon-params-denied-2018.rs:15:56 @@ -60,7 +60,7 @@ LL | fn foo_with_qualified_path_and_ref(&<Bar as T>::Baz); help: explicitly ignore the parameter name | LL | fn foo_with_qualified_path_and_ref(_: &<Bar as T>::Baz); - | ~~~~~~~~~~~~~~~~~~~ + | ++ error: expected one of `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `,` --> $DIR/anon-params-denied-2018.rs:18:57 @@ -72,7 +72,7 @@ LL | fn foo_with_multiple_qualified_paths(<Bar as T>::Baz, <Bar as T>::Baz); help: explicitly ignore the parameter name | LL | fn foo_with_multiple_qualified_paths(_: <Bar as T>::Baz, <Bar as T>::Baz); - | ~~~~~~~~~~~~~~~~~~ + | ++ error: expected one of `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)` --> $DIR/anon-params-denied-2018.rs:18:74 @@ -84,7 +84,7 @@ LL | fn foo_with_multiple_qualified_paths(<Bar as T>::Baz, <Bar as T>::Baz); help: explicitly ignore the parameter name | LL | fn foo_with_multiple_qualified_paths(<Bar as T>::Baz, _: <Bar as T>::Baz); - | ~~~~~~~~~~~~~~~~~~ + | ++ error: expected one of `:`, `@`, or `|`, found `,` --> $DIR/anon-params-denied-2018.rs:22:36 diff --git a/tests/ui/argument-suggestions/basic.stderr b/tests/ui/argument-suggestions/basic.stderr index ea58ca97cfa..2d52df21233 100644 --- a/tests/ui/argument-suggestions/basic.stderr +++ b/tests/ui/argument-suggestions/basic.stderr @@ -33,7 +33,7 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/basic.rs:22:5 | LL | missing(); - | ^^^^^^^-- an argument of type `u32` is missing + | ^^^^^^^-- argument #1 of type `u32` is missing | note: function defined here --> $DIR/basic.rs:15:4 @@ -86,7 +86,7 @@ error[E0057]: this function takes 1 argument but 0 arguments were supplied --> $DIR/basic.rs:27:5 | LL | closure(); - | ^^^^^^^-- an argument is missing + | ^^^^^^^-- argument #1 is missing | note: closure defined here --> $DIR/basic.rs:26:19 diff --git a/tests/ui/argument-suggestions/display-is-suggestable.stderr b/tests/ui/argument-suggestions/display-is-suggestable.stderr index bde87475e0a..eea88c3e78d 100644 --- a/tests/ui/argument-suggestions/display-is-suggestable.stderr +++ b/tests/ui/argument-suggestions/display-is-suggestable.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/display-is-suggestable.rs:6:5 | LL | foo(); - | ^^^-- an argument of type `&dyn std::fmt::Display + Send` is missing + | ^^^-- argument #1 of type `&dyn std::fmt::Display + Send` is missing | note: function defined here --> $DIR/display-is-suggestable.rs:3:4 diff --git a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr index f6bc84c1203..47fbfc98c67 100644 --- a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr +++ b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr @@ -8,7 +8,7 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/extern-fn-arg-names.rs:7:5 | LL | dstfn(1); - | ^^^^^--- an argument is missing + | ^^^^^--- argument #2 is missing | note: function defined here --> $DIR/extern-fn-arg-names.rs:2:8 diff --git a/tests/ui/argument-suggestions/extra_arguments.stderr b/tests/ui/argument-suggestions/extra_arguments.stderr index dec3da75186..8c95cc86a27 100644 --- a/tests/ui/argument-suggestions/extra_arguments.stderr +++ b/tests/ui/argument-suggestions/extra_arguments.stderr @@ -19,9 +19,9 @@ error[E0061]: this function takes 0 arguments but 2 arguments were supplied --> $DIR/extra_arguments.rs:20:3 | LL | empty(1, 1); - | ^^^^^ - - unexpected argument of type `{integer}` + | ^^^^^ - - unexpected argument #2 of type `{integer}` | | - | unexpected argument of type `{integer}` + | unexpected argument #1 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:1:4 @@ -38,7 +38,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:22:3 | LL | one_arg(1, 1); - | ^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^ - unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 @@ -55,7 +55,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:23:3 | LL | one_arg(1, ""); - | ^^^^^^^ -- unexpected argument of type `&'static str` + | ^^^^^^^ -- unexpected argument #2 of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:2:4 @@ -72,9 +72,9 @@ error[E0061]: this function takes 1 argument but 3 arguments were supplied --> $DIR/extra_arguments.rs:24:3 | LL | one_arg(1, "", 1.0); - | ^^^^^^^ -- --- unexpected argument of type `{float}` + | ^^^^^^^ -- --- unexpected argument #3 of type `{float}` | | - | unexpected argument of type `&'static str` + | unexpected argument #2 of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:2:4 @@ -91,7 +91,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:26:3 | LL | two_arg_same(1, 1, 1); - | ^^^^^^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^^^^^^ - unexpected argument #3 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:3:4 @@ -108,7 +108,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:27:3 | LL | two_arg_same(1, 1, 1.0); - | ^^^^^^^^^^^^ --- unexpected argument of type `{float}` + | ^^^^^^^^^^^^ --- unexpected argument #3 of type `{float}` | note: function defined here --> $DIR/extra_arguments.rs:3:4 @@ -125,7 +125,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:29:3 | LL | two_arg_diff(1, 1, ""); - | ^^^^^^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^^^^^^ - unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 @@ -142,7 +142,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:30:3 | LL | two_arg_diff(1, "", ""); - | ^^^^^^^^^^^^ -- unexpected argument of type `&'static str` + | ^^^^^^^^^^^^ -- unexpected argument #3 of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:4:4 @@ -159,9 +159,9 @@ error[E0061]: this function takes 2 arguments but 4 arguments were supplied --> $DIR/extra_arguments.rs:31:3 | LL | two_arg_diff(1, 1, "", ""); - | ^^^^^^^^^^^^ - -- unexpected argument of type `&'static str` + | ^^^^^^^^^^^^ - -- unexpected argument #4 of type `&'static str` | | - | unexpected argument of type `{integer}` + | unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 @@ -178,9 +178,9 @@ error[E0061]: this function takes 2 arguments but 4 arguments were supplied --> $DIR/extra_arguments.rs:32:3 | LL | two_arg_diff(1, "", 1, ""); - | ^^^^^^^^^^^^ - -- unexpected argument of type `&'static str` + | ^^^^^^^^^^^^ - -- unexpected argument #4 of type `&'static str` | | - | unexpected argument of type `{integer}` + | unexpected argument #3 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 @@ -197,7 +197,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:35:3 | LL | two_arg_same(1, 1, ""); - | ^^^^^^^^^^^^ -- unexpected argument of type `&'static str` + | ^^^^^^^^^^^^ -- unexpected argument #3 of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:3:4 @@ -214,7 +214,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:36:3 | LL | two_arg_diff(1, 1, ""); - | ^^^^^^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^^^^^^ - unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 @@ -234,7 +234,7 @@ LL | two_arg_same( | ^^^^^^^^^^^^ ... LL | "" - | -- unexpected argument of type `&'static str` + | -- unexpected argument #3 of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:3:4 @@ -255,7 +255,7 @@ LL | two_arg_diff( | ^^^^^^^^^^^^ LL | 1, LL | 1, - | - unexpected argument of type `{integer}` + | - unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 @@ -271,12 +271,12 @@ error[E0061]: this function takes 0 arguments but 2 arguments were supplied --> $DIR/extra_arguments.rs:8:9 | LL | empty($x, 1); - | ^^^^^ - unexpected argument of type `{integer}` + | ^^^^^ - unexpected argument #2 of type `{integer}` ... LL | foo!(1, ~); | ---------- | | | - | | unexpected argument of type `{integer}` + | | unexpected argument #1 of type `{integer}` | in this macro invocation | note: function defined here @@ -290,12 +290,12 @@ error[E0061]: this function takes 0 arguments but 2 arguments were supplied --> $DIR/extra_arguments.rs:14:9 | LL | empty(1, $y); - | ^^^^^ - unexpected argument of type `{integer}` + | ^^^^^ - unexpected argument #1 of type `{integer}` ... LL | foo!(~, 1); | ---------- | | | - | | unexpected argument of type `{integer}` + | | unexpected argument #2 of type `{integer}` | in this macro invocation | note: function defined here @@ -314,8 +314,8 @@ LL | empty($x, $y); LL | foo!(1, 1); | ---------- | | | | - | | | unexpected argument of type `{integer}` - | | unexpected argument of type `{integer}` + | | | unexpected argument #2 of type `{integer}` + | | unexpected argument #1 of type `{integer}` | in this macro invocation | note: function defined here @@ -329,7 +329,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:53:3 | LL | one_arg(1, panic!()); - | ^^^^^^^ -------- unexpected argument + | ^^^^^^^ -------- unexpected argument #2 | note: function defined here --> $DIR/extra_arguments.rs:2:4 @@ -346,7 +346,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:54:3 | LL | one_arg(panic!(), 1); - | ^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^ - unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 @@ -363,7 +363,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:55:3 | LL | one_arg(stringify!($e), 1); - | ^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^ - unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 @@ -380,7 +380,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:60:3 | LL | one_arg(for _ in 1.. {}, 1); - | ^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^ - unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 diff --git a/tests/ui/argument-suggestions/issue-100478.stderr b/tests/ui/argument-suggestions/issue-100478.stderr index e4304988f9b..94709f0ebc6 100644 --- a/tests/ui/argument-suggestions/issue-100478.stderr +++ b/tests/ui/argument-suggestions/issue-100478.stderr @@ -4,8 +4,8 @@ error[E0061]: this function takes 3 arguments but 1 argument was supplied LL | three_diff(T2::new(0)); | ^^^^^^^^^^------------ | || - | |an argument of type `T1` is missing - | an argument of type `T3` is missing + | |argument #1 of type `T1` is missing + | argument #3 of type `T3` is missing | note: function defined here --> $DIR/issue-100478.rs:30:4 @@ -63,7 +63,7 @@ LL | foo( | ^^^ ... LL | p3, p4, p5, p6, p7, p8, - | -- an argument of type `Arc<T2>` is missing + | -- argument #2 of type `Arc<T2>` is missing | note: function defined here --> $DIR/issue-100478.rs:29:4 diff --git a/tests/ui/argument-suggestions/issue-101097.stderr b/tests/ui/argument-suggestions/issue-101097.stderr index 061f510144b..6e21f19ab4f 100644 --- a/tests/ui/argument-suggestions/issue-101097.stderr +++ b/tests/ui/argument-suggestions/issue-101097.stderr @@ -4,7 +4,7 @@ error[E0061]: this function takes 6 arguments but 7 arguments were supplied LL | f(C, A, A, A, B, B, C); | ^ - - - - expected `C`, found `B` | | | | - | | | unexpected argument of type `A` + | | | unexpected argument #4 of type `A` | | expected `B`, found `A` | expected `A`, found `C` | @@ -64,8 +64,8 @@ error[E0308]: arguments to this function are incorrect LL | f(A, A, D, D, B, B); | ^ - - ---- two arguments of type `C` and `C` are missing | | | - | | unexpected argument of type `D` - | unexpected argument of type `D` + | | unexpected argument #4 of type `D` + | unexpected argument #3 of type `D` | note: function defined here --> $DIR/issue-101097.rs:6:4 diff --git a/tests/ui/argument-suggestions/issue-109425.stderr b/tests/ui/argument-suggestions/issue-109425.stderr index 1514f1cb487..bfe007793d4 100644 --- a/tests/ui/argument-suggestions/issue-109425.stderr +++ b/tests/ui/argument-suggestions/issue-109425.stderr @@ -2,9 +2,9 @@ error[E0061]: this function takes 0 arguments but 2 arguments were supplied --> $DIR/issue-109425.rs:10:5 | LL | f(0, 1,); // f() - | ^ - - unexpected argument of type `{integer}` + | ^ - - unexpected argument #2 of type `{integer}` | | - | unexpected argument of type `{integer}` + | unexpected argument #1 of type `{integer}` | note: function defined here --> $DIR/issue-109425.rs:3:4 @@ -21,9 +21,9 @@ error[E0061]: this function takes 1 argument but 3 arguments were supplied --> $DIR/issue-109425.rs:12:5 | LL | i(0, 1, 2,); // i(0,) - | ^ - - unexpected argument of type `{integer}` + | ^ - - unexpected argument #3 of type `{integer}` | | - | unexpected argument of type `{integer}` + | unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/issue-109425.rs:4:4 @@ -40,9 +40,9 @@ error[E0061]: this function takes 1 argument but 3 arguments were supplied --> $DIR/issue-109425.rs:14:5 | LL | i(0, 1, 2); // i(0) - | ^ - - unexpected argument of type `{integer}` + | ^ - - unexpected argument #3 of type `{integer}` | | - | unexpected argument of type `{integer}` + | unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/issue-109425.rs:4:4 @@ -59,9 +59,9 @@ error[E0061]: this function takes 2 arguments but 4 arguments were supplied --> $DIR/issue-109425.rs:16:5 | LL | is(0, 1, 2, ""); // is(0, "") - | ^^ - - unexpected argument of type `{integer}` + | ^^ - - unexpected argument #3 of type `{integer}` | | - | unexpected argument of type `{integer}` + | unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/issue-109425.rs:5:4 @@ -78,9 +78,9 @@ error[E0061]: this function takes 1 argument but 3 arguments were supplied --> $DIR/issue-109425.rs:18:5 | LL | s(0, 1, ""); // s("") - | ^ - - unexpected argument of type `{integer}` + | ^ - - unexpected argument #2 of type `{integer}` | | - | unexpected argument of type `{integer}` + | unexpected argument #1 of type `{integer}` | note: function defined here --> $DIR/issue-109425.rs:6:4 diff --git a/tests/ui/argument-suggestions/issue-109831.stderr b/tests/ui/argument-suggestions/issue-109831.stderr index 7b9a3c9ef2c..12be0887121 100644 --- a/tests/ui/argument-suggestions/issue-109831.stderr +++ b/tests/ui/argument-suggestions/issue-109831.stderr @@ -29,7 +29,7 @@ error[E0061]: this function takes 3 arguments but 4 arguments were supplied --> $DIR/issue-109831.rs:7:5 | LL | f(A, A, B, C); - | ^ - - - unexpected argument + | ^ - - - unexpected argument #4 | | | | | expected `B`, found `A` | expected `B`, found `A` diff --git a/tests/ui/argument-suggestions/issue-112507.stderr b/tests/ui/argument-suggestions/issue-112507.stderr index 17bde4d9743..908ed35c669 100644 --- a/tests/ui/argument-suggestions/issue-112507.stderr +++ b/tests/ui/argument-suggestions/issue-112507.stderr @@ -4,12 +4,12 @@ error[E0061]: this enum variant takes 1 argument but 4 arguments were supplied LL | let _a = Value::Float( | ^^^^^^^^^^^^ LL | 0, - | - unexpected argument of type `{integer}` + | - unexpected argument #1 of type `{integer}` LL | None, LL | None, - | ---- unexpected argument of type `Option<_>` + | ---- unexpected argument #3 of type `Option<_>` LL | 0, - | - unexpected argument of type `{integer}` + | - unexpected argument #4 of type `{integer}` | note: tuple variant defined here --> $DIR/issue-112507.rs:2:5 diff --git a/tests/ui/argument-suggestions/issue-96638.stderr b/tests/ui/argument-suggestions/issue-96638.stderr index 887bf82a2f6..6492acbad94 100644 --- a/tests/ui/argument-suggestions/issue-96638.stderr +++ b/tests/ui/argument-suggestions/issue-96638.stderr @@ -4,7 +4,7 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied LL | f(&x, ""); | ^ -- -- expected `usize`, found `&str` | | - | an argument of type `usize` is missing + | argument #1 of type `usize` is missing | note: function defined here --> $DIR/issue-96638.rs:1:4 diff --git a/tests/ui/argument-suggestions/issue-97484.stderr b/tests/ui/argument-suggestions/issue-97484.stderr index 6bdb734fddf..a7708f6e0d7 100644 --- a/tests/ui/argument-suggestions/issue-97484.stderr +++ b/tests/ui/argument-suggestions/issue-97484.stderr @@ -2,11 +2,11 @@ error[E0061]: this function takes 4 arguments but 7 arguments were supplied --> $DIR/issue-97484.rs:12:5 | LL | foo(&&A, B, C, D, E, F, G); - | ^^^ - - - - unexpected argument of type `F` + | ^^^ - - - - unexpected argument #6 of type `F` | | | | | | | expected `&E`, found `E` - | | unexpected argument of type `C` - | unexpected argument of type `B` + | | unexpected argument #3 of type `C` + | unexpected argument #2 of type `B` | note: function defined here --> $DIR/issue-97484.rs:9:4 diff --git a/tests/ui/argument-suggestions/issue-98894.stderr b/tests/ui/argument-suggestions/issue-98894.stderr index 72e6fec27e6..93e604c3101 100644 --- a/tests/ui/argument-suggestions/issue-98894.stderr +++ b/tests/ui/argument-suggestions/issue-98894.stderr @@ -2,7 +2,7 @@ error[E0057]: this function takes 2 arguments but 1 argument was supplied --> $DIR/issue-98894.rs:2:5 | LL | (|_, ()| ())(if true {} else {return;}); - | ^^^^^^^^^^^^--------------------------- an argument of type `()` is missing + | ^^^^^^^^^^^^--------------------------- argument #2 of type `()` is missing | note: closure defined here --> $DIR/issue-98894.rs:2:6 diff --git a/tests/ui/argument-suggestions/issue-98897.stderr b/tests/ui/argument-suggestions/issue-98897.stderr index eed3964559a..671e3d99d85 100644 --- a/tests/ui/argument-suggestions/issue-98897.stderr +++ b/tests/ui/argument-suggestions/issue-98897.stderr @@ -2,7 +2,7 @@ error[E0057]: this function takes 2 arguments but 1 argument was supplied --> $DIR/issue-98897.rs:2:5 | LL | (|_, ()| ())([return, ()]); - | ^^^^^^^^^^^^-------------- an argument of type `()` is missing + | ^^^^^^^^^^^^-------------- argument #2 of type `()` is missing | note: closure defined here --> $DIR/issue-98897.rs:2:6 diff --git a/tests/ui/argument-suggestions/issue-99482.stderr b/tests/ui/argument-suggestions/issue-99482.stderr index 9c83b47f8b6..be407874615 100644 --- a/tests/ui/argument-suggestions/issue-99482.stderr +++ b/tests/ui/argument-suggestions/issue-99482.stderr @@ -2,7 +2,7 @@ error[E0057]: this function takes 2 arguments but 1 argument was supplied --> $DIR/issue-99482.rs:3:14 | LL | let _f = f(main); - | ^ ---- an argument of type `()` is missing + | ^ ---- argument #1 of type `()` is missing | note: closure defined here --> $DIR/issue-99482.rs:2:13 diff --git a/tests/ui/argument-suggestions/missing_arguments.stderr b/tests/ui/argument-suggestions/missing_arguments.stderr index ba9ece040be..3a27a51d032 100644 --- a/tests/ui/argument-suggestions/missing_arguments.stderr +++ b/tests/ui/argument-suggestions/missing_arguments.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/missing_arguments.rs:10:3 | LL | one_arg(); - | ^^^^^^^-- an argument of type `i32` is missing + | ^^^^^^^-- argument #1 of type `i32` is missing | note: function defined here --> $DIR/missing_arguments.rs:1:4 @@ -34,7 +34,7 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/missing_arguments.rs:15:3 | LL | two_same( 1 ); - | ^^^^^^^^----------------- an argument of type `i32` is missing + | ^^^^^^^^----------------- argument #2 of type `i32` is missing | note: function defined here --> $DIR/missing_arguments.rs:2:4 @@ -66,7 +66,7 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/missing_arguments.rs:17:3 | LL | two_diff( 1 ); - | ^^^^^^^^----------------- an argument of type `f32` is missing + | ^^^^^^^^----------------- argument #2 of type `f32` is missing | note: function defined here --> $DIR/missing_arguments.rs:3:4 @@ -82,7 +82,7 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/missing_arguments.rs:18:3 | LL | two_diff( 1.0 ); - | ^^^^^^^^ --- an argument of type `i32` is missing + | ^^^^^^^^ --- argument #1 of type `i32` is missing | note: function defined here --> $DIR/missing_arguments.rs:3:4 @@ -130,7 +130,7 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied --> $DIR/missing_arguments.rs:23:3 | LL | three_same( 1, 1 ); - | ^^^^^^^^^^------------------------- an argument of type `i32` is missing + | ^^^^^^^^^^------------------------- argument #3 of type `i32` is missing | note: function defined here --> $DIR/missing_arguments.rs:4:4 @@ -146,7 +146,7 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied --> $DIR/missing_arguments.rs:26:3 | LL | three_diff( 1.0, "" ); - | ^^^^^^^^^^ --- an argument of type `i32` is missing + | ^^^^^^^^^^ --- argument #1 of type `i32` is missing | note: function defined here --> $DIR/missing_arguments.rs:5:4 @@ -162,7 +162,7 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied --> $DIR/missing_arguments.rs:27:3 | LL | three_diff( 1, "" ); - | ^^^^^^^^^^ -- an argument of type `f32` is missing + | ^^^^^^^^^^ -- argument #2 of type `f32` is missing | note: function defined here --> $DIR/missing_arguments.rs:5:4 @@ -178,7 +178,7 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied --> $DIR/missing_arguments.rs:28:3 | LL | three_diff( 1, 1.0 ); - | ^^^^^^^^^^------------------------- an argument of type `&str` is missing + | ^^^^^^^^^^------------------------- argument #3 of type `&str` is missing | note: function defined here --> $DIR/missing_arguments.rs:5:4 @@ -212,8 +212,8 @@ error[E0061]: this function takes 3 arguments but 1 argument was supplied LL | three_diff( 1.0 ); | ^^^^^^^^^^------------------------- | | | - | | an argument of type `i32` is missing - | an argument of type `&str` is missing + | | argument #1 of type `i32` is missing + | argument #3 of type `&str` is missing | note: function defined here --> $DIR/missing_arguments.rs:5:4 diff --git a/tests/ui/argument-suggestions/mixed_cases.stderr b/tests/ui/argument-suggestions/mixed_cases.stderr index c645dd38179..bec5d4dc16b 100644 --- a/tests/ui/argument-suggestions/mixed_cases.stderr +++ b/tests/ui/argument-suggestions/mixed_cases.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/mixed_cases.rs:10:3 | LL | two_args(1, "", X {}); - | ^^^^^^^^ -- ---- unexpected argument of type `X` + | ^^^^^^^^ -- ---- unexpected argument #3 of type `X` | | | expected `f32`, found `&str` | @@ -21,10 +21,10 @@ error[E0061]: this function takes 3 arguments but 4 arguments were supplied --> $DIR/mixed_cases.rs:11:3 | LL | three_args(1, "", X {}, ""); - | ^^^^^^^^^^ -- ---- -- unexpected argument of type `&'static str` + | ^^^^^^^^^^ -- ---- -- unexpected argument #4 of type `&'static str` | | | - | | unexpected argument of type `X` - | an argument of type `f32` is missing + | | unexpected argument #3 of type `X` + | argument #2 of type `f32` is missing | note: function defined here --> $DIR/mixed_cases.rs:6:4 @@ -43,7 +43,7 @@ LL | three_args(1, X {}); | ^^^^^^^^^^--------- | | | | | expected `f32`, found `X` - | an argument of type `&str` is missing + | argument #3 of type `&str` is missing | note: function defined here --> $DIR/mixed_cases.rs:6:4 @@ -59,9 +59,9 @@ error[E0308]: arguments to this function are incorrect --> $DIR/mixed_cases.rs:17:3 | LL | three_args(1, "", X {}); - | ^^^^^^^^^^ -- ---- unexpected argument of type `X` + | ^^^^^^^^^^ -- ---- unexpected argument #3 of type `X` | | - | an argument of type `f32` is missing + | argument #2 of type `f32` is missing | note: function defined here --> $DIR/mixed_cases.rs:6:4 @@ -98,7 +98,7 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied LL | three_args("", 1); | ^^^^^^^^^^ -- - | | | - | | an argument of type `f32` is missing + | | argument #2 of type `f32` is missing | | expected `&str`, found `{integer}` | expected `i32`, found `&'static str` | diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr index dc293945eb6..730f20cfb88 100644 --- a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr +++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr @@ -32,7 +32,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:10:5 | LL | add_one(2, 2); - | ^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^ - unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:1:4 @@ -49,7 +49,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:11:5 | LL | add_one(no_such_local, 10); - | ^^^^^^^ ------------- unexpected argument + | ^^^^^^^ ------------- unexpected argument #1 | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:1:4 @@ -66,7 +66,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:13:5 | LL | add_one(10, no_such_local); - | ^^^^^^^ ------------- unexpected argument + | ^^^^^^^ ------------- unexpected argument #2 | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:1:4 @@ -83,7 +83,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:15:5 | LL | add_two(10, no_such_local, 10); - | ^^^^^^^ ------------- unexpected argument + | ^^^^^^^ ------------- unexpected argument #2 | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:5:4 @@ -100,7 +100,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:17:5 | LL | add_two(no_such_local, 10, 10); - | ^^^^^^^ ------------- unexpected argument + | ^^^^^^^ ------------- unexpected argument #1 | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:5:4 @@ -117,7 +117,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:19:5 | LL | add_two(10, 10, no_such_local); - | ^^^^^^^ ------------- unexpected argument + | ^^^^^^^ ------------- unexpected argument #3 | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:5:4 diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr deleted file mode 100644 index 1ccf9febd4b..00000000000 --- a/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0158]: associated consts cannot be referenced in patterns - --> $DIR/associated-const-type-parameter-arms.rs:20:9 - | -LL | A::X => println!("A::X"), - | ^^^^ - -error[E0158]: associated consts cannot be referenced in patterns - --> $DIR/associated-const-type-parameter-arms.rs:22:9 - | -LL | B::X => println!("B::X"), - | ^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arms.rs b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs index 3f260d84e4c..b5798adc71c 100644 --- a/tests/ui/associated-consts/associated-const-type-parameter-arms.rs +++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs @@ -18,12 +18,18 @@ impl Foo for Def { pub fn test<A: Foo, B: Foo>(arg: EFoo) { match arg { A::X => println!("A::X"), - //~^ error: associated consts cannot be referenced in patterns [E0158] + //~^ error: constant pattern depends on a generic parameter B::X => println!("B::X"), - //~^ error: associated consts cannot be referenced in patterns [E0158] + //~^ error: constant pattern depends on a generic parameter _ => (), } } +pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) { + //~^ ERROR constant pattern depends on a generic parameter + let A::X = arg; + //~^ ERROR constant pattern depends on a generic parameter +} + fn main() { } diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr new file mode 100644 index 00000000000..adc8f399207 --- /dev/null +++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr @@ -0,0 +1,27 @@ +error[E0158]: constant pattern depends on a generic parameter + --> $DIR/associated-const-type-parameter-pattern.rs:20:9 + | +LL | A::X => println!("A::X"), + | ^^^^ + +error[E0158]: constant pattern depends on a generic parameter + --> $DIR/associated-const-type-parameter-pattern.rs:22:9 + | +LL | B::X => println!("B::X"), + | ^^^^ + +error[E0158]: constant pattern depends on a generic parameter + --> $DIR/associated-const-type-parameter-pattern.rs:30:9 + | +LL | let A::X = arg; + | ^^^^ + +error[E0158]: constant pattern depends on a generic parameter + --> $DIR/associated-const-type-parameter-pattern.rs:28:48 + | +LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) { + | ^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/associated-consts/issue-102335-const.stderr b/tests/ui/associated-consts/issue-102335-const.stderr index dc1631220e2..cf96c8cf8eb 100644 --- a/tests/ui/associated-consts/issue-102335-const.stderr +++ b/tests/ui/associated-consts/issue-102335-const.stderr @@ -6,8 +6,9 @@ LL | type A: S<C<X = 0i32> = 34>; | help: consider removing this associated item binding | -LL | type A: S<C<X = 0i32> = 34>; - | ~~~~~~~~~~ +LL - type A: S<C<X = 0i32> = 34>; +LL + type A: S<C = 34>; + | error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-const.rs:4:17 @@ -18,8 +19,9 @@ LL | type A: S<C<X = 0i32> = 34>; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider removing this associated item binding | -LL | type A: S<C<X = 0i32> = 34>; - | ~~~~~~~~~~ +LL - type A: S<C<X = 0i32> = 34>; +LL + type A: S<C = 34>; + | error: aborting due to 2 previous errors diff --git a/tests/ui/associated-inherent-types/issue-109768.stderr b/tests/ui/associated-inherent-types/issue-109768.stderr index e960f4fb5d1..e71551f9e73 100644 --- a/tests/ui/associated-inherent-types/issue-109768.stderr +++ b/tests/ui/associated-inherent-types/issue-109768.stderr @@ -34,7 +34,7 @@ error[E0061]: this struct takes 1 argument but 0 arguments were supplied --> $DIR/issue-109768.rs:10:56 | LL | const WRAPPED_ASSOC_3: Wrapper<Self::AssocType3> = Wrapper(); - | ^^^^^^^-- an argument is missing + | ^^^^^^^-- argument #1 is missing | note: tuple struct defined here --> $DIR/issue-109768.rs:3:8 diff --git a/tests/ui/associated-type-bounds/issue-102335-ty.stderr b/tests/ui/associated-type-bounds/issue-102335-ty.stderr index cd585f7f7d8..259b0ca00e1 100644 --- a/tests/ui/associated-type-bounds/issue-102335-ty.stderr +++ b/tests/ui/associated-type-bounds/issue-102335-ty.stderr @@ -6,8 +6,9 @@ LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint | help: consider removing this associated item binding | -LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint - | ~~~~~~~~~~~ +LL - type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint +LL + type A: S<C = ()>; // Just one erroneous equality constraint + | error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-ty.rs:2:17 @@ -18,8 +19,9 @@ LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider removing this associated item binding | -LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint - | ~~~~~~~~~~~ +LL - type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint +LL + type A: S<C = ()>; // Just one erroneous equality constraint + | error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-ty.rs:8:17 @@ -29,8 +31,9 @@ LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equal | help: consider removing this associated item binding | -LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints - | ~~~~~~~~~~ +LL - type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints +LL + type A: S<C<X = i32> = ()>; // More than one erroneous equality constraints + | error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-ty.rs:8:17 @@ -41,8 +44,9 @@ LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equal = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider removing this associated item binding | -LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints - | ~~~~~~~~~~ +LL - type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints +LL + type A: S<C<X = i32> = ()>; // More than one erroneous equality constraints + | error: aborting due to 4 previous errors diff --git a/tests/ui/associated-type-bounds/no-gat-position.stderr b/tests/ui/associated-type-bounds/no-gat-position.stderr index 39a2f89f9ac..03dc752c533 100644 --- a/tests/ui/associated-type-bounds/no-gat-position.stderr +++ b/tests/ui/associated-type-bounds/no-gat-position.stderr @@ -6,8 +6,9 @@ LL | fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>; | help: consider removing this associated item constraint | -LL | fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>; - | ~~~~~~~~~~~ +LL - fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>; +LL + fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>; + | error: aborting due to 1 previous error diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr index dde7036231e..e9fd8503296 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr @@ -13,12 +13,12 @@ error: future cannot be sent between threads safely LL | is_send(foo::<T>()); | ^^^^^^^^^^ future returned by `foo` is not `Send` | - = help: within `impl Future<Output = Result<(), ()>>`, the trait `Send` is not implemented for `impl Future<Output = Result<(), ()>> { <T as Foo>::method() }`, which is required by `impl Future<Output = Result<(), ()>>: Send` + = help: within `impl Future<Output = Result<(), ()>>`, the trait `Send` is not implemented for `impl Future<Output = Result<(), ()>> { <T as Foo>::method(..) }`, which is required by `impl Future<Output = Result<(), ()>>: Send` note: future is not `Send` as it awaits another future which is not `Send` --> $DIR/basic.rs:13:5 | LL | T::method().await?; - | ^^^^^^^^^^^ await occurs here on type `impl Future<Output = Result<(), ()>> { <T as Foo>::method() }`, which is not `Send` + | ^^^^^^^^^^^ await occurs here on type `impl Future<Output = Result<(), ()>> { <T as Foo>::method(..) }`, which is not `Send` note: required by a bound in `is_send` --> $DIR/basic.rs:17:20 | diff --git a/tests/ui/associated-type-bounds/return-type-notation/display.rs b/tests/ui/associated-type-bounds/return-type-notation/display.rs new file mode 100644 index 00000000000..c5be2ca00ea --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/display.rs @@ -0,0 +1,25 @@ +#![feature(return_type_notation)] +//~^ WARN the feature `return_type_notation` is incomplete + +trait Trait {} +fn needs_trait(_: impl Trait) {} + +trait Assoc { + fn method() -> impl Sized; + fn method_with_lt() -> impl Sized; + fn method_with_ty<T>() -> impl Sized; + fn method_with_ct<const N: usize>() -> impl Sized; +} + +fn foo<T: Assoc>(t: T) { + needs_trait(T::method()); + //~^ ERROR the trait bound + needs_trait(T::method_with_lt()); + //~^ ERROR the trait bound + needs_trait(T::method_with_ty()); + //~^ ERROR the trait bound + needs_trait(T::method_with_ct()); + //~^ ERROR the trait bound +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/display.stderr b/tests/ui/associated-type-bounds/return-type-notation/display.stderr new file mode 100644 index 00000000000..4915ec1aa83 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/display.stderr @@ -0,0 +1,78 @@ +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/display.rs:1:12 + | +LL | #![feature(return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the trait bound `impl Sized { <T as Assoc>::method(..) }: Trait` is not satisfied + --> $DIR/display.rs:15:17 + | +LL | needs_trait(T::method()); + | ----------- ^^^^^^^^^^^ the trait `Trait` is not implemented for `impl Sized { <T as Assoc>::method(..) }` + | | + | required by a bound introduced by this call + | +note: required by a bound in `needs_trait` + --> $DIR/display.rs:5:24 + | +LL | fn needs_trait(_: impl Trait) {} + | ^^^^^ required by this bound in `needs_trait` + +error[E0277]: the trait bound `impl Sized { <T as Assoc>::method_with_lt(..) }: Trait` is not satisfied + --> $DIR/display.rs:17:17 + | +LL | needs_trait(T::method_with_lt()); + | ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `impl Sized { <T as Assoc>::method_with_lt(..) }` + | | + | required by a bound introduced by this call + | +note: required by a bound in `needs_trait` + --> $DIR/display.rs:5:24 + | +LL | fn needs_trait(_: impl Trait) {} + | ^^^^^ required by this bound in `needs_trait` + +error[E0277]: the trait bound `impl Sized: Trait` is not satisfied + --> $DIR/display.rs:19:17 + | +LL | needs_trait(T::method_with_ty()); + | ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `impl Sized` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/display.rs:4:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ +note: required by a bound in `needs_trait` + --> $DIR/display.rs:5:24 + | +LL | fn needs_trait(_: impl Trait) {} + | ^^^^^ required by this bound in `needs_trait` + +error[E0277]: the trait bound `impl Sized: Trait` is not satisfied + --> $DIR/display.rs:21:17 + | +LL | needs_trait(T::method_with_ct()); + | ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `impl Sized` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/display.rs:4:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ +note: required by a bound in `needs_trait` + --> $DIR/display.rs:5:24 + | +LL | fn needs_trait(_: impl Trait) {} + | ^^^^^ required by this bound in `needs_trait` + +error: aborting due to 4 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/associated-types-eq-2.stderr b/tests/ui/associated-types/associated-types-eq-2.stderr index 69b1b533450..e5013a35d45 100644 --- a/tests/ui/associated-types/associated-types-eq-2.stderr +++ b/tests/ui/associated-types/associated-types-eq-2.stderr @@ -50,8 +50,9 @@ LL | impl Tr1<A = usize> for usize { | help: consider removing this associated item binding | -LL | impl Tr1<A = usize> for usize { - | ~~~~~~~~~~~ +LL - impl Tr1<A = usize> for usize { +LL + impl Tr1 for usize { + | error[E0046]: not all trait items implemented, missing: `A` --> $DIR/associated-types-eq-2.rs:20:1 @@ -70,8 +71,9 @@ LL | fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {} | help: consider removing this associated item binding | -LL | fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {} - | ~~~~~~~ +LL - fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {} +LL + fn baz<I: Tr1>(_x: &<I as Tr1>::A) {} + | error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied --> $DIR/associated-types-eq-2.rs:40:6 @@ -128,8 +130,9 @@ LL | impl Tr2<i32, t2 = Qux, T3 = usize> for Qux { | help: consider removing this associated item binding | -LL | impl Tr2<i32, t2 = Qux, T3 = usize> for Qux { - | ~~~~~~~~~~ +LL - impl Tr2<i32, t2 = Qux, T3 = usize> for Qux { +LL + impl Tr2<i32, T3 = usize> for Qux { + | error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied --> $DIR/associated-types-eq-2.rs:54:6 @@ -157,8 +160,9 @@ LL | impl Tr2<i32, X = Qux, Y = usize> for Bar { | help: consider removing this associated item binding | -LL | impl Tr2<i32, X = Qux, Y = usize> for Bar { - | ~~~~~~~~~ +LL - impl Tr2<i32, X = Qux, Y = usize> for Bar { +LL + impl Tr2<i32, Y = usize> for Bar { + | error[E0107]: trait takes 3 generic arguments but 2 generic arguments were supplied --> $DIR/associated-types-eq-2.rs:61:6 @@ -228,8 +232,9 @@ LL | impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux { | help: consider removing this associated item binding | -LL | impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux { - | ~~~~~~~ +LL - impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux { +LL + impl Tr3<T2 = Qux, T3 = usize> for Qux { + | error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:92:10 @@ -239,8 +244,9 @@ LL | impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar { | help: consider removing this associated item binding | -LL | impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar { - | ~~~~~~~~ +LL - impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar { +LL + impl Tr3<T2 = Qux, T3 = usize> for Bar { + | error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied --> $DIR/associated-types-eq-2.rs:98:6 @@ -268,8 +274,9 @@ LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { | help: consider removing this associated item binding | -LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { - | ~~~~~~~~~ +LL - impl Tr3<42, T2 = 42, T3 = usize> for Bar { +LL + impl Tr3<42, T3 = usize> for Bar { + | error[E0107]: trait takes 3 generic arguments but 0 generic arguments were supplied --> $DIR/associated-types-eq-2.rs:106:6 @@ -295,8 +302,9 @@ LL | impl Tr3<X = 42, Y = Qux, Z = usize> for Bar { | help: consider removing this associated item binding | -LL | impl Tr3<X = 42, Y = Qux, Z = usize> for Bar { - | ~~~~~~~ +LL - impl Tr3<X = 42, Y = Qux, Z = usize> for Bar { +LL + impl Tr3<Y = Qux, Z = usize> for Bar { + | error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied --> $DIR/associated-types-eq-2.rs:117:13 diff --git a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr index adde31b4a32..b4012d2a5b9 100644 --- a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr +++ b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr @@ -3,11 +3,6 @@ error[E0277]: the trait bound `T: Foo<usize>` is not satisfied | LL | let u: <T as Foo<usize>>::Bar = t.get_bar(); | ^ the trait `Foo<usize>` is not implemented for `T` - | -help: consider further restricting this bound - | -LL | fn f<T:Foo<isize> + Foo<usize>>(t: &T) { - | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.rs b/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.rs new file mode 100644 index 00000000000..6083cc7d96d --- /dev/null +++ b/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.rs @@ -0,0 +1,23 @@ +//@ edition:2021 +// issue: rust-lang/rust#127555 + +pub trait Foo { + fn bar<F>(&mut self, func: F) -> impl std::future::Future<Output = ()> + Send + where + F: FnMut(); +} + +struct Baz {} + +impl Foo for Baz { + async fn bar<F>(&mut self, _func: F) -> () + //~^ ERROR `F` cannot be sent between threads safely + where + F: FnMut() + Send, + //~^ ERROR impl has stricter requirements than trait + { + () + } +} + +fn main() {} diff --git a/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.stderr b/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.stderr new file mode 100644 index 00000000000..7f3cd2a5900 --- /dev/null +++ b/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.stderr @@ -0,0 +1,33 @@ +error[E0277]: `F` cannot be sent between threads safely + --> $DIR/remove-invalid-type-bound-suggest-issue-127555.rs:13:5 + | +LL | / async fn bar<F>(&mut self, _func: F) -> () +LL | | +LL | | where +LL | | F: FnMut() + Send, + | |__________________________^ `F` cannot be sent between threads safely + | +note: required by a bound in `<Baz as Foo>::bar` + --> $DIR/remove-invalid-type-bound-suggest-issue-127555.rs:16:22 + | +LL | async fn bar<F>(&mut self, _func: F) -> () + | --- required by a bound in this associated function +... +LL | F: FnMut() + Send, + | ^^^^ required by this bound in `<Baz as Foo>::bar` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/remove-invalid-type-bound-suggest-issue-127555.rs:16:22 + | +LL | / fn bar<F>(&mut self, func: F) -> impl std::future::Future<Output = ()> + Send +LL | | where +LL | | F: FnMut(); + | |___________________- definition of `bar` from trait +... +LL | F: FnMut() + Send, + | ^^^^ impl has extra requirement `F: Send` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0276, E0277. +For more information about an error, try `rustc --explain E0276`. diff --git a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr index 66819d1fcf7..80dc5fdc747 100644 --- a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr +++ b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr @@ -9,10 +9,6 @@ note: required by a bound in `<() as Actor>::on_mount` | LL | async fn on_mount(self, _: impl Inbox<&'a ()>) {} | ^^^^^^^^^^^^^ required by this bound in `<() as Actor>::on_mount` -help: consider further restricting this bound - | -LL | async fn on_mount(self, _: impl Inbox<&'a ()> + Inbox<&'a ()>) {} - | +++++++++++++++ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates --> $DIR/unconstrained-impl-region.rs:13:6 diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr index 23ede089b5a..acad8bd3791 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr +++ b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr @@ -18,8 +18,8 @@ LL | | } LL | | }); | |______^ implementation of `Send` is not general enough | - = note: `Send` would have to be implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'0>() }`, for any two lifetimes `'0` and `'1`... - = note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>() }`, for some specific lifetime `'2` + = note: `Send` would have to be implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'0>(..) }`, for any two lifetimes `'0` and `'1`... + = note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>(..) }`, for some specific lifetime `'2` error: implementation of `Send` is not general enough --> $DIR/issue-110963-early.rs:14:5 @@ -32,8 +32,8 @@ LL | | } LL | | }); | |______^ implementation of `Send` is not general enough | - = note: `Send` would have to be implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'0>() }`, for any two lifetimes `'0` and `'1`... - = note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>() }`, for some specific lifetime `'2` + = note: `Send` would have to be implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'0>(..) }`, for any two lifetimes `'0` and `'1`... + = note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>(..) }`, for some specific lifetime `'2` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr index b23dbc37a55..e061587f491 100644 --- a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr +++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr @@ -15,8 +15,9 @@ LL | impl Super1<'_, bar(..): Send> for () {} | help: consider removing this associated item constraint | -LL | impl Super1<'_, bar(..): Send> for () {} - | ~~~~~~~~~~~~~~~ +LL - impl Super1<'_, bar(..): Send> for () {} +LL + impl Super1<'_> for () {} + | error[E0046]: not all trait items implemented, missing: `bar` --> $DIR/rtn-in-impl-signature.rs:10:1 diff --git a/tests/ui/blind/blind-item-block-item-shadow.stderr b/tests/ui/blind/blind-item-block-item-shadow.stderr index 2e24ef453c2..38e3087ca34 100644 --- a/tests/ui/blind/blind-item-block-item-shadow.stderr +++ b/tests/ui/blind/blind-item-block-item-shadow.stderr @@ -10,7 +10,7 @@ LL | use foo::Bar; help: you can use `as` to change the binding name of the import | LL | use foo::Bar as OtherBar; - | ~~~~~~~~~~~~~~~~~~~~ + | +++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/blind/blind-item-item-shadow.stderr b/tests/ui/blind/blind-item-item-shadow.stderr index 84b273c7338..08f5f5b47ed 100644 --- a/tests/ui/blind/blind-item-item-shadow.stderr +++ b/tests/ui/blind/blind-item-item-shadow.stderr @@ -11,7 +11,7 @@ LL | use foo::foo; help: you can use `as` to change the binding name of the import | LL | use foo::foo as other_foo; - | ~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/moved-value-suggest-reborrow-issue-127285.fixed b/tests/ui/borrowck/moved-value-suggest-reborrow-issue-127285.fixed new file mode 100644 index 00000000000..cec52272fee --- /dev/null +++ b/tests/ui/borrowck/moved-value-suggest-reborrow-issue-127285.fixed @@ -0,0 +1,17 @@ +//@ run-rustfix + +#![allow(dead_code)] + +struct X(u32); + +impl X { + fn f(&mut self) { + generic(&mut *self); + self.0 += 1; + //~^ ERROR: use of moved value: `self` [E0382] + } +} + +fn generic<T>(_x: T) {} + +fn main() {} diff --git a/tests/ui/borrowck/moved-value-suggest-reborrow-issue-127285.rs b/tests/ui/borrowck/moved-value-suggest-reborrow-issue-127285.rs new file mode 100644 index 00000000000..dd015697fdc --- /dev/null +++ b/tests/ui/borrowck/moved-value-suggest-reborrow-issue-127285.rs @@ -0,0 +1,17 @@ +//@ run-rustfix + +#![allow(dead_code)] + +struct X(u32); + +impl X { + fn f(&mut self) { + generic(self); + self.0 += 1; + //~^ ERROR: use of moved value: `self` [E0382] + } +} + +fn generic<T>(_x: T) {} + +fn main() {} diff --git a/tests/ui/borrowck/moved-value-suggest-reborrow-issue-127285.stderr b/tests/ui/borrowck/moved-value-suggest-reborrow-issue-127285.stderr new file mode 100644 index 00000000000..3da8b6e9dff --- /dev/null +++ b/tests/ui/borrowck/moved-value-suggest-reborrow-issue-127285.stderr @@ -0,0 +1,18 @@ +error[E0382]: use of moved value: `self` + --> $DIR/moved-value-suggest-reborrow-issue-127285.rs:10:9 + | +LL | fn f(&mut self) { + | --------- move occurs because `self` has type `&mut X`, which does not implement the `Copy` trait +LL | generic(self); + | ---- value moved here +LL | self.0 += 1; + | ^^^^^^^^^^^ value used here after move + | +help: consider creating a fresh reborrow of `self` here + | +LL | generic(&mut *self); + | ++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/borrowck/mut-borrow-in-loop-2.stderr b/tests/ui/borrowck/mut-borrow-in-loop-2.stderr index 7a569d1da41..4f32df1eb24 100644 --- a/tests/ui/borrowck/mut-borrow-in-loop-2.stderr +++ b/tests/ui/borrowck/mut-borrow-in-loop-2.stderr @@ -8,19 +8,10 @@ LL | for _ in 0..3 { LL | Other::handle(value); | ^^^^^ value moved here, in previous iteration of loop | -note: consider changing this parameter type in function `handle` to borrow instead if owning the value isn't necessary - --> $DIR/mut-borrow-in-loop-2.rs:8:22 - | -LL | fn handle(value: T) -> Self; - | ------ ^ this parameter takes ownership of the value - | | - | in this function -help: consider moving the expression out of the loop so it is only moved once - | -LL ~ let mut value = Other::handle(value); -LL ~ for _ in 0..3 { -LL ~ value; +help: consider creating a fresh reborrow of `value` here | +LL | Other::handle(&mut *value); + | ++++++ help: consider creating a fresh reborrow of `value` here | LL | Other::handle(&mut *value); diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr index 4beea83d8a5..72d60a1439a 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.stderr +++ b/tests/ui/c-variadic/variadic-ffi-1.stderr @@ -24,7 +24,7 @@ error[E0060]: this function takes at least 2 arguments but 1 argument was suppli --> $DIR/variadic-ffi-1.rs:23:9 | LL | foo(1); - | ^^^--- an argument of type `u8` is missing + | ^^^--- argument #2 of type `u8` is missing | note: function defined here --> $DIR/variadic-ffi-1.rs:15:8 diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr index 2d86bf76d11..1e2adcc7d9e 100644 --- a/tests/ui/cast/ice-cast-type-with-error-124848.stderr +++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr @@ -39,7 +39,7 @@ error[E0061]: this struct takes 2 arguments but 1 argument was supplied --> $DIR/ice-cast-type-with-error-124848.rs:12:24 | LL | let mut unpinned = MyType(Cell::new(None)); - | ^^^^^^----------------- an argument is missing + | ^^^^^^----------------- argument #2 is missing | note: tuple struct defined here --> $DIR/ice-cast-type-with-error-124848.rs:7:8 diff --git a/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs b/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs index 2e7061e7c4b..ab8eec876bc 100644 --- a/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs +++ b/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs @@ -23,9 +23,20 @@ const BAR_BAZ: Foo = if 42 == 42 { Foo::Qux(CustomEq) // dead arm }; +const EMPTY: &[CustomEq] = &[]; + fn main() { + // BAR_BAZ itself is fine but the enum has other variants + // that are non-structural. Still, this should be accepted. match Foo::Qux(CustomEq) { BAR_BAZ => panic!(), _ => {} } + + // Similarly, an empty slice of a type that is non-structural + // is accepted. + match &[CustomEq] as &[CustomEq] { + EMPTY => panic!(), + _ => {}, + } } diff --git a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs index 86d971044fe..645e1418912 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.rs @@ -26,7 +26,7 @@ fn main() { match None { NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"), - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR must implement `PartialEq` _ => panic!("whoops"), } } diff --git a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr index 88b82d5004b..ed531a1fead 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr @@ -1,11 +1,8 @@ -error: to use a constant of type `NoPartialEq` in a pattern, `NoPartialEq` must be annotated with `#[derive(PartialEq)]` +error: to use a constant of type `Option<NoPartialEq>` in a pattern, the type must implement `PartialEq` --> $DIR/reject_non_partial_eq.rs:28:9 | LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"), | ^^^^^^^^^^^^^^^^^^ - | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.rs b/tests/ui/consts/invalid-inline-const-in-match-arm.rs index 0654fd82fbc..4fe4b0d33c8 100644 --- a/tests/ui/consts/invalid-inline-const-in-match-arm.rs +++ b/tests/ui/consts/invalid-inline-const-in-match-arm.rs @@ -4,5 +4,6 @@ fn main() { match () { const { (|| {})() } => {} //~^ ERROR cannot call non-const closure in constants + //~| ERROR could not evaluate constant pattern } } diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr index 7579f7f9692..0e41053a29d 100644 --- a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr +++ b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr @@ -11,6 +11,12 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable LL + #![feature(const_trait_impl)] | -error: aborting due to 1 previous error +error: could not evaluate constant pattern + --> $DIR/invalid-inline-const-in-match-arm.rs:5:9 + | +LL | const { (|| {})() } => {} + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/issue-73976-polymorphic.stderr b/tests/ui/consts/issue-73976-polymorphic.stderr index 97a5fbc5747..8a44eb9854f 100644 --- a/tests/ui/consts/issue-73976-polymorphic.stderr +++ b/tests/ui/consts/issue-73976-polymorphic.stderr @@ -1,10 +1,10 @@ -error: constant pattern depends on a generic parameter +error[E0158]: constant pattern depends on a generic parameter --> $DIR/issue-73976-polymorphic.rs:20:37 | LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) | ^^^^^^^^^^^^^^^^^^^^^ -error: constant pattern depends on a generic parameter +error[E0158]: constant pattern depends on a generic parameter --> $DIR/issue-73976-polymorphic.rs:31:42 | LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) @@ -12,3 +12,4 @@ LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/consts/issue-79137-toogeneric.stderr b/tests/ui/consts/issue-79137-toogeneric.stderr index 18bdde45e2c..de81512ec6d 100644 --- a/tests/ui/consts/issue-79137-toogeneric.stderr +++ b/tests/ui/consts/issue-79137-toogeneric.stderr @@ -1,4 +1,4 @@ -error: constant pattern depends on a generic parameter +error[E0158]: constant pattern depends on a generic parameter --> $DIR/issue-79137-toogeneric.rs:12:43 | LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE) @@ -6,3 +6,4 @@ LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE) error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/coroutine/issue-102645.stderr b/tests/ui/coroutine/issue-102645.stderr index ab5e4a8459f..1ef37d3f7d1 100644 --- a/tests/ui/coroutine/issue-102645.stderr +++ b/tests/ui/coroutine/issue-102645.stderr @@ -2,7 +2,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/issue-102645.rs:15:22 | LL | Pin::new(&mut b).resume(); - | ^^^^^^-- an argument of type `()` is missing + | ^^^^^^-- argument #1 of type `()` is missing | note: method defined here --> $SRC_DIR/core/src/ops/coroutine.rs:LL:COL diff --git a/tests/ui/duplicate/duplicate-check-macro-exports.stderr b/tests/ui/duplicate/duplicate-check-macro-exports.stderr index eff19c09062..470a516ecbc 100644 --- a/tests/ui/duplicate/duplicate-check-macro-exports.stderr +++ b/tests/ui/duplicate/duplicate-check-macro-exports.stderr @@ -11,7 +11,7 @@ LL | macro_rules! panic { () => {} } help: you can use `as` to change the binding name of the import | LL | pub use std::panic as other_panic; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0057.stderr b/tests/ui/error-codes/E0057.stderr index efd2af6d609..ef6e2908b93 100644 --- a/tests/ui/error-codes/E0057.stderr +++ b/tests/ui/error-codes/E0057.stderr @@ -2,7 +2,7 @@ error[E0057]: this function takes 1 argument but 0 arguments were supplied --> $DIR/E0057.rs:3:13 | LL | let a = f(); - | ^-- an argument is missing + | ^-- argument #1 is missing | note: closure defined here --> $DIR/E0057.rs:2:13 @@ -18,7 +18,7 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/E0057.rs:5:13 | LL | let c = f(2, 3); - | ^ - unexpected argument of type `{integer}` + | ^ - unexpected argument #2 of type `{integer}` | note: closure defined here --> $DIR/E0057.rs:2:13 diff --git a/tests/ui/error-codes/E0060.stderr b/tests/ui/error-codes/E0060.stderr index 88c1f1bbb2a..8387b15b970 100644 --- a/tests/ui/error-codes/E0060.stderr +++ b/tests/ui/error-codes/E0060.stderr @@ -2,7 +2,7 @@ error[E0060]: this function takes at least 1 argument but 0 arguments were suppl --> $DIR/E0060.rs:6:14 | LL | unsafe { printf(); } - | ^^^^^^-- an argument of type `*const u8` is missing + | ^^^^^^-- argument #1 of type `*const u8` is missing | note: function defined here --> $DIR/E0060.rs:2:8 diff --git a/tests/ui/error-codes/E0061.stderr b/tests/ui/error-codes/E0061.stderr index fa4ccbe6677..7b180c07120 100644 --- a/tests/ui/error-codes/E0061.stderr +++ b/tests/ui/error-codes/E0061.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/E0061.rs:6:5 | LL | f(0); - | ^--- an argument of type `&str` is missing + | ^--- argument #2 of type `&str` is missing | note: function defined here --> $DIR/E0061.rs:1:4 @@ -18,7 +18,7 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/E0061.rs:9:5 | LL | f2(); - | ^^-- an argument of type `u16` is missing + | ^^-- argument #1 of type `u16` is missing | note: function defined here --> $DIR/E0061.rs:3:4 diff --git a/tests/ui/error-codes/E0229.stderr b/tests/ui/error-codes/E0229.stderr index 7d9cedc3bdc..038f44e8b14 100644 --- a/tests/ui/error-codes/E0229.stderr +++ b/tests/ui/error-codes/E0229.stderr @@ -6,8 +6,9 @@ LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {} | help: consider removing this associated item binding | -LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {} - | ~~~~~~~~~ +LL - fn baz<I>(x: &<I as Foo<A = Bar>>::A) {} +LL + fn baz<I>(x: &<I as Foo>::A) {} + | error[E0229]: associated item constraints are not allowed here --> $DIR/E0229.rs:13:25 @@ -18,8 +19,9 @@ LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider removing this associated item binding | -LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {} - | ~~~~~~~~~ +LL - fn baz<I>(x: &<I as Foo<A = Bar>>::A) {} +LL + fn baz<I>(x: &<I as Foo>::A) {} + | error[E0229]: associated item constraints are not allowed here --> $DIR/E0229.rs:13:25 @@ -30,8 +32,9 @@ LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider removing this associated item binding | -LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {} - | ~~~~~~~~~ +LL - fn baz<I>(x: &<I as Foo<A = Bar>>::A) {} +LL + fn baz<I>(x: &<I as Foo>::A) {} + | error[E0277]: the trait bound `I: Foo` is not satisfied --> $DIR/E0229.rs:13:15 diff --git a/tests/ui/error-codes/E0252.stderr b/tests/ui/error-codes/E0252.stderr index efbb9ec96de..16574964eb3 100644 --- a/tests/ui/error-codes/E0252.stderr +++ b/tests/ui/error-codes/E0252.stderr @@ -10,7 +10,7 @@ LL | use bar::baz; help: you can use `as` to change the binding name of the import | LL | use bar::baz as other_baz; - | ~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0254.stderr b/tests/ui/error-codes/E0254.stderr index d89497b2804..592b8766d6b 100644 --- a/tests/ui/error-codes/E0254.stderr +++ b/tests/ui/error-codes/E0254.stderr @@ -11,7 +11,7 @@ LL | use foo::alloc; help: you can use `as` to change the binding name of the import | LL | use foo::alloc as other_alloc; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0255.stderr b/tests/ui/error-codes/E0255.stderr index e5f908217e1..b67a334f02c 100644 --- a/tests/ui/error-codes/E0255.stderr +++ b/tests/ui/error-codes/E0255.stderr @@ -11,7 +11,7 @@ LL | fn foo() {} help: you can use `as` to change the binding name of the import | LL | use bar::foo as other_foo; - | ~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/extern/issue-18819.stderr b/tests/ui/extern/issue-18819.stderr index b2cf0bad1df..6de0ebfe9ae 100644 --- a/tests/ui/extern/issue-18819.stderr +++ b/tests/ui/extern/issue-18819.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/issue-18819.rs:16:5 | LL | print_x(X); - | ^^^^^^^--- an argument of type `&str` is missing + | ^^^^^^^--- argument #2 of type `&str` is missing | note: expected `&dyn Foo<Item = bool>`, found `X` --> $DIR/issue-18819.rs:16:13 diff --git a/tests/ui/fn/issue-3044.stderr b/tests/ui/fn/issue-3044.stderr index 06254775b74..8351818dc89 100644 --- a/tests/ui/fn/issue-3044.stderr +++ b/tests/ui/fn/issue-3044.stderr @@ -5,7 +5,7 @@ LL | needlesArr.iter().fold(|x, y| { | _______________________^^^^- LL | | LL | | }); - | |______- an argument is missing + | |______- argument #2 is missing | note: method defined here --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL diff --git a/tests/ui/generic-associated-types/issue-102335-gat.stderr b/tests/ui/generic-associated-types/issue-102335-gat.stderr index b4772486e6e..bcef76290fc 100644 --- a/tests/ui/generic-associated-types/issue-102335-gat.stderr +++ b/tests/ui/generic-associated-types/issue-102335-gat.stderr @@ -6,8 +6,9 @@ LL | type A: S<C<(), i32 = ()> = ()>; | help: consider removing this associated item binding | -LL | type A: S<C<(), i32 = ()> = ()>; - | ~~~~~~~~~~ +LL - type A: S<C<(), i32 = ()> = ()>; +LL + type A: S<C<()> = ()>; + | error[E0229]: associated item constraints are not allowed here --> $DIR/issue-102335-gat.rs:2:21 @@ -18,8 +19,9 @@ LL | type A: S<C<(), i32 = ()> = ()>; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider removing this associated item binding | -LL | type A: S<C<(), i32 = ()> = ()>; - | ~~~~~~~~~~ +LL - type A: S<C<(), i32 = ()> = ()>; +LL + type A: S<C<()> = ()>; + | error: aborting due to 2 previous errors diff --git a/tests/ui/generic-associated-types/issue-91139.migrate.stderr b/tests/ui/generic-associated-types/issue-91139.migrate.stderr index 23b7bf45afb..e3b658558e3 100644 --- a/tests/ui/generic-associated-types/issue-91139.migrate.stderr +++ b/tests/ui/generic-associated-types/issue-91139.migrate.stderr @@ -1,7 +1,6 @@ error: expected identifier, found `<<` --> $DIR/issue-91139.rs:1:1 | -LL | <<<<<<< HEAD | ^^ expected identifier error: aborting due to 1 previous error diff --git a/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr b/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr index dfc6761e17e..c60c4c72a21 100644 --- a/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr +++ b/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr @@ -14,8 +14,9 @@ LL | impl Foo<T: Default> for String {} | help: declare the type parameter right after the `impl` keyword | -LL | impl<T: Default> Foo<T> for String {} - | ++++++++++++ ~ +LL - impl Foo<T: Default> for String {} +LL + impl<T: Default> Foo<T> for String {} + | error[E0229]: associated item constraints are not allowed here --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:7:10 @@ -25,8 +26,9 @@ LL | impl Foo<T: 'a + Default> for u8 {} | help: declare the type parameter right after the `impl` keyword | -LL | impl<'a, T: 'a + Default> Foo<T> for u8 {} - | +++++++++++++++++++++ ~ +LL - impl Foo<T: 'a + Default> for u8 {} +LL + impl<'a, T: 'a + Default> Foo<T> for u8 {} + | error[E0229]: associated item constraints are not allowed here --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:13:13 @@ -36,8 +38,9 @@ LL | impl<T> Foo<T: Default> for u16 {} | help: declare the type parameter right after the `impl` keyword | -LL | impl<T, T: Default> Foo<T> for u16 {} - | ++++++++++++ ~ +LL - impl<T> Foo<T: Default> for u16 {} +LL + impl<T, T: Default> Foo<T> for u16 {} + | error[E0229]: associated item constraints are not allowed here --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:17:14 @@ -47,8 +50,9 @@ LL | impl<'a> Foo<T: 'a + Default> for u32 {} | help: declare the type parameter right after the `impl` keyword | -LL | impl<'a, 'a, T: 'a + Default> Foo<T> for u32 {} - | +++++++++++++++++++++ ~ +LL - impl<'a> Foo<T: 'a + Default> for u32 {} +LL + impl<'a, 'a, T: 'a + Default> Foo<T> for u32 {} + | error[E0229]: associated item constraints are not allowed here --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:23:10 @@ -58,8 +62,9 @@ LL | impl Bar<T: Default, K: Default> for String {} | help: declare the type parameter right after the `impl` keyword | -LL | impl<T: Default> Bar<T, K: Default> for String {} - | ++++++++++++ ~ +LL - impl Bar<T: Default, K: Default> for String {} +LL + impl<T: Default> Bar<T, K: Default> for String {} + | error[E0107]: trait takes 2 generic arguments but 1 generic argument was supplied --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:27:9 @@ -87,8 +92,9 @@ LL | impl<T> Bar<T, K: Default> for u8 {} | help: declare the type parameter right after the `impl` keyword | -LL | impl<T, K: Default> Bar<T, K> for u8 {} - | ++++++++++++ ~ +LL - impl<T> Bar<T, K: Default> for u8 {} +LL + impl<T, K: Default> Bar<T, K> for u8 {} + | error: aborting due to 8 previous errors diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr index 8771de85c19..3697bd9cf02 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr @@ -9,10 +9,6 @@ note: required by a bound in `impl_hr` | LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impl_hr` -help: consider further restricting this bound - | -LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static> + for<'a> Trait<'a, '_>>() { - | +++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr index 90df487c07e..6e0ec5620da 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr @@ -9,10 +9,6 @@ note: required by a bound in `trait_bound` | LL | fn trait_bound<T: for<'a> Trait<'a>>() {} | ^^^^^^^^^^^^^^^^^ required by this bound in `trait_bound` -help: consider further restricting this bound - | -LL | fn function1<T: Trait<'static> + for<'a> Trait<'a>>() { - | +++++++++++++++++++ error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied --> $DIR/candidate-from-env-universe-err-project.rs:38:24 @@ -25,10 +21,6 @@ note: required by a bound in `projection_bound` | LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `projection_bound` -help: consider further restricting this bound - | -LL | fn function2<T: Trait<'static, Assoc = usize> + for<'a> Trait<'a>>() { - | +++++++++++++++++++ error[E0271]: type mismatch resolving `<T as Trait<'a>>::Assoc == usize` --> $DIR/candidate-from-env-universe-err-project.rs:38:24 diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr index af76377de85..dc1a4c9b983 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr @@ -11,10 +11,6 @@ note: required by a bound in `want_foo_for_any_tcx` | LL | fn want_foo_for_any_tcx<F: for<'tcx> Foo<'tcx>>(f: &F) { | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx` -help: consider further restricting this bound - | -LL | fn want_foo_for_some_tcx<'x, F: Foo<'x> + for<'tcx> Foo<'tcx>>(f: &'x F) { - | +++++++++++++++++++++ error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied --> $DIR/hrtb-higher-ranker-supertraits.rs:28:26 @@ -29,10 +25,6 @@ note: required by a bound in `want_bar_for_any_ccx` | LL | fn want_bar_for_any_ccx<B: for<'ccx> Bar<'ccx>>(b: &B) { | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` -help: consider further restricting this bound - | -LL | fn want_bar_for_some_ccx<'x, B: Bar<'x> + for<'ccx> Bar<'ccx>>(b: &B) { - | +++++++++++++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr b/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr index 99d088799fb..34d7db9b3cf 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/issue-58451.rs:12:9 | LL | f(&[f()]); - | ^-- an argument is missing + | ^-- argument #1 is missing | note: function defined here --> $DIR/issue-58451.rs:5:4 diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr index fbf82a24b50..ae449099987 100644 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr @@ -22,10 +22,6 @@ note: required by a bound in `<Bar as Foo<char>>::foo` | LL | fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> { | ^^^^^^^ required by this bound in `<Bar as Foo<char>>::foo` -help: consider further restricting this bound - | -LL | fn foo<F2: Foo<u8> + Foo<u8>>(self) -> impl Foo<u8> { - | +++++++++ error[E0276]: impl has stricter requirements than trait --> $DIR/return-dont-satisfy-bounds.rs:8:16 diff --git a/tests/ui/impl-trait/precise-capturing/hidden-type-suggestion.rs b/tests/ui/impl-trait/precise-capturing/hidden-type-suggestion.rs index e0b115b0ce4..b50780643f1 100644 --- a/tests/ui/impl-trait/precise-capturing/hidden-type-suggestion.rs +++ b/tests/ui/impl-trait/precise-capturing/hidden-type-suggestion.rs @@ -27,4 +27,16 @@ fn missing<'a, 'captured, 'not_captured, Captured>(x: &'a ()) -> impl Captures<' //~^ ERROR hidden type for } +fn no_params_yet(_: impl Sized, y: &()) -> impl Sized { +//~^ HELP add a `use<...>` bound + y +//~^ ERROR hidden type for +} + +fn yes_params_yet<'a, T>(_: impl Sized, y: &'a ()) -> impl Sized { +//~^ HELP add a `use<...>` bound + y +//~^ ERROR hidden type for +} + fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/hidden-type-suggestion.stderr b/tests/ui/impl-trait/precise-capturing/hidden-type-suggestion.stderr index 391f16d012e..1007a835894 100644 --- a/tests/ui/impl-trait/precise-capturing/hidden-type-suggestion.stderr +++ b/tests/ui/impl-trait/precise-capturing/hidden-type-suggestion.stderr @@ -62,6 +62,48 @@ help: add a `use<...>` bound to explicitly capture `'a` LL | fn missing<'a, 'captured, 'not_captured, Captured>(x: &'a ()) -> impl Captures<'captured> + use<'captured, 'a, Captured> { | ++++++++++++++++++++++++++++++ -error: aborting due to 4 previous errors +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/hidden-type-suggestion.rs:32:5 + | +LL | fn no_params_yet(_: impl Sized, y: &()) -> impl Sized { + | --- ---------- opaque type defined here + | | + | hidden type `&()` captures the anonymous lifetime defined here +LL | +LL | y + | ^ + | +note: you could use a `use<...>` bound to explicitly capture `'_`, but argument-position `impl Trait`s are not nameable + --> $DIR/hidden-type-suggestion.rs:30:21 + | +LL | fn no_params_yet(_: impl Sized, y: &()) -> impl Sized { + | ^^^^^^^^^^ +help: add a `use<...>` bound to explicitly capture `'_` after turning all argument-position `impl Trait` into type parameters, noting that this possibly affects the API of this crate + | +LL | fn no_params_yet<T: Sized>(_: T, y: &()) -> impl Sized + use<'_, T> { + | ++++++++++ ~ ++++++++++++ + +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/hidden-type-suggestion.rs:38:5 + | +LL | fn yes_params_yet<'a, T>(_: impl Sized, y: &'a ()) -> impl Sized { + | -- ---------- opaque type defined here + | | + | hidden type `&'a ()` captures the lifetime `'a` as defined here +LL | +LL | y + | ^ + | +note: you could use a `use<...>` bound to explicitly capture `'a`, but argument-position `impl Trait`s are not nameable + --> $DIR/hidden-type-suggestion.rs:36:29 + | +LL | fn yes_params_yet<'a, T>(_: impl Sized, y: &'a ()) -> impl Sized { + | ^^^^^^^^^^ +help: add a `use<...>` bound to explicitly capture `'a` after turning all argument-position `impl Trait` into type parameters, noting that this possibly affects the API of this crate + | +LL | fn yes_params_yet<'a, T, U: Sized>(_: U, y: &'a ()) -> impl Sized + use<'a, T, U> { + | ++++++++++ ~ +++++++++++++++ + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/imports/double-import.stderr b/tests/ui/imports/double-import.stderr index 73bb73e3490..15b8620909f 100644 --- a/tests/ui/imports/double-import.stderr +++ b/tests/ui/imports/double-import.stderr @@ -10,7 +10,7 @@ LL | use sub2::foo; help: you can use `as` to change the binding name of the import | LL | use sub2::foo as other_foo; - | ~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-19498.stderr b/tests/ui/imports/issue-19498.stderr index 9d26022098f..69bdb67d389 100644 --- a/tests/ui/imports/issue-19498.stderr +++ b/tests/ui/imports/issue-19498.stderr @@ -11,7 +11,7 @@ LL | mod A {} help: you can use `as` to change the binding name of the import | LL | use self::A as OtherA; - | ~~~~~~~~~~~~~~~~~ + | +++++++++ error[E0255]: the name `B` is defined multiple times --> $DIR/issue-19498.rs:5:1 @@ -26,7 +26,7 @@ LL | pub mod B {} help: you can use `as` to change the binding name of the import | LL | use self::B as OtherB; - | ~~~~~~~~~~~~~~~~~ + | +++++++++ error[E0255]: the name `D` is defined multiple times --> $DIR/issue-19498.rs:9:5 @@ -40,7 +40,7 @@ LL | mod D {} help: you can use `as` to change the binding name of the import | LL | use C::D as OtherD; - | ~~~~~~~~~~~~~~ + | +++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/imports/issue-24081.stderr b/tests/ui/imports/issue-24081.stderr index e5ed6b10a54..6ceba6c7013 100644 --- a/tests/ui/imports/issue-24081.stderr +++ b/tests/ui/imports/issue-24081.stderr @@ -11,7 +11,7 @@ LL | type Add = bool; help: you can use `as` to change the binding name of the import | LL | use std::ops::Add as OtherAdd; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++ error[E0255]: the name `Sub` is defined multiple times --> $DIR/issue-24081.rs:9:1 @@ -26,7 +26,7 @@ LL | struct Sub { x: f32 } help: you can use `as` to change the binding name of the import | LL | use std::ops::Sub as OtherSub; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++ error[E0255]: the name `Mul` is defined multiple times --> $DIR/issue-24081.rs:11:1 @@ -41,7 +41,7 @@ LL | enum Mul { A, B } help: you can use `as` to change the binding name of the import | LL | use std::ops::Mul as OtherMul; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++ error[E0255]: the name `Div` is defined multiple times --> $DIR/issue-24081.rs:13:1 @@ -56,7 +56,7 @@ LL | mod Div { } help: you can use `as` to change the binding name of the import | LL | use std::ops::Div as OtherDiv; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++ error[E0255]: the name `Rem` is defined multiple times --> $DIR/issue-24081.rs:15:1 @@ -71,7 +71,7 @@ LL | trait Rem { } help: you can use `as` to change the binding name of the import | LL | use std::ops::Rem as OtherRem; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++ error: aborting due to 5 previous errors diff --git a/tests/ui/imports/issue-25396.stderr b/tests/ui/imports/issue-25396.stderr index 518d2be7841..6f9b080f3c5 100644 --- a/tests/ui/imports/issue-25396.stderr +++ b/tests/ui/imports/issue-25396.stderr @@ -10,7 +10,7 @@ LL | use bar::baz; help: you can use `as` to change the binding name of the import | LL | use bar::baz as other_baz; - | ~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++ error[E0252]: the name `Quux` is defined multiple times --> $DIR/issue-25396.rs:7:5 @@ -24,7 +24,7 @@ LL | use bar::Quux; help: you can use `as` to change the binding name of the import | LL | use bar::Quux as OtherQuux; - | ~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++ error[E0252]: the name `blah` is defined multiple times --> $DIR/issue-25396.rs:10:5 @@ -38,7 +38,7 @@ LL | use bar::blah; help: you can use `as` to change the binding name of the import | LL | use bar::blah as other_blah; - | ~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++ error[E0252]: the name `WOMP` is defined multiple times --> $DIR/issue-25396.rs:13:5 @@ -52,7 +52,7 @@ LL | use bar::WOMP; help: you can use `as` to change the binding name of the import | LL | use bar::WOMP as OtherWOMP; - | ~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/imports/issue-32354-suggest-import-rename.stderr b/tests/ui/imports/issue-32354-suggest-import-rename.stderr index de9bdc4f2cc..753fa434ffb 100644 --- a/tests/ui/imports/issue-32354-suggest-import-rename.stderr +++ b/tests/ui/imports/issue-32354-suggest-import-rename.stderr @@ -10,7 +10,7 @@ LL | use extension2::ConstructorExtension; help: you can use `as` to change the binding name of the import | LL | use extension2::ConstructorExtension as OtherConstructorExtension; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/import-self.stderr b/tests/ui/imports/issue-45829/import-self.stderr index 0c9424f3083..3c9d4fe6ba6 100644 --- a/tests/ui/imports/issue-45829/import-self.stderr +++ b/tests/ui/imports/issue-45829/import-self.stderr @@ -48,7 +48,7 @@ LL | use foo::self; help: you can use `as` to change the binding name of the import | LL | use foo as other_foo; - | ~~~~~~~~~~~~~~~~ + | ~~~~~~~~~~~~ error[E0252]: the name `A` is defined multiple times --> $DIR/import-self.rs:16:11 diff --git a/tests/ui/imports/issue-45829/issue-45829.stderr b/tests/ui/imports/issue-45829/issue-45829.stderr index 627a09a07b8..c6835c3bd7a 100644 --- a/tests/ui/imports/issue-45829/issue-45829.stderr +++ b/tests/ui/imports/issue-45829/issue-45829.stderr @@ -10,7 +10,7 @@ LL | use foo::{A, B as A}; help: you can use `as` to change the binding name of the import | LL | use foo::{A, B as OtherA}; - | ~~~~~~~~~~~ + | ~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr b/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr index 9b0a2534a1d..fd4fb9db0b6 100644 --- a/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr +++ b/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr @@ -10,7 +10,7 @@ LL | use std as issue_45829_b; help: you can use `as` to change the binding name of the import | LL | use std as other_issue_45829_b; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-use-with-tabs.stderr b/tests/ui/imports/issue-45829/rename-use-with-tabs.stderr index 5751f41ae9d..178303bbc1d 100644 --- a/tests/ui/imports/issue-45829/rename-use-with-tabs.stderr +++ b/tests/ui/imports/issue-45829/rename-use-with-tabs.stderr @@ -10,7 +10,7 @@ LL | use foo::{A, bar::B as A}; help: you can use `as` to change the binding name of the import | LL | use foo::{A, bar::B as OtherA}; - | ~~~~~~~~~~~~~~~~ + | ~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-with-path.stderr b/tests/ui/imports/issue-45829/rename-with-path.stderr index 69e084db6ff..a83fdb37324 100644 --- a/tests/ui/imports/issue-45829/rename-with-path.stderr +++ b/tests/ui/imports/issue-45829/rename-with-path.stderr @@ -10,7 +10,7 @@ LL | use std::{collections::HashMap as A, sync::Arc as A}; help: you can use `as` to change the binding name of the import | LL | use std::{collections::HashMap as A, sync::Arc as OtherA}; - | ~~~~~~~~~~~~~~~~~~~ + | ~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename.stderr b/tests/ui/imports/issue-45829/rename.stderr index f1ee5112dc1..4977909487c 100644 --- a/tests/ui/imports/issue-45829/rename.stderr +++ b/tests/ui/imports/issue-45829/rename.stderr @@ -10,7 +10,7 @@ LL | use std as core; help: you can use `as` to change the binding name of the import | LL | use std as other_core; - | ~~~~~~~~~~~~~~~~~ + | ~~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-52891.stderr b/tests/ui/imports/issue-52891.stderr index 7bb1301edf2..730962d702a 100644 --- a/tests/ui/imports/issue-52891.stderr +++ b/tests/ui/imports/issue-52891.stderr @@ -98,7 +98,7 @@ LL | use issue_52891::b::inner; help: you can use `as` to change the binding name of the import | LL | use issue_52891::b::inner as other_inner; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++++ error[E0254]: the name `issue_52891` is defined multiple times --> $DIR/issue-52891.rs:31:19 diff --git a/tests/ui/imports/issue-8640.stderr b/tests/ui/imports/issue-8640.stderr index ea350e97e64..d22fddb1a69 100644 --- a/tests/ui/imports/issue-8640.stderr +++ b/tests/ui/imports/issue-8640.stderr @@ -10,7 +10,7 @@ LL | mod bar {} help: you can use `as` to change the binding name of the import | LL | use baz::bar as other_bar; - | ~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/inline-const/const-match-pat-generic.stderr b/tests/ui/inline-const/const-match-pat-generic.stderr index 15c3a876afc..26f72b34eca 100644 --- a/tests/ui/inline-const/const-match-pat-generic.stderr +++ b/tests/ui/inline-const/const-match-pat-generic.stderr @@ -1,10 +1,10 @@ -error: constant pattern depends on a generic parameter +error[E0158]: constant pattern depends on a generic parameter --> $DIR/const-match-pat-generic.rs:7:9 | LL | const { V } => {}, | ^^^^^^^^^^^ -error: constant pattern depends on a generic parameter +error[E0158]: constant pattern depends on a generic parameter --> $DIR/const-match-pat-generic.rs:19:9 | LL | const { f(V) } => {}, @@ -12,3 +12,4 @@ LL | const { f(V) } => {}, error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/issues/issue-4935.stderr b/tests/ui/issues/issue-4935.stderr index f18cf66f14d..7ee895d91c7 100644 --- a/tests/ui/issues/issue-4935.stderr +++ b/tests/ui/issues/issue-4935.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/issue-4935.rs:5:13 | LL | fn main() { foo(5, 6) } - | ^^^ - unexpected argument of type `{integer}` + | ^^^ - unexpected argument #2 of type `{integer}` | note: function defined here --> $DIR/issue-4935.rs:3:4 diff --git a/tests/ui/lifetimes/issue-26638.stderr b/tests/ui/lifetimes/issue-26638.stderr index 403a8c67ccb..dc18e0f1f7a 100644 --- a/tests/ui/lifetimes/issue-26638.stderr +++ b/tests/ui/lifetimes/issue-26638.stderr @@ -50,7 +50,7 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/issue-26638.rs:4:47 | LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } - | ^^^^-- an argument of type `&u8` is missing + | ^^^^-- argument #1 of type `&u8` is missing | help: provide the argument | diff --git a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr index f8d919fd68b..4ea14cdf042 100644 --- a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr +++ b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr @@ -6,8 +6,9 @@ LL | fn bar(foo: Foo<Target = usize>) {} | help: consider removing this associated item binding | -LL | fn bar(foo: Foo<Target = usize>) {} - | ~~~~~~~~~~~~~~~~ +LL - fn bar(foo: Foo<Target = usize>) {} +LL + fn bar(foo: Foo) {} + | error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs b/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs index 1acefa314aa..695a752fe17 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs @@ -1,6 +1,6 @@ //@ run-pass -#![allow(dead_code, non_camel_case_types, non_upper_case_globals)] +#![allow(dead_code, non_camel_case_types, non_upper_case_globals, unused_variables)] #![feature(macro_metavar_expr_concat)] macro_rules! create_things { @@ -37,13 +37,58 @@ macro_rules! without_dollar_sign_is_an_ident { }; } -macro_rules! literals { - ($ident:ident) => {{ - let ${concat(_a, "_b")}: () = (); - let ${concat("_b", _a)}: () = (); +macro_rules! combinations { + ($ident:ident, $literal:literal, $tt_ident:tt, $tt_literal:tt) => {{ + // tt ident + let ${concat($tt_ident, b)} = (); + let ${concat($tt_ident, _b)} = (); + let ${concat($tt_ident, "b")} = (); + let ${concat($tt_ident, $tt_ident)} = (); + let ${concat($tt_ident, $tt_literal)} = (); + let ${concat($tt_ident, $ident)} = (); + let ${concat($tt_ident, $literal)} = (); + // tt literal + let ${concat($tt_literal, b)} = (); + let ${concat($tt_literal, _b)} = (); + let ${concat($tt_literal, "b")} = (); + let ${concat($tt_literal, $tt_ident)} = (); + let ${concat($tt_literal, $tt_literal)} = (); + let ${concat($tt_literal, $ident)} = (); + let ${concat($tt_literal, $literal)} = (); - let ${concat($ident, "_b")}: () = (); - let ${concat("_b", $ident)}: () = (); + // ident (adhoc) + let ${concat(_b, b)} = (); + let ${concat(_b, _b)} = (); + let ${concat(_b, "b")} = (); + let ${concat(_b, $tt_ident)} = (); + let ${concat(_b, $tt_literal)} = (); + let ${concat(_b, $ident)} = (); + let ${concat(_b, $literal)} = (); + // ident (param) + let ${concat($ident, b)} = (); + let ${concat($ident, _b)} = (); + let ${concat($ident, "b")} = (); + let ${concat($ident, $tt_ident)} = (); + let ${concat($ident, $tt_literal)} = (); + let ${concat($ident, $ident)} = (); + let ${concat($ident, $literal)} = (); + + // literal (adhoc) + let ${concat("a", b)} = (); + let ${concat("a", _b)} = (); + let ${concat("a", "b")} = (); + let ${concat("a", $tt_ident)} = (); + let ${concat("a", $tt_literal)} = (); + let ${concat("a", $ident)} = (); + let ${concat("a", $literal)} = (); + // literal (param) + let ${concat($literal, b)} = (); + let ${concat($literal, _b)} = (); + let ${concat($literal, "b")} = (); + let ${concat($literal, $tt_ident)} = (); + let ${concat($literal, $tt_literal)} = (); + let ${concat($literal, $ident)} = (); + let ${concat($literal, $literal)} = (); }}; } @@ -66,5 +111,5 @@ fn main() { assert_eq!(VARident, 1); assert_eq!(VAR_123, 2); - literals!(_hello); + combinations!(_hello, "a", b, "b"); } diff --git a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs index b2845c8d1c1..7673bd3200f 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs @@ -20,7 +20,7 @@ macro_rules! wrong_concat_declarations { //~^ ERROR `concat` must have at least two elements ${concat($ex, aaaa)} - //~^ ERROR `${concat(..)}` currently only accepts identifiers + //~^ ERROR metavariables of `${concat(..)}` must be of type ${concat($ex, aaaa 123)} //~^ ERROR expected comma @@ -98,6 +98,39 @@ macro_rules! unsupported_literals { }}; } +macro_rules! bad_literal_string { + ($literal:literal) => { + const ${concat(_foo, $literal)}: () = (); + //~^ ERROR `${concat(..)}` is not generating a valid identifier + //~| ERROR `${concat(..)}` is not generating a valid identifier + //~| ERROR `${concat(..)}` is not generating a valid identifier + //~| ERROR `${concat(..)}` is not generating a valid identifier + //~| ERROR `${concat(..)}` is not generating a valid identifier + //~| ERROR `${concat(..)}` is not generating a valid identifier + //~| ERROR `${concat(..)}` is not generating a valid identifier + } +} + +macro_rules! bad_literal_non_string { + ($literal:literal) => { + const ${concat(_foo, $literal)}: () = (); + //~^ ERROR metavariables of `${concat(..)}` must be of type + //~| ERROR metavariables of `${concat(..)}` must be of type + //~| ERROR metavariables of `${concat(..)}` must be of type + //~| ERROR metavariables of `${concat(..)}` must be of type + //~| ERROR metavariables of `${concat(..)}` must be of type + } +} + +macro_rules! bad_tt_literal { + ($tt:tt) => { + const ${concat(_foo, $tt)}: () = (); + //~^ ERROR metavariables of `${concat(..)}` must be of type + //~| ERROR metavariables of `${concat(..)}` must be of type + //~| ERROR metavariables of `${concat(..)}` must be of type + } +} + fn main() { wrong_concat_declarations!(1); @@ -113,4 +146,23 @@ fn main() { unsupported_literals!(_abc); empty!(); + + bad_literal_string!("\u{00BD}"); + bad_literal_string!("\x41"); + bad_literal_string!("🤷"); + bad_literal_string!("d[-_-]b"); + + bad_literal_string!("-1"); + bad_literal_string!("1.0"); + bad_literal_string!("'1'"); + + bad_literal_non_string!(1); + bad_literal_non_string!(-1); + bad_literal_non_string!(1.0); + bad_literal_non_string!('1'); + bad_literal_non_string!(false); + + bad_tt_literal!(1); + bad_tt_literal!(1.0); + bad_tt_literal!('1'); } diff --git a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr index 2fe5842b39e..2de6d2b3ce3 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr +++ b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr @@ -64,11 +64,13 @@ error: expected identifier or string literal LL | let ${concat($ident, 1)}: () = (); | ^ -error: `${concat(..)}` currently only accepts identifiers or meta-variables as parameters +error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt` --> $DIR/syntax-errors.rs:22:19 | LL | ${concat($ex, aaaa)} | ^^ + | + = note: currently only string literals are supported error: variable `foo` is not recognized in meta-variable expression --> $DIR/syntax-errors.rs:35:30 @@ -131,5 +133,152 @@ LL | empty!(); | = note: this error originates in the macro `empty` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 18 previous errors +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:103:16 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | bad_literal_string!("\u{00BD}"); + | ------------------------------- in this macro invocation + | + = note: this error originates in the macro `bad_literal_string` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:103:16 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | bad_literal_string!("\x41"); + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `bad_literal_string` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:103:16 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | bad_literal_string!("🤷"); + | ------------------------- in this macro invocation + | + = note: this error originates in the macro `bad_literal_string` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:103:16 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | bad_literal_string!("d[-_-]b"); + | ------------------------------ in this macro invocation + | + = note: this error originates in the macro `bad_literal_string` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:103:16 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | bad_literal_string!("-1"); + | ------------------------- in this macro invocation + | + = note: this error originates in the macro `bad_literal_string` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:103:16 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | bad_literal_string!("1.0"); + | -------------------------- in this macro invocation + | + = note: this error originates in the macro `bad_literal_string` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:103:16 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | bad_literal_string!("'1'"); + | -------------------------- in this macro invocation + | + = note: this error originates in the macro `bad_literal_string` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt` + --> $DIR/syntax-errors.rs:116:31 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^ + | + = note: currently only string literals are supported + +error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt` + --> $DIR/syntax-errors.rs:116:31 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^ + | + = note: currently only string literals are supported + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt` + --> $DIR/syntax-errors.rs:116:31 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^ + | + = note: currently only string literals are supported + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt` + --> $DIR/syntax-errors.rs:116:31 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^ + | + = note: currently only string literals are supported + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt` + --> $DIR/syntax-errors.rs:116:31 + | +LL | const ${concat(_foo, $literal)}: () = (); + | ^^^^^^^ + | + = note: currently only string literals are supported + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt` + --> $DIR/syntax-errors.rs:127:31 + | +LL | const ${concat(_foo, $tt)}: () = (); + | ^^ + | + = note: currently only string literals are supported + +error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt` + --> $DIR/syntax-errors.rs:127:31 + | +LL | const ${concat(_foo, $tt)}: () = (); + | ^^ + | + = note: currently only string literals are supported + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt` + --> $DIR/syntax-errors.rs:127:31 + | +LL | const ${concat(_foo, $tt)}: () = (); + | ^^ + | + = note: currently only string literals are supported + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 33 previous errors diff --git a/tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs b/tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs index b2cfb211e2d..4eeb2384deb 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs @@ -3,12 +3,17 @@ #![feature(macro_metavar_expr_concat)] macro_rules! turn_to_page { - ($ident:ident) => { + ($ident:ident, $literal:literal, $tt:tt) => { const ${concat("Ḧ", $ident)}: i32 = 394; + const ${concat("Ḧ", $literal)}: i32 = 394; + const ${concat("Ḧ", $tt)}: i32 = 394; }; } fn main() { - turn_to_page!(P); - assert_eq!(ḦP, 394); + turn_to_page!(P1, "Ṕ2", Ṕ); + assert_eq!(ḦṔ, 394); + assert_eq!(ḦP1, 394); + assert_eq!(ḦṔ2, 394); + } diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr index 0855a17b333..84005119a87 100644 --- a/tests/ui/methods/method-call-err-msg.stderr +++ b/tests/ui/methods/method-call-err-msg.stderr @@ -19,7 +19,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/method-call-err-msg.rs:14:7 | LL | .one() - | ^^^-- an argument of type `isize` is missing + | ^^^-- argument #1 of type `isize` is missing | note: method defined here --> $DIR/method-call-err-msg.rs:6:8 @@ -35,7 +35,7 @@ error[E0061]: this method takes 2 arguments but 1 argument was supplied --> $DIR/method-call-err-msg.rs:15:7 | LL | .two(0); - | ^^^--- an argument of type `isize` is missing + | ^^^--- argument #2 of type `isize` is missing | note: method defined here --> $DIR/method-call-err-msg.rs:7:8 diff --git a/tests/ui/mismatched_types/overloaded-calls-bad.stderr b/tests/ui/mismatched_types/overloaded-calls-bad.stderr index cd483e7ad2c..c52fa713615 100644 --- a/tests/ui/mismatched_types/overloaded-calls-bad.stderr +++ b/tests/ui/mismatched_types/overloaded-calls-bad.stderr @@ -16,7 +16,7 @@ error[E0057]: this function takes 1 argument but 0 arguments were supplied --> $DIR/overloaded-calls-bad.rs:35:15 | LL | let ans = s(); - | ^-- an argument of type `isize` is missing + | ^-- argument #1 of type `isize` is missing | note: implementation defined here --> $DIR/overloaded-calls-bad.rs:10:1 @@ -32,7 +32,7 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/overloaded-calls-bad.rs:37:15 | LL | let ans = s("burma", "shave"); - | ^ ------- ------- unexpected argument of type `&'static str` + | ^ ------- ------- unexpected argument #2 of type `&'static str` | | | expected `isize`, found `&str` | diff --git a/tests/ui/not-enough-arguments.stderr b/tests/ui/not-enough-arguments.stderr index 8b2dafb4e1d..89e98866667 100644 --- a/tests/ui/not-enough-arguments.stderr +++ b/tests/ui/not-enough-arguments.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 4 arguments but 3 arguments were supplied --> $DIR/not-enough-arguments.rs:27:3 | LL | foo(1, 2, 3); - | ^^^--------- an argument of type `isize` is missing + | ^^^--------- argument #4 of type `isize` is missing | note: function defined here --> $DIR/not-enough-arguments.rs:5:4 diff --git a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs b/tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs deleted file mode 100644 index 95ead6b5d4a..00000000000 --- a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs +++ /dev/null @@ -1,26 +0,0 @@ -pub enum EFoo { - A, -} - -pub trait Foo { - const X: EFoo; -} - -struct Abc; - -impl Foo for Abc { - const X: EFoo = EFoo::A; -} - -struct Def; -impl Foo for Def { - const X: EFoo = EFoo::A; -} - -pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) { - //~^ ERROR associated consts cannot be referenced in patterns - let A::X = arg; - //~^ ERROR associated consts cannot be referenced in patterns -} - -fn main() {} diff --git a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr b/tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr deleted file mode 100644 index 62c90b638d7..00000000000 --- a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0158]: associated consts cannot be referenced in patterns - --> $DIR/issue-68393-let-pat-assoc-constant.rs:22:9 - | -LL | let A::X = arg; - | ^^^^ - -error[E0158]: associated consts cannot be referenced in patterns - --> $DIR/issue-68393-let-pat-assoc-constant.rs:20:40 - | -LL | pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) { - | ^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr b/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr index e22e636adb6..a8d0efedb6c 100644 --- a/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr +++ b/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr @@ -8,7 +8,7 @@ LL | use std::slice as std; help: you can use `as` to change the binding name of the import | LL | use std::slice as other_std; - | ~~~~~~~~~~~~~~~~~~~~~~~ + | ~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/resolve/resolve-conflict-item-vs-import.stderr b/tests/ui/resolve/resolve-conflict-item-vs-import.stderr index 3b1b5f1ad00..a8b16009c55 100644 --- a/tests/ui/resolve/resolve-conflict-item-vs-import.stderr +++ b/tests/ui/resolve/resolve-conflict-item-vs-import.stderr @@ -11,7 +11,7 @@ LL | fn transmute() {} help: you can use `as` to change the binding name of the import | LL | use std::mem::transmute as other_transmute; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/resolve/resolve-conflict-type-vs-import.stderr b/tests/ui/resolve/resolve-conflict-type-vs-import.stderr index c5cb4e07862..241e48d0cd5 100644 --- a/tests/ui/resolve/resolve-conflict-type-vs-import.stderr +++ b/tests/ui/resolve/resolve-conflict-type-vs-import.stderr @@ -11,7 +11,7 @@ LL | struct Iter; help: you can use `as` to change the binding name of the import | LL | use std::slice::Iter as OtherIter; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs index c69fe145f77..c01f8934c75 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs @@ -13,7 +13,7 @@ const A: &[B] = &[]; pub fn main() { match &[][..] { A => (), - //~^ ERROR must be annotated with `#[derive(PartialEq)]` + //~^ ERROR must implement `PartialEq` _ => (), } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr index 02e2bab4d0a..736e4c30c8a 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr @@ -1,11 +1,8 @@ -error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` +error: to use a constant of type `&[B]` in a pattern, the type must implement `PartialEq` --> $DIR/issue-61188-match-slice-forbidden-without-eq.rs:15:9 | LL | A => (), | ^ - | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.rs index 6d6a336e688..f343013f2b0 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.rs @@ -28,13 +28,9 @@ fn main() { // Also cover range patterns match x { NAN..=1.0 => {}, //~ ERROR cannot use NaN in patterns - //~^ ERROR lower range bound must be less than or equal to upper -1.0..=NAN => {}, //~ ERROR cannot use NaN in patterns - //~^ ERROR lower range bound must be less than or equal to upper NAN.. => {}, //~ ERROR cannot use NaN in patterns - //~^ ERROR lower range bound must be less than or equal to upper ..NAN => {}, //~ ERROR cannot use NaN in patterns - //~^ ERROR lower range bound must be less than upper _ => {}, }; } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr index baca1d75048..44b05ea31e9 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-6804-nan-match.stderr @@ -34,14 +34,8 @@ LL | NAN..=1.0 => {}, = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead -error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/issue-6804-nan-match.rs:30:9 - | -LL | NAN..=1.0 => {}, - | ^^^^^^^^^ lower bound larger than upper bound - error: cannot use NaN in patterns - --> $DIR/issue-6804-nan-match.rs:32:16 + --> $DIR/issue-6804-nan-match.rs:31:16 | LL | -1.0..=NAN => {}, | ^^^ @@ -49,14 +43,8 @@ LL | -1.0..=NAN => {}, = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead -error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/issue-6804-nan-match.rs:32:9 - | -LL | -1.0..=NAN => {}, - | ^^^^^^^^^^ lower bound larger than upper bound - error: cannot use NaN in patterns - --> $DIR/issue-6804-nan-match.rs:34:9 + --> $DIR/issue-6804-nan-match.rs:32:9 | LL | NAN.. => {}, | ^^^ @@ -64,14 +52,8 @@ LL | NAN.. => {}, = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead -error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/issue-6804-nan-match.rs:34:9 - | -LL | NAN.. => {}, - | ^^^^^ lower bound larger than upper bound - error: cannot use NaN in patterns - --> $DIR/issue-6804-nan-match.rs:36:11 + --> $DIR/issue-6804-nan-match.rs:33:11 | LL | ..NAN => {}, | ^^^ @@ -79,13 +61,5 @@ LL | ..NAN => {}, = note: NaNs compare inequal to everything, even themselves, so this pattern would never match = help: try using the `is_nan` method instead -error[E0579]: lower range bound must be less than upper - --> $DIR/issue-6804-nan-match.rs:36:9 - | -LL | ..NAN => {}, - | ^^^^^ - -error: aborting due to 11 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0030, E0579. -For more information about an error, try `rustc --explain E0030`. diff --git a/tests/ui/span/issue-34264.stderr b/tests/ui/span/issue-34264.stderr index 89c67719b5a..b581cdd0be2 100644 --- a/tests/ui/span/issue-34264.stderr +++ b/tests/ui/span/issue-34264.stderr @@ -54,7 +54,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/issue-34264.rs:7:5 | LL | foo(Some(42), 2, ""); - | ^^^ -- unexpected argument of type `&'static str` + | ^^^ -- unexpected argument #3 of type `&'static str` | note: function defined here --> $DIR/issue-34264.rs:1:4 @@ -85,7 +85,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/issue-34264.rs:10:5 | LL | bar(1, 2, 3); - | ^^^ - unexpected argument of type `{integer}` + | ^^^ - unexpected argument #3 of type `{integer}` | note: function defined here --> $DIR/issue-34264.rs:3:4 diff --git a/tests/ui/span/missing-unit-argument.stderr b/tests/ui/span/missing-unit-argument.stderr index ff89f775334..79980f48ab6 100644 --- a/tests/ui/span/missing-unit-argument.stderr +++ b/tests/ui/span/missing-unit-argument.stderr @@ -2,7 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:11:33 | LL | let _: Result<(), String> = Ok(); - | ^^-- an argument of type `()` is missing + | ^^-- argument #1 of type `()` is missing | note: tuple variant defined here --> $SRC_DIR/core/src/result.rs:LL:COL @@ -31,7 +31,7 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/missing-unit-argument.rs:13:5 | LL | foo(()); - | ^^^---- an argument of type `()` is missing + | ^^^---- argument #2 of type `()` is missing | note: function defined here --> $DIR/missing-unit-argument.rs:1:4 @@ -47,7 +47,7 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:14:5 | LL | bar(); - | ^^^-- an argument of type `()` is missing + | ^^^-- argument #1 of type `()` is missing | note: function defined here --> $DIR/missing-unit-argument.rs:2:4 @@ -63,7 +63,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:15:7 | LL | S.baz(); - | ^^^-- an argument of type `()` is missing + | ^^^-- argument #1 of type `()` is missing | note: method defined here --> $DIR/missing-unit-argument.rs:6:8 @@ -79,7 +79,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:16:7 | LL | S.generic::<()>(); - | ^^^^^^^^^^^^^-- an argument of type `()` is missing + | ^^^^^^^^^^^^^-- argument #1 of type `()` is missing | note: method defined here --> $DIR/missing-unit-argument.rs:7:8 diff --git a/tests/ui/suggestions/args-instead-of-tuple-errors.stderr b/tests/ui/suggestions/args-instead-of-tuple-errors.stderr index 510b99bb5af..1051a16b40d 100644 --- a/tests/ui/suggestions/args-instead-of-tuple-errors.stderr +++ b/tests/ui/suggestions/args-instead-of-tuple-errors.stderr @@ -2,7 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied --> $DIR/args-instead-of-tuple-errors.rs:6:34 | LL | let _: Option<(i32, bool)> = Some(1, 2); - | ^^^^ - unexpected argument of type `{integer}` + | ^^^^ - unexpected argument #2 of type `{integer}` | note: expected `(i32, bool)`, found integer --> $DIR/args-instead-of-tuple-errors.rs:6:39 @@ -30,7 +30,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/args-instead-of-tuple-errors.rs:8:5 | LL | int_bool(1, 2); - | ^^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^^ - unexpected argument #2 of type `{integer}` | note: expected `(i32, bool)`, found integer --> $DIR/args-instead-of-tuple-errors.rs:8:14 @@ -54,7 +54,7 @@ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/args-instead-of-tuple-errors.rs:11:28 | LL | let _: Option<(i8,)> = Some(); - | ^^^^-- an argument of type `(i8,)` is missing + | ^^^^-- argument #1 of type `(i8,)` is missing | note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL diff --git a/tests/ui/suggestions/args-instead-of-tuple.stderr b/tests/ui/suggestions/args-instead-of-tuple.stderr index 0bdf10b0d63..3ca560f93eb 100644 --- a/tests/ui/suggestions/args-instead-of-tuple.stderr +++ b/tests/ui/suggestions/args-instead-of-tuple.stderr @@ -28,7 +28,7 @@ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/args-instead-of-tuple.rs:11:25 | LL | let _: Option<()> = Some(); - | ^^^^-- an argument of type `()` is missing + | ^^^^-- argument #1 of type `()` is missing | note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL diff --git a/tests/ui/suggestions/issue-109396.stderr b/tests/ui/suggestions/issue-109396.stderr index d4956872a39..5419e8240c5 100644 --- a/tests/ui/suggestions/issue-109396.stderr +++ b/tests/ui/suggestions/issue-109396.stderr @@ -11,14 +11,14 @@ LL | let mut mutex = std::mem::zeroed( | ^^^^^^^^^^^^^^^^ LL | LL | file.as_raw_fd(), - | ---------------- unexpected argument + | ---------------- unexpected argument #1 LL | LL | 0, - | - unexpected argument of type `{integer}` + | - unexpected argument #2 of type `{integer}` LL | 0, - | - unexpected argument of type `{integer}` + | - unexpected argument #3 of type `{integer}` LL | 0, - | - unexpected argument of type `{integer}` + | - unexpected argument #4 of type `{integer}` | note: function defined here --> $SRC_DIR/core/src/mem/mod.rs:LL:COL diff --git a/tests/ui/suggestions/issue-109854.stderr b/tests/ui/suggestions/issue-109854.stderr index 52444cd4c45..d9cbbe37d46 100644 --- a/tests/ui/suggestions/issue-109854.stderr +++ b/tests/ui/suggestions/issue-109854.stderr @@ -7,9 +7,9 @@ LL | String::with_capacity( LL | / r#" LL | | pub(crate) struct Person<T: Clone> {} LL | | "#, - | |__- unexpected argument of type `&'static str` + | |__- unexpected argument #2 of type `&'static str` LL | r#""#, - | ----- unexpected argument of type `&'static str` + | ----- unexpected argument #3 of type `&'static str` | note: expected `usize`, found fn item --> $DIR/issue-109854.rs:4:5 diff --git a/tests/ui/suggestions/issue-85347.stderr b/tests/ui/suggestions/issue-85347.stderr index b3616041c4c..af77ddd35e3 100644 --- a/tests/ui/suggestions/issue-85347.stderr +++ b/tests/ui/suggestions/issue-85347.stderr @@ -22,8 +22,9 @@ LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>; | help: consider removing this associated item binding | -LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>; - | ~~~~~~~~~~~~~~~ +LL - type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>; +LL + type Bar<'a>: Deref<Target = <Self>::Bar>; + | error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied --> $DIR/issue-85347.rs:3:42 @@ -51,8 +52,9 @@ LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider removing this associated item binding | -LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>; - | ~~~~~~~~~~~~~~~ +LL - type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>; +LL + type Bar<'a>: Deref<Target = <Self>::Bar>; + | error: aborting due to 4 previous errors diff --git a/tests/ui/tuple/wrong_argument_ice-3.stderr b/tests/ui/tuple/wrong_argument_ice-3.stderr index ce21751f39d..78212ed1e76 100644 --- a/tests/ui/tuple/wrong_argument_ice-3.stderr +++ b/tests/ui/tuple/wrong_argument_ice-3.stderr @@ -2,7 +2,7 @@ error[E0061]: this method takes 1 argument but 2 arguments were supplied --> $DIR/wrong_argument_ice-3.rs:9:16 | LL | groups.push(new_group, vec![process]); - | ^^^^ ------------- unexpected argument of type `Vec<&Process>` + | ^^^^ ------------- unexpected argument #2 of type `Vec<&Process>` | note: expected `(Vec<String>, Vec<Process>)`, found `Vec<String>` --> $DIR/wrong_argument_ice-3.rs:9:21 diff --git a/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr index db75a520c65..371f5b10988 100644 --- a/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr +++ b/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr @@ -2,7 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:21:5 | LL | <E>::V(); - | ^^^^^^-- an argument of type `u8` is missing + | ^^^^^^-- argument #1 of type `u8` is missing | note: tuple variant defined here --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:5:5 diff --git a/tests/ui/type/type-ascription-instead-of-initializer.stderr b/tests/ui/type/type-ascription-instead-of-initializer.stderr index 224ff6e7404..630e82d254e 100644 --- a/tests/ui/type/type-ascription-instead-of-initializer.stderr +++ b/tests/ui/type/type-ascription-instead-of-initializer.stderr @@ -11,7 +11,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/type-ascription-instead-of-initializer.rs:2:12 | LL | let x: Vec::with_capacity(10, 20); - | ^^^^^^^^^^^^^^^^^^ -- unexpected argument of type `{integer}` + | ^^^^^^^^^^^^^^^^^^ -- unexpected argument #2 of type `{integer}` | note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL diff --git a/tests/ui/type/type-check/point-at-inference-4.rs b/tests/ui/type/type-check/point-at-inference-4.rs index 3deb234c275..5745b738532 100644 --- a/tests/ui/type/type-check/point-at-inference-4.rs +++ b/tests/ui/type/type-check/point-at-inference-4.rs @@ -13,7 +13,7 @@ fn main() { //~^ ERROR this method takes 2 arguments but 1 argument was supplied //~| NOTE this argument has type `i32`... //~| NOTE ... which causes `s` to have type `S<i32, _>` - //~| NOTE an argument is missing + //~| NOTE argument #2 is missing //~| HELP provide the argument //~| HELP change the type of the numeric literal from `i32` to `u32` let t: S<u32, _> = s; diff --git a/tests/ui/type/type-check/point-at-inference-4.stderr b/tests/ui/type/type-check/point-at-inference-4.stderr index 5f7bb8b9367..a953ca70ea2 100644 --- a/tests/ui/type/type-check/point-at-inference-4.stderr +++ b/tests/ui/type/type-check/point-at-inference-4.stderr @@ -2,7 +2,7 @@ error[E0061]: this method takes 2 arguments but 1 argument was supplied --> $DIR/point-at-inference-4.rs:12:7 | LL | s.infer(0i32); - | ^^^^^------ an argument is missing + | ^^^^^------ argument #2 is missing | note: method defined here --> $DIR/point-at-inference-4.rs:4:8 diff --git a/tests/ui/typeck/cyclic_type_ice.stderr b/tests/ui/typeck/cyclic_type_ice.stderr index bfff6830fc5..36715b4ee5d 100644 --- a/tests/ui/typeck/cyclic_type_ice.stderr +++ b/tests/ui/typeck/cyclic_type_ice.stderr @@ -13,7 +13,7 @@ error[E0057]: this function takes 2 arguments but 1 argument was supplied --> $DIR/cyclic_type_ice.rs:3:5 | LL | f(f); - | ^--- an argument is missing + | ^--- argument #2 is missing | note: closure defined here --> $DIR/cyclic_type_ice.rs:2:13 diff --git a/tests/ui/typeck/remove-extra-argument.stderr b/tests/ui/typeck/remove-extra-argument.stderr index 4bab2959651..d4e0dcb50ae 100644 --- a/tests/ui/typeck/remove-extra-argument.stderr +++ b/tests/ui/typeck/remove-extra-argument.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/remove-extra-argument.rs:6:5 | LL | l(vec![], vec![]) - | ^ ------ unexpected argument of type `Vec<_>` + | ^ ------ unexpected argument #2 of type `Vec<_>` | note: function defined here --> $DIR/remove-extra-argument.rs:3:4 diff --git a/tests/ui/typeck/struct-enum-wrong-args.stderr b/tests/ui/typeck/struct-enum-wrong-args.stderr index d005eca841e..e58d162901e 100644 --- a/tests/ui/typeck/struct-enum-wrong-args.stderr +++ b/tests/ui/typeck/struct-enum-wrong-args.stderr @@ -2,7 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:6:13 | LL | let _ = Some(3, 2); - | ^^^^ - unexpected argument of type `{integer}` + | ^^^^ - unexpected argument #2 of type `{integer}` | note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL @@ -16,9 +16,9 @@ error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:7:13 | LL | let _ = Ok(3, 6, 2); - | ^^ - - unexpected argument of type `{integer}` + | ^^ - - unexpected argument #3 of type `{integer}` | | - | unexpected argument of type `{integer}` + | unexpected argument #2 of type `{integer}` | note: tuple variant defined here --> $SRC_DIR/core/src/result.rs:LL:COL @@ -32,7 +32,7 @@ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:8:13 | LL | let _ = Ok(); - | ^^-- an argument is missing + | ^^-- argument #1 is missing | note: tuple variant defined here --> $SRC_DIR/core/src/result.rs:LL:COL @@ -45,7 +45,7 @@ error[E0061]: this struct takes 1 argument but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:9:13 | LL | let _ = Wrapper(); - | ^^^^^^^-- an argument of type `i32` is missing + | ^^^^^^^-- argument #1 of type `i32` is missing | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:2:8 @@ -61,7 +61,7 @@ error[E0061]: this struct takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:10:13 | LL | let _ = Wrapper(5, 2); - | ^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^ - unexpected argument #2 of type `{integer}` | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:2:8 @@ -94,7 +94,7 @@ error[E0061]: this struct takes 2 arguments but 1 argument was supplied --> $DIR/struct-enum-wrong-args.rs:12:13 | LL | let _ = DoubleWrapper(5); - | ^^^^^^^^^^^^^--- an argument of type `i32` is missing + | ^^^^^^^^^^^^^--- argument #2 of type `i32` is missing | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:3:8 @@ -110,7 +110,7 @@ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:13:13 | LL | let _ = DoubleWrapper(5, 2, 7); - | ^^^^^^^^^^^^^ - unexpected argument of type `{integer}` + | ^^^^^^^^^^^^^ - unexpected argument #3 of type `{integer}` | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:3:8 diff --git a/tests/ui/variants/variant-namespacing.stderr b/tests/ui/variants/variant-namespacing.stderr index 9e91ff7178d..2a2491b81f9 100644 --- a/tests/ui/variants/variant-namespacing.stderr +++ b/tests/ui/variants/variant-namespacing.stderr @@ -11,7 +11,7 @@ LL | pub use variant_namespacing::XE::{XStruct, XTuple, XUnit}; help: you can use `as` to change the binding name of the import | LL | pub use variant_namespacing::XE::{XStruct as OtherXStruct, XTuple, XUnit}; - | ~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++ error[E0255]: the name `XTuple` is defined multiple times --> $DIR/variant-namespacing.rs:24:44 @@ -26,7 +26,7 @@ LL | pub use variant_namespacing::XE::{XStruct, XTuple, XUnit}; help: you can use `as` to change the binding name of the import | LL | pub use variant_namespacing::XE::{XStruct, XTuple as OtherXTuple, XUnit}; - | ~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++++ error[E0255]: the name `XUnit` is defined multiple times --> $DIR/variant-namespacing.rs:24:52 @@ -41,7 +41,7 @@ LL | pub use variant_namespacing::XE::{XStruct, XTuple, XUnit}; help: you can use `as` to change the binding name of the import | LL | pub use variant_namespacing::XE::{XStruct, XTuple, XUnit as OtherXUnit}; - | ~~~~~~~~~~~~~~~~~~~ + | +++++++++++++ error[E0255]: the name `Struct` is defined multiple times --> $DIR/variant-namespacing.rs:28:13 @@ -56,7 +56,7 @@ LL | pub use E::{Struct, Tuple, Unit}; help: you can use `as` to change the binding name of the import | LL | pub use E::{Struct as OtherStruct, Tuple, Unit}; - | ~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++++ error[E0255]: the name `Tuple` is defined multiple times --> $DIR/variant-namespacing.rs:28:21 @@ -71,7 +71,7 @@ LL | pub use E::{Struct, Tuple, Unit}; help: you can use `as` to change the binding name of the import | LL | pub use E::{Struct, Tuple as OtherTuple, Unit}; - | ~~~~~~~~~~~~~~~~~~~ + | +++++++++++++ error[E0255]: the name `Unit` is defined multiple times --> $DIR/variant-namespacing.rs:28:28 @@ -86,7 +86,7 @@ LL | pub use E::{Struct, Tuple, Unit}; help: you can use `as` to change the binding name of the import | LL | pub use E::{Struct, Tuple, Unit as OtherUnit}; - | ~~~~~~~~~~~~~~~~~ + | ++++++++++++ error: aborting due to 6 previous errors diff --git a/triagebot.toml b/triagebot.toml index 763a5206c3c..2f36eb9d1c9 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -928,6 +928,7 @@ compiler-team-contributors = [ "@fee1-dead", "@jieyouxu", "@BoxyUwU", + "@chenyukang", ] compiler = [ "compiler-team", @@ -976,6 +977,7 @@ diagnostics = [ "@estebank", "@oli-obk", "@TaKO8Ki", + "@chenyukang", ] parser = [ "@compiler-errors", @@ -989,6 +991,7 @@ lexer = [ "@nnethercote", "@petrochenkov", "@estebank", + "@chenyukang", ] arena = [ "@nnethercote", |
