From ad6432c8ef9e27a37bdb440f8deba0e3e36a58f8 Mon Sep 17 00:00:00 2001 From: klensy Date: Tue, 23 Jan 2024 11:12:24 +0300 Subject: [PATCH 01/17] compiletest: reduce useless regex rebuilds before: ==8812== Total: 2,374,977,159 bytes in 6,840,026 blocks ==8812== At t-gmax: 8,090,486 bytes in 3,389 blocks ==8812== At t-end: 3,185,454 bytes in 757 blocks ==8812== Reads: 1,873,472,286 bytes ==8812== Writes: 1,249,411,589 bytes ==11212== I refs: 6,370,244,180 after: ==18725== Total: 429,769,246 bytes in 957,259 blocks ==18725== At t-gmax: 8,058,316 bytes in 3,502 blocks ==18725== At t-end: 3,045,261 bytes in 1,097 blocks ==18725== Reads: 431,872,599 bytes ==18725== Writes: 214,738,653 bytes ==20839== I refs: 1,873,010,089 --- src/tools/compiletest/src/runtest.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 8be4def15dedc..ca7efea07caae 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -4315,10 +4315,11 @@ impl<'test> TestCx<'test> { let mut seen_allocs = indexmap::IndexSet::new(); // The alloc-id appears in pretty-printed allocations. - let re = + static ALLOC_ID_PP_RE: Lazy = Lazy::new(|| { Regex::new(r"╾─*a(lloc)?([0-9]+)(\+0x[0-9]+)?()?( \([0-9]+ ptr bytes\))?─*╼") - .unwrap(); - normalized = re + .unwrap() + }); + normalized = ALLOC_ID_PP_RE .replace_all(&normalized, |caps: &Captures<'_>| { // Renumber the captured index. let index = caps.get(2).unwrap().as_str().to_string(); @@ -4331,8 +4332,9 @@ impl<'test> TestCx<'test> { .into_owned(); // The alloc-id appears in a sentence. - let re = Regex::new(r"\balloc([0-9]+)\b").unwrap(); - normalized = re + static ALLOC_ID_RE: Lazy = + Lazy::new(|| Regex::new(r"\balloc([0-9]+)\b").unwrap()); + normalized = ALLOC_ID_RE .replace_all(&normalized, |caps: &Captures<'_>| { let index = caps.get(1).unwrap().as_str().to_string(); let (index, _) = seen_allocs.insert_full(index); From e78d6859f7001b859bf7bacdc87c8da31f2f89e4 Mon Sep 17 00:00:00 2001 From: klensy Date: Tue, 23 Jan 2024 11:46:19 +0300 Subject: [PATCH 02/17] reduce bufreader size from default(8kb) to 1kb Headers WAY less than 1kb anyway, so this can be improved more? before ==18725== Total: 429,769,246 bytes in 957,259 blocks ==18725== At t-gmax: 8,058,316 bytes in 3,502 blocks ==18725== At t-end: 3,045,261 bytes in 1,097 blocks ==18725== Reads: 431,872,599 bytes ==18725== Writes: 214,738,653 bytes after ==49344== Total: 201,418,575 bytes in 957,174 blocks ==49344== At t-gmax: 7,937,250 bytes in 3,310 blocks ==49344== At t-end: 3,035,637 bytes in 1,076 blocks ==49344== Reads: 431,607,448 bytes ==49344== Writes: 210,731,540 bytes --- src/tools/compiletest/src/header.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index e70e01e8757e0..7c65e37119de4 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -650,7 +650,7 @@ fn iter_header_extra( let comment = if testfile.extension().is_some_and(|e| e == "rs") { "//" } else { "#" }; - let mut rdr = BufReader::new(rdr); + let mut rdr = BufReader::with_capacity(1024, rdr); let mut ln = String::new(); let mut line_number = 0; From 0710ebb999dd633bd536e66fcaab3d2a4b1739e8 Mon Sep 17 00:00:00 2001 From: klensy Date: Tue, 23 Jan 2024 19:36:07 +0300 Subject: [PATCH 03/17] don't collect found paths into BTreeSet: keeping order of inserted Paths having high cost on hot path, collect into HashSet instead and sort afterward. from 1,858,963,938 to 1,448,975,825 I refs. --- src/tools/compiletest/src/lib.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 60dd15841b766..543304694f620 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -25,7 +25,7 @@ use build_helper::git::{get_git_modified_files, get_git_untracked_files}; use core::panic; use getopts::Options; use lazycell::AtomicLazyCell; -use std::collections::BTreeSet; +use std::collections::HashSet; use std::ffi::OsString; use std::fs; use std::io::{self, ErrorKind}; @@ -415,7 +415,7 @@ pub fn run_tests(config: Arc) { let mut tests = Vec::new(); for c in configs { - let mut found_paths = BTreeSet::new(); + let mut found_paths = HashSet::new(); make_tests(c, &mut tests, &mut found_paths); check_overlapping_tests(&found_paths); } @@ -550,7 +550,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts { pub fn make_tests( config: Arc, tests: &mut Vec, - found_paths: &mut BTreeSet, + found_paths: &mut HashSet, ) { debug!("making tests from {:?}", config.src_base.display()); let inputs = common_inputs_stamp(&config); @@ -646,7 +646,7 @@ fn collect_tests_from_dir( relative_dir_path: &Path, inputs: &Stamp, tests: &mut Vec, - found_paths: &mut BTreeSet, + found_paths: &mut HashSet, modified_tests: &Vec, poisoned: &mut bool, ) -> io::Result<()> { @@ -1128,7 +1128,7 @@ fn not_a_digit(c: char) -> bool { !c.is_digit(10) } -fn check_overlapping_tests(found_paths: &BTreeSet) { +fn check_overlapping_tests(found_paths: &HashSet) { let mut collisions = Vec::new(); for path in found_paths { for ancestor in path.ancestors().skip(1) { @@ -1138,6 +1138,7 @@ fn check_overlapping_tests(found_paths: &BTreeSet) { } } if !collisions.is_empty() { + collisions.sort(); let collisions: String = collisions .into_iter() .map(|(path, check_parent)| format!("test {path:?} clashes with {check_parent:?}\n")) From bcfdf3307bcc0246dbe6ac709ed695a0a809c2ea Mon Sep 17 00:00:00 2001 From: klensy Date: Wed, 24 Jan 2024 14:58:59 +0300 Subject: [PATCH 04/17] add fixme about walking tests tree --- src/tools/compiletest/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 543304694f620..667358b1a6e31 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -675,6 +675,8 @@ fn collect_tests_from_dir( // Add each `.rs` file as a test, and recurse further on any // subdirectories we find, except for `aux` directories. + // FIXME: this walks full tests tree, even if we have something to ignore + // use walkdir/ignore like in tidy? for file in fs::read_dir(dir)? { let file = file?; let file_path = file.path(); From 4a2939bcd24f6bf81bd8e1e82f349c783bca89e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 30 Dec 2023 19:47:31 +0100 Subject: [PATCH 05/17] Gate PR CI on clippy correctness lints --- src/ci/docker/host-x86_64/mingw-check/Dockerfile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index f8fcda5070fab..30d3a52d82b82 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -40,13 +40,9 @@ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/ ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 -# Run clippy just to make sure it doesn't error out; we don't actually want to gate on the warnings -# though. -# Ideally we'd use stage 1, but that ICEs: https://github.com/rust-lang/rust-clippy/issues/11230 - ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ - python3 ../x.py clippy --stage 0 -Awarnings && \ + python3 ../x.py clippy compiler -Aclippy::all -Dclippy::correctness && \ python3 ../x.py build --stage 0 src/tools/build-manifest && \ python3 ../x.py test --stage 0 src/tools/compiletest && \ python3 ../x.py test --stage 0 core alloc std test proc_macro && \ From cb024ba6e386242c5bea20fcc613c7edbc48f290 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 11 Feb 2024 21:36:12 +0000 Subject: [PATCH 06/17] is_closure_like --- .../src/diagnostics/conflict_errors.rs | 4 ++-- .../src/diagnostics/mutability_errors.rs | 11 +++++------ .../src/type_check/input_output.rs | 2 +- compiler/rustc_codegen_llvm/src/attributes.rs | 2 +- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 6 +++--- .../src/transform/check_consts/mod.rs | 2 +- compiler/rustc_hir/src/def.rs | 6 ++++++ compiler/rustc_hir_typeck/src/check.rs | 3 +-- compiler/rustc_hir_typeck/src/gather_locals.rs | 2 +- compiler/rustc_middle/src/mir/pretty.rs | 2 +- compiler/rustc_middle/src/ty/closure.rs | 4 ++-- compiler/rustc_middle/src/ty/instance.rs | 7 ++----- compiler/rustc_middle/src/ty/util.rs | 16 +++++++++------- .../src/coverage/spans/from_mir.rs | 4 ++-- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_passes/src/upvars.rs | 2 +- .../clippy/clippy_lints/src/redundant_locals.rs | 2 +- 17 files changed, 40 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index f87269960bc84..c6d312c922cd4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -3161,7 +3161,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) -> Option> { // Define a fallback for when we can't match a closure. let fallback = || { - let is_closure = self.infcx.tcx.is_closure_or_coroutine(self.mir_def_id().to_def_id()); + let is_closure = self.infcx.tcx.is_closure_like(self.mir_def_id().to_def_id()); if is_closure { None } else { @@ -3372,7 +3372,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { sig: ty::PolyFnSig<'tcx>, ) -> Option> { debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig); - let is_closure = self.infcx.tcx.is_closure_or_coroutine(did.to_def_id()); + let is_closure = self.infcx.tcx.is_closure_like(did.to_def_id()); let fn_hir_id = self.infcx.tcx.local_def_id_to_hir_id(did); let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(fn_hir_id)?; diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 9e7fd45ec19ad..350645e07341b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -67,7 +67,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { local, projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)], } => { - debug_assert!(is_closure_or_coroutine( + debug_assert!(is_closure_like( Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty )); @@ -126,9 +126,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { { item_msg = access_place_desc; debug_assert!(self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_ref()); - debug_assert!(is_closure_or_coroutine( - the_place_err.ty(self.body, self.infcx.tcx).ty - )); + debug_assert!(is_closure_like(the_place_err.ty(self.body, self.infcx.tcx).ty)); reason = if self.is_upvar_field_projection(access_place.as_ref()).is_some() { ", as it is a captured variable in a `Fn` closure".to_string() @@ -389,7 +387,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { local, projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)], } => { - debug_assert!(is_closure_or_coroutine( + debug_assert!(is_closure_like( Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty )); @@ -1474,7 +1472,8 @@ fn suggest_ampmut<'tcx>( } } -fn is_closure_or_coroutine(ty: Ty<'_>) -> bool { +/// If the type is a `Coroutine`, `Closure`, or `CoroutineClosure` +fn is_closure_like(ty: Ty<'_>) -> bool { ty.is_closure() || ty.is_coroutine() || ty.is_coroutine_closure() } diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index a5a7ce4ea3e86..af5b635ae6688 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -29,7 +29,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { pub(super) fn check_signature_annotation(&mut self, body: &Body<'tcx>) { let mir_def_id = body.source.def_id().expect_local(); - if !self.tcx().is_closure_or_coroutine(mir_def_id.to_def_id()) { + if !self.tcx().is_closure_like(mir_def_id.to_def_id()) { return; } diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 07c83f1aa089a..f9eaa0d94cbbd 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -479,7 +479,7 @@ pub fn from_fn_attrs<'ll, 'tcx>( // `+multivalue` feature because the purpose of the wasm abi is to match // the WebAssembly specification, which has this feature. This won't be // needed when LLVM enables this `multivalue` feature by default. - if !cx.tcx.is_closure_or_coroutine(instance.def_id()) { + if !cx.tcx.is_closure_like(instance.def_id()) { let abi = cx.tcx.fn_sig(instance.def_id()).skip_binder().abi(); if abi == Abi::Wasm { function_features.push("+multivalue".to_string()); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index b387d0b2258b0..9e23757fceef0 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -229,7 +229,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL, sym::track_caller => { - let is_closure = tcx.is_closure_or_coroutine(did.to_def_id()); + let is_closure = tcx.is_closure_like(did.to_def_id()); if !is_closure && let Some(fn_sig) = fn_sig() @@ -274,7 +274,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } } sym::target_feature => { - if !tcx.is_closure_or_coroutine(did.to_def_id()) + if !tcx.is_closure_like(did.to_def_id()) && let Some(fn_sig) = fn_sig() && fn_sig.skip_binder().unsafety() == hir::Unsafety::Normal { @@ -529,7 +529,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // would result in this closure being compiled without the inherited target features, but this // is probably a poor usage of `#[inline(always)]` and easily avoided by not using the attribute. if tcx.features().target_feature_11 - && tcx.is_closure_or_coroutine(did.to_def_id()) + && tcx.is_closure_like(did.to_def_id()) && codegen_fn_attrs.inline != InlineAttr::Always { let owner_id = tcx.parent(did.to_def_id()); diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 98276ff2e68d6..0eaeb8b808909 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -72,7 +72,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { pub fn fn_sig(&self) -> PolyFnSig<'tcx> { let did = self.def_id().to_def_id(); - if self.tcx.is_closure_or_coroutine(did) { + if self.tcx.is_closure_like(did) { let ty = self.tcx.type_of(did).instantiate_identity(); let ty::Closure(_, args) = ty.kind() else { bug!("type_of closure not ty::Closure") }; args.as_closure().sig() diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 81ec7ddb629e3..a0f7a30c2c31b 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -115,6 +115,12 @@ pub enum DefKind { Impl { of_trait: bool, }, + /// A closure, coroutine, or coroutine-closure. + /// + /// These are all represented with the same `ExprKind::Closure` in the AST and HIR, + /// which makes it difficult to distinguish these during def collection. Therefore, + /// we treat them all the same, and code which needs to distinguish them can match + /// or `hir::ClosureKind` or `type_of`. Closure, } diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index aab78465f8c85..be68b598e7668 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -90,8 +90,7 @@ pub(super) fn check_fn<'a, 'tcx>( // ty.span == binding_span iff this is a closure parameter with no type ascription, // or if it's an implicit `self` parameter traits::SizedArgumentType( - if ty_span == Some(param.span) && tcx.is_closure_or_coroutine(fn_def_id.into()) - { + if ty_span == Some(param.span) && tcx.is_closure_like(fn_def_id.into()) { None } else { ty.map(|ty| ty.hir_id) diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index f9af357f0e79e..4d37f725c9400 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -153,7 +153,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { // ascription, or if it's an implicit `self` parameter traits::SizedArgumentType( if ty_span == ident.span - && self.fcx.tcx.is_closure_or_coroutine(self.fcx.body_id.into()) + && self.fcx.tcx.is_closure_like(self.fcx.body_id.into()) { None } else { diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index b601b465668e9..a011f6114de96 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -491,7 +491,7 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn io::Write) -> io: let kind = tcx.def_kind(def_id); let is_function = match kind { DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) => true, - _ => tcx.is_closure_or_coroutine(def_id), + _ => tcx.is_closure_like(def_id), }; match (kind, body.source.promoted) { (_, Some(i)) => write!(w, "{i:?} in ")?, diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 8ff5b135acae8..7db64504f85ea 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -197,7 +197,7 @@ pub struct ClosureTypeInfo<'tcx> { } fn closure_typeinfo<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ClosureTypeInfo<'tcx> { - debug_assert!(tcx.is_closure_or_coroutine(def.to_def_id())); + debug_assert!(tcx.is_closure_like(def.to_def_id())); let typeck_results = tcx.typeck(def); let user_provided_sig = typeck_results.user_provided_sigs[&def]; let captures = typeck_results.closure_min_captures_flattened(def); @@ -217,7 +217,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn closure_captures(self, def_id: LocalDefId) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] { - if !self.is_closure_or_coroutine(def_id.to_def_id()) { + if !self.is_closure_like(def_id.to_def_id()) { return &[]; }; self.closure_typeinfo(def_id).captures diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 8848d216f5b49..01b7be98b1866 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -465,10 +465,7 @@ impl<'tcx> Instance<'tcx> { ) -> Option> { debug!("resolve(def_id={:?}, args={:?})", def_id, args); // Use either `resolve_closure` or `resolve_for_vtable` - assert!( - !tcx.is_closure_or_coroutine(def_id), - "Called `resolve_for_fn_ptr` on closure: {def_id:?}" - ); + assert!(!tcx.is_closure_like(def_id), "Called `resolve_for_fn_ptr` on closure: {def_id:?}"); Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| { match resolved.def { InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => { @@ -530,7 +527,7 @@ impl<'tcx> Instance<'tcx> { }) ) { - if tcx.is_closure_or_coroutine(def) { + if tcx.is_closure_like(def) { debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}", def, def_id, args); diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 4feaeb0dd0523..c674a868d9fa2 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -541,13 +541,15 @@ impl<'tcx> TyCtxt<'tcx> { Ok(()) } - /// Returns `true` if `def_id` refers to a closure (e.g., `|x| x * 2`). Note - /// that closures have a `DefId`, but the closure *expression* also - /// has a `HirId` that is located within the context where the - /// closure appears (and, sadly, a corresponding `NodeId`, since - /// those are not yet phased out). The parent of the closure's - /// `DefId` will also be the context where it appears. - pub fn is_closure_or_coroutine(self, def_id: DefId) -> bool { + /// Returns `true` if `def_id` refers to a closure, coroutine, or coroutine-closure + /// (i.e. an async closure). These are all represented by `hir::Closure`, and all + /// have the same `DefKind`. + /// + /// Note that closures have a `DefId`, but the closure *expression* also has a + // `HirId` that is located within the context where the closure appears (and, sadly, + // a corresponding `NodeId`, since those are not yet phased out). The parent of + // the closure's `DefId` will also be the context where it appears. + pub fn is_closure_like(self, def_id: DefId) -> bool { matches!(self.def_kind(def_id), DefKind::Closure) } diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 01fae7c0bec86..4ac8dde03a6cf 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -138,7 +138,7 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>( let (span, visible_macro) = unexpand_into_body_span_with_visible_macro(expn_span, body_span)?; - Some(SpanFromMir::new(span, visible_macro, bcb, is_closure_or_coroutine(statement))) + Some(SpanFromMir::new(span, visible_macro, bcb, is_closure_like(statement))) }); let terminator_span = Some(data.terminator()).into_iter().filter_map(move |terminator| { @@ -153,7 +153,7 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>( }) } -fn is_closure_or_coroutine(statement: &Statement<'_>) -> bool { +fn is_closure_like(statement: &Statement<'_>) -> bool { match statement.kind { StatementKind::Assign(box (_, Rvalue::Aggregate(box ref agg_kind, _))) => match agg_kind { AggregateKind::Closure(_, _) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 3376af986531e..a771fa86eb7d1 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1154,7 +1154,7 @@ fn create_fn_mono_item<'tcx>( let def_id = instance.def_id(); if tcx.sess.opts.unstable_opts.profile_closures && def_id.is_local() - && tcx.is_closure_or_coroutine(def_id) + && tcx.is_closure_like(def_id) { crate::util::dump_closure_profile(tcx, instance); } diff --git a/compiler/rustc_passes/src/upvars.rs b/compiler/rustc_passes/src/upvars.rs index ded20c38543d4..4d44e8762b0d1 100644 --- a/compiler/rustc_passes/src/upvars.rs +++ b/compiler/rustc_passes/src/upvars.rs @@ -11,7 +11,7 @@ use rustc_span::Span; pub fn provide(providers: &mut Providers) { providers.upvars_mentioned = |tcx, def_id| { - if !tcx.is_closure_or_coroutine(def_id) { + if !tcx.is_closure_like(def_id) { return None; } diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs index 700a5dd4a8511..6528a7b369f74 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs @@ -101,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals { fn is_by_value_closure_capture(cx: &LateContext<'_>, redefinition: HirId, root_variable: HirId) -> bool { let closure_def_id = cx.tcx.hir().enclosing_body_owner(redefinition); - cx.tcx.is_closure_or_coroutine(closure_def_id.to_def_id()) + cx.tcx.is_closure_like(closure_def_id.to_def_id()) && cx.tcx.closure_captures(closure_def_id).iter().any(|c| { matches!(c.info.capture_kind, UpvarCapture::ByValue) && matches!(c.place.base, PlaceBase::Upvar(upvar) if upvar.var_path.hir_id == root_variable) From 87816378ab4190583df1b74bcfeacb8bc5dd4d70 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 11 Feb 2024 22:09:28 +0000 Subject: [PATCH 07/17] Fix async closures in CTFE --- .../rustc_const_eval/src/interpret/util.rs | 1 + .../src/interpret/validity.rs | 4 +- src/tools/miri/tests/pass/async-closure.rs | 40 +++++++++++++++++++ .../miri/tests/pass/async-closure.stdout | 3 ++ 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/tools/miri/tests/pass/async-closure.rs create mode 100644 src/tools/miri/tests/pass/async-closure.stdout diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 416443f5f4d22..52b79203d2b46 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -34,6 +34,7 @@ where match *ty.kind() { ty::Param(_) => ControlFlow::Break(FoundParam), ty::Closure(def_id, args) + | ty::CoroutineClosure(def_id, args, ..) | ty::Coroutine(def_id, args, ..) | ty::FnDef(def_id, args) => { let instance = ty::InstanceDef::Item(def_id); diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 38aeace02ba4b..dd14542ad8f22 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -236,8 +236,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // Now we know we are projecting to a field, so figure out which one. match layout.ty.kind() { - // coroutines and closures. - ty::Closure(def_id, _) | ty::Coroutine(def_id, _) => { + // coroutines, closures, and coroutine-closures all have upvars that may be named. + ty::Closure(def_id, _) | ty::Coroutine(def_id, _) | ty::CoroutineClosure(def_id, _) => { let mut name = None; // FIXME this should be more descriptive i.e. CapturePlace instead of CapturedVar // https://github.com/rust-lang/project-rfc-2229/issues/46 diff --git a/src/tools/miri/tests/pass/async-closure.rs b/src/tools/miri/tests/pass/async-closure.rs new file mode 100644 index 0000000000000..9b2fc2948bf45 --- /dev/null +++ b/src/tools/miri/tests/pass/async-closure.rs @@ -0,0 +1,40 @@ +#![feature(async_closure, noop_waker, async_fn_traits)] + +use std::future::Future; +use std::pin::pin; +use std::task::*; + +pub fn block_on(fut: impl Future) -> T { + let mut fut = pin!(fut); + let ctx = &mut Context::from_waker(Waker::noop()); + + loop { + match fut.as_mut().poll(ctx) { + Poll::Pending => {} + Poll::Ready(t) => break t, + } + } +} + +async fn call_once(f: impl async FnOnce(DropMe)) { + f(DropMe("world")).await; +} + +#[derive(Debug)] +struct DropMe(&'static str); + +impl Drop for DropMe { + fn drop(&mut self) { + println!("{}", self.0); + } +} + +pub fn main() { + block_on(async { + let b = DropMe("hello"); + let async_closure = async move |a: DropMe| { + println!("{a:?} {b:?}"); + }; + call_once(async_closure).await; + }); +} diff --git a/src/tools/miri/tests/pass/async-closure.stdout b/src/tools/miri/tests/pass/async-closure.stdout new file mode 100644 index 0000000000000..34cfdedc44ace --- /dev/null +++ b/src/tools/miri/tests/pass/async-closure.stdout @@ -0,0 +1,3 @@ +DropMe("world") DropMe("hello") +world +hello From 3856df059ed90b8fd19a82efbfb9da36f68e6bb9 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Mon, 12 Feb 2024 15:39:32 +0900 Subject: [PATCH 08/17] Dejargnonize subst --- .../src/diagnostics/conflict_errors.rs | 2 +- .../src/region_infer/opaque_types.rs | 24 ++--- .../src/interpret/eval_context.rs | 15 +-- .../rustc_const_eval/src/interpret/operand.rs | 12 ++- .../rustc_const_eval/src/interpret/place.rs | 7 +- .../rustc_const_eval/src/interpret/step.rs | 4 +- .../src/interpret/terminator.rs | 6 +- .../rustc_const_eval/src/interpret/util.rs | 14 +-- .../src/error_codes/E0139.md | 8 +- .../src/error_codes/E0230.md | 6 +- .../src/error_codes/E0231.md | 6 +- .../src/error_codes/E0393.md | 4 +- .../src/error_codes/E0794.md | 4 +- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir_analysis/messages.ftl | 4 +- .../rustc_hir_analysis/src/astconv/bounds.rs | 13 +-- .../src/astconv/generics.rs | 8 +- .../rustc_hir_analysis/src/astconv/mod.rs | 18 ++-- .../src/astconv/object_safety.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 6 +- .../src/check/compare_impl_item.rs | 18 ++-- .../rustc_hir_analysis/src/check/dropck.rs | 4 +- compiler/rustc_hir_analysis/src/check/mod.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 42 +++++---- .../src/coherence/builtin.rs | 2 +- .../src/collect/generics_of.rs | 2 +- .../src/collect/resolve_bound_vars.rs | 3 +- .../src/constrained_generic_params.rs | 2 +- compiler/rustc_hir_analysis/src/errors.rs | 4 +- .../src/impl_wf_check/min_specialization.rs | 14 +-- .../src/outlives/implicit_infer.rs | 6 +- .../rustc_hir_analysis/src/variance/mod.rs | 8 +- compiler/rustc_hir_typeck/src/check.rs | 2 +- compiler/rustc_hir_typeck/src/coercion.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 30 +++--- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 8 +- .../src/fn_ctxt/suggestions.rs | 14 +-- .../rustc_hir_typeck/src/method/confirm.rs | 32 ++++--- compiler/rustc_hir_typeck/src/method/mod.rs | 4 +- compiler/rustc_hir_typeck/src/method/probe.rs | 12 +-- compiler/rustc_hir_typeck/src/place_op.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 4 +- .../{substitute.rs => instantiate.rs} | 22 ++--- .../rustc_infer/src/infer/canonical/mod.rs | 14 +-- .../src/infer/canonical/query_response.rs | 91 ++++++++++--------- compiler/rustc_infer/src/infer/mod.rs | 24 ++--- .../rustc_infer/src/infer/opaque_types.rs | 2 +- .../src/infer/outlives/test_type_match.rs | 4 +- .../rustc_infer/src/infer/outlives/verify.rs | 2 +- .../src/infer/relate/generalize.rs | 10 +- .../rustc_infer/src/infer/type_variable.rs | 2 +- compiler/rustc_infer/src/traits/util.rs | 3 +- compiler/rustc_middle/src/infer/canonical.rs | 2 +- .../rustc_middle/src/mir/interpret/queries.rs | 18 ++-- compiler/rustc_middle/src/mir/mono.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 4 +- compiler/rustc_middle/src/traits/mod.rs | 2 +- compiler/rustc_middle/src/traits/select.rs | 3 +- compiler/rustc_middle/src/traits/util.rs | 2 +- compiler/rustc_middle/src/ty/_match.rs | 2 +- compiler/rustc_middle/src/ty/consts.rs | 2 +- compiler/rustc_middle/src/ty/fold.rs | 4 +- compiler/rustc_middle/src/ty/generic_args.rs | 26 +++--- compiler/rustc_middle/src/ty/generics.rs | 4 +- compiler/rustc_middle/src/ty/instance.rs | 16 ++-- compiler/rustc_middle/src/ty/mod.rs | 4 +- .../src/ty/normalize_erasing_regions.rs | 12 +-- compiler/rustc_middle/src/ty/opaque_types.rs | 8 +- compiler/rustc_middle/src/ty/predicate.rs | 30 +++--- compiler/rustc_middle/src/ty/sty.rs | 30 +++--- .../rustc_middle/src/ty/typeck_results.rs | 22 ++--- compiler/rustc_mir_build/src/thir/cx/expr.rs | 4 +- compiler/rustc_mir_build/src/thir/util.rs | 2 +- compiler/rustc_mir_transform/src/add_retag.rs | 4 +- .../src/deduce_param_attrs.rs | 4 +- .../src/function_item_references.rs | 8 +- compiler/rustc_mir_transform/src/gvn.rs | 16 ++-- .../rustc_mir_transform/src/inline/cycle.rs | 4 +- .../rustc_mir_transform/src/instsimplify.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 8 +- compiler/rustc_mir_transform/src/ref_prop.rs | 8 +- compiler/rustc_mir_transform/src/shim.rs | 6 +- compiler/rustc_mir_transform/src/ssa.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 8 +- .../rustc_monomorphize/src/polymorphize.rs | 2 +- compiler/rustc_passes/src/dead.rs | 4 +- compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 6 +- compiler/rustc_smir/src/rustc_smir/context.rs | 2 +- compiler/rustc_symbol_mangling/src/legacy.rs | 2 +- compiler/rustc_symbol_mangling/src/v0.rs | 4 +- .../src/solve/assembly/structural_traits.rs | 2 +- .../src/solve/eval_ctxt/canonical.rs | 19 ++-- .../src/solve/eval_ctxt/select.rs | 6 +- .../src/solve/normalizes_to/inherent.rs | 12 +-- .../src/solve/trait_goals.rs | 6 +- .../src/traits/coherence.rs | 18 ++-- .../traits/error_reporting/infer_ctxt_ext.rs | 2 +- .../error_reporting/on_unimplemented.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 4 +- .../error_reporting/type_err_ctxt_ext.rs | 30 +++--- .../rustc_trait_selection/src/traits/mod.rs | 8 +- .../src/traits/object_safety.rs | 6 +- .../src/traits/project.rs | 6 +- .../traits/query/type_op/ascribe_user_type.rs | 2 +- .../query/type_op/implied_outlives_bounds.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 2 +- .../src/traits/select/confirmation.rs | 6 +- .../src/traits/select/mod.rs | 6 +- .../src/traits/specialize/mod.rs | 24 ++--- .../rustc_trait_selection/src/traits/util.rs | 2 +- .../src/traits/vtable.rs | 2 +- .../rustc_trait_selection/src/traits/wf.rs | 2 +- .../src/normalize_projection_ty.rs | 2 +- compiler/rustc_ty_utils/src/abi.rs | 4 +- compiler/rustc_ty_utils/src/layout.rs | 6 +- compiler/rustc_ty_utils/src/needs_drop.rs | 11 ++- compiler/rustc_ty_utils/src/opaque_types.rs | 14 +-- .../rustc_ty_utils/src/representability.rs | 8 +- compiler/rustc_type_ir/src/flags.rs | 2 +- compiler/rustc_type_ir/src/region_kind.rs | 10 +- compiler/rustc_type_ir/src/ty_kind.rs | 6 +- compiler/stable_mir/src/compiler_interface.rs | 2 +- compiler/stable_mir/src/mir/mono.rs | 2 +- src/librustdoc/clean/mod.rs | 14 ++- src/librustdoc/clean/types.rs | 6 +- src/librustdoc/core.rs | 10 +- 128 files changed, 574 insertions(+), 541 deletions(-) rename compiler/rustc_infer/src/infer/canonical/{substitute.rs => instantiate.rs} (80%) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 44e4dea34817e..8b9b4e926ef47 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -691,7 +691,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably) // borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`. - // These types seem reasonably opaque enough that they could be substituted with their + // These types seem reasonably opaque enough that they could be instantiated with their // borrowed variants in a function body when we see a move error. let borrow_level = match *ty.kind() { ty::Param(_) => tcx diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 636c174e002d2..cd2fe56ca4916 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -45,7 +45,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// be allowed: /// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }` /// - /// Then we map the regions in both the type and the subst to their + /// Then we map the regions in both the type and the generic parameters to their /// `external_name` giving `concrete_type = &'a i32`, /// `args = ['static, 'a]`. This will then allow /// `infer_opaque_definition_from_instantiation` to determine that @@ -77,9 +77,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { let args = opaque_type_key.args; debug!(?concrete_type, ?args); - let mut subst_regions = vec![self.universal_regions.fr_static]; + let mut arg_regions = vec![self.universal_regions.fr_static]; - let to_universal_region = |vid, subst_regions: &mut Vec<_>| { + let to_universal_region = |vid, arg_regions: &mut Vec<_>| { trace!(?vid); let scc = self.constraint_sccs.scc(vid); trace!(?scc); @@ -88,11 +88,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { }) { Some(region) => { let vid = self.universal_regions.to_region_vid(region); - subst_regions.push(vid); + arg_regions.push(vid); region } None => { - subst_regions.push(vid); + arg_regions.push(vid); ty::Region::new_error_with_message( infcx.tcx, concrete_type.span, @@ -106,10 +106,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { // This will ensure they get precedence when folding the regions in the concrete type. if let Some(&ci) = member_constraints.get(&opaque_type_key) { for &vid in self.member_constraints.choice_regions(ci) { - to_universal_region(vid, &mut subst_regions); + to_universal_region(vid, &mut arg_regions); } } - debug!(?subst_regions); + debug!(?arg_regions); // Next, insert universal regions from args, so we can translate regions that appear // in them but are not subject to member constraints, for instance closure args. @@ -119,18 +119,18 @@ impl<'tcx> RegionInferenceContext<'tcx> { return region; } let vid = self.to_region_vid(region); - to_universal_region(vid, &mut subst_regions) + to_universal_region(vid, &mut arg_regions) }); debug!(?universal_args); - debug!(?subst_regions); + debug!(?arg_regions); // Deduplicate the set of regions while keeping the chosen order. - let subst_regions = subst_regions.into_iter().collect::>(); - debug!(?subst_regions); + let arg_regions = arg_regions.into_iter().collect::>(); + debug!(?arg_regions); let universal_concrete_type = infcx.tcx.fold_regions(concrete_type, |region, _| match *region { - ty::ReVar(vid) => subst_regions + ty::ReVar(vid) => arg_regions .iter() .find(|ur_vid| self.eval_equal(vid, **ur_vid)) .and_then(|ur_vid| self.definitions[*ur_vid].external_name) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index dd9dfe3fe7983..ffab8f5e555d6 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -554,18 +554,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Call this on things you got out of the MIR (so it is as generic as the current /// stack frame), to bring it into the proper environment for this interpreter. - pub(super) fn subst_from_current_frame_and_normalize_erasing_regions< + pub(super) fn instantiate_from_current_frame_and_normalize_erasing_regions< T: TypeFoldable>, >( &self, value: T, ) -> Result { - self.subst_from_frame_and_normalize_erasing_regions(self.frame(), value) + self.instantiate_from_frame_and_normalize_erasing_regions(self.frame(), value) } /// Call this on things you got out of the MIR (so it is as generic as the provided /// stack frame), to bring it into the proper environment for this interpreter. - pub(super) fn subst_from_frame_and_normalize_erasing_regions>>( + pub(super) fn instantiate_from_frame_and_normalize_erasing_regions< + T: TypeFoldable>, + >( &self, frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>, value: T, @@ -656,7 +658,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let layout = from_known_layout(self.tcx, self.param_env, layout, || { let local_ty = frame.body.local_decls[local].ty; - let local_ty = self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty)?; + let local_ty = + self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?; self.layout_of(local_ty) })?; @@ -791,8 +794,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Make sure all the constants required by this frame evaluate successfully (post-monomorphization check). if M::POST_MONO_CHECKS { for &const_ in &body.required_consts { - let c = - self.subst_from_current_frame_and_normalize_erasing_regions(const_.const_)?; + let c = self + .instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?; c.eval(*self.tcx, self.param_env, Some(const_.span)).map_err(|err| { err.emit_note(*self.tcx); err diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 4653c9016c698..317e5673b51bb 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -696,9 +696,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("eval_place_to_op: got {:?}", op); // Sanity-check the type we ended up with. if cfg!(debug_assertions) { - let normalized_place_ty = self.subst_from_current_frame_and_normalize_erasing_regions( - mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty, - )?; + let normalized_place_ty = self + .instantiate_from_current_frame_and_normalize_erasing_regions( + mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty, + )?; if !mir_assign_valid_types( *self.tcx, self.param_env, @@ -731,8 +732,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &Copy(place) | &Move(place) => self.eval_place_to_op(place, layout)?, Constant(constant) => { - let c = - self.subst_from_current_frame_and_normalize_erasing_regions(constant.const_)?; + let c = self.instantiate_from_current_frame_and_normalize_erasing_regions( + constant.const_, + )?; // This can still fail: // * During ConstProp, with `TooGeneric` or since the `required_consts` were not all diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 772445f4f622e..03d1dc9fd3d64 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -542,9 +542,10 @@ where trace!("{:?}", self.dump_place(&place)); // Sanity-check the type we ended up with. if cfg!(debug_assertions) { - let normalized_place_ty = self.subst_from_current_frame_and_normalize_erasing_regions( - mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty, - )?; + let normalized_place_ty = self + .instantiate_from_current_frame_and_normalize_erasing_regions( + mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty, + )?; if !mir_assign_valid_types( *self.tcx, self.param_env, diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index f0f1008aba80b..23f3d7eb67dae 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -235,7 +235,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } NullaryOp(ref null_op, ty) => { - let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?; + let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?; let layout = self.layout_of(ty)?; if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op && layout.is_unsized() @@ -276,7 +276,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Cast(cast_kind, ref operand, cast_ty) => { let src = self.eval_operand(operand, None)?; let cast_ty = - self.subst_from_current_frame_and_normalize_erasing_regions(cast_ty)?; + self.instantiate_from_current_frame_and_normalize_erasing_regions(cast_ty)?; self.cast(&src, cast_kind, cast_ty, &dest)?; } diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index ff20fc5092c60..4037220e5ed4b 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -173,7 +173,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Drop { place, target, unwind, replace: _ } => { let frame = self.frame(); let ty = place.ty(&frame.body.local_decls, *self.tcx).ty; - let ty = self.subst_from_frame_and_normalize_erasing_regions(frame, ty)?; + let ty = self.instantiate_from_frame_and_normalize_erasing_regions(frame, ty)?; let instance = Instance::resolve_drop_in_place(*self.tcx, ty); if let ty::InstanceDef::DropGlue(_, None) = instance.def { // This is the branch we enter if and only if the dropped type has no drop glue @@ -672,8 +672,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Construct the destination place for this argument. At this point all // locals are still dead, so we cannot construct a `PlaceTy`. let dest = mir::Place::from(local); - // `layout_of_local` does more than just the substitution we need to get the - // type, but the result gets cached so this avoids calling the substitution + // `layout_of_local` does more than just the instantiation we need to get the + // type, but the result gets cached so this avoids calling the instantiation // query *again* the next time this local is accessed. let ty = self.layout_of_local(self.frame(), local, None)?.ty; if Some(local) == body.spread_arg { diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 416443f5f4d22..d15dd1bee1918 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -19,11 +19,11 @@ where } struct FoundParam; - struct UsedParamsNeedSubstVisitor<'tcx> { + struct UsedParamsNeedInstantiationVisitor<'tcx> { tcx: TyCtxt<'tcx>, } - impl<'tcx> TypeVisitor> for UsedParamsNeedSubstVisitor<'tcx> { + impl<'tcx> TypeVisitor> for UsedParamsNeedInstantiationVisitor<'tcx> { type BreakTy = FoundParam; fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { @@ -38,17 +38,17 @@ where | ty::FnDef(def_id, args) => { let instance = ty::InstanceDef::Item(def_id); let unused_params = self.tcx.unused_generic_params(instance); - for (index, subst) in args.into_iter().enumerate() { + for (index, arg) in args.into_iter().enumerate() { let index = index .try_into() .expect("more generic parameters than can fit into a `u32`"); // Only recurse when generic parameters in fns, closures and coroutines // are used and have to be instantiated. // - // Just in case there are closures or coroutines within this subst, + // Just in case there are closures or coroutines within this arg, // recurse. - if unused_params.is_used(index) && subst.has_param() { - return subst.visit_with(self); + if unused_params.is_used(index) && arg.has_param() { + return arg.visit_with(self); } } ControlFlow::Continue(()) @@ -65,7 +65,7 @@ where } } - let mut vis = UsedParamsNeedSubstVisitor { tcx }; + let mut vis = UsedParamsNeedInstantiationVisitor { tcx }; if matches!(ty.visit_with(&mut vis), ControlFlow::Break(FoundParam)) { throw_inval!(TooGeneric); } else { diff --git a/compiler/rustc_error_codes/src/error_codes/E0139.md b/compiler/rustc_error_codes/src/error_codes/E0139.md index a116cf29395fa..4f7f65689c631 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0139.md +++ b/compiler/rustc_error_codes/src/error_codes/E0139.md @@ -22,9 +22,9 @@ fn foo(x: Vec) { In this specific case there's a good chance that the transmute is harmless (but this is not guaranteed by Rust). However, when alignment and enum optimizations come into the picture, it's quite likely that the sizes may or may not match -with different type parameter substitutions. It's not possible to check this for -_all_ possible types, so `transmute()` simply only accepts types without any -unsubstituted type parameters. +with different type parameter instantiations. It's not possible to check this +for _all_ possible types, so `transmute()` simply only accepts types without any +uninstantiated type parameters. If you need this, there's a good chance you're doing something wrong. Keep in mind that Rust doesn't guarantee much about the layout of different structs @@ -32,7 +32,7 @@ mind that Rust doesn't guarantee much about the layout of different structs there is a solution that avoids the transmute entirely, try it instead. If it's possible, hand-monomorphize the code by writing the function for each -possible type substitution. It's possible to use traits to do this cleanly, +possible type instantiation. It's possible to use traits to do this cleanly, for example: ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0230.md b/compiler/rustc_error_codes/src/error_codes/E0230.md index 87ea90e73c902..c30a7e38e9c48 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0230.md +++ b/compiler/rustc_error_codes/src/error_codes/E0230.md @@ -15,9 +15,9 @@ There will be an error about `bool` not implementing `Index`, followed by a note saying "the type `bool` cannot be indexed by `u8`". As you can see, you can specify type parameters in curly braces for -substitution with the actual types (using the regular format string syntax) in -a given situation. Furthermore, `{Self}` will substitute to the type (in this -case, `bool`) that we tried to use. +instantiation with the actual types (using the regular format string syntax) in +a given situation. Furthermore, `{Self}` will be instantiated to the type (in +this case, `bool`) that we tried to use. This error appears when the curly braces contain an identifier which doesn't match with any of the type parameters or the string `Self`. This might happen diff --git a/compiler/rustc_error_codes/src/error_codes/E0231.md b/compiler/rustc_error_codes/src/error_codes/E0231.md index a1aaf90df496a..b22e3c7082a8a 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0231.md +++ b/compiler/rustc_error_codes/src/error_codes/E0231.md @@ -15,9 +15,9 @@ there will be an error about `bool` not implementing `Index`, followed by a note saying "the type `bool` cannot be indexed by `u8`". As you can see, you can specify type parameters in curly braces for -substitution with the actual types (using the regular format string syntax) in -a given situation. Furthermore, `{Self}` will substitute to the type (in this -case, `bool`) that we tried to use. +instantiation with the actual types (using the regular format string syntax) in +a given situation. Furthermore, `{Self}` will be instantiated to the type (in +this case, `bool`) that we tried to use. This error appears when the curly braces do not contain an identifier. Please add one of the same name as a type parameter. If you intended to use literal diff --git a/compiler/rustc_error_codes/src/error_codes/E0393.md b/compiler/rustc_error_codes/src/error_codes/E0393.md index 3e853cf1b8a36..50225b25163fe 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0393.md +++ b/compiler/rustc_error_codes/src/error_codes/E0393.md @@ -12,12 +12,12 @@ fn together_we_will_rule_the_galaxy(son: &A) {} ``` A trait object is defined over a single, fully-defined trait. With a regular -default parameter, this parameter can just be substituted in. However, if the +default parameter, this parameter can just be instantiated in. However, if the default parameter is `Self`, the trait changes for each concrete type; i.e. `i32` will be expected to implement `A`, `bool` will be expected to implement `A`, etc... These types will not share an implementation of a fully-defined trait; instead they share implementations of a trait with -different parameters substituted in for each implementation. This is +different parameters instantiated in for each implementation. This is irreconcilable with what we need to make a trait object work, and is thus disallowed. Making the trait concrete by explicitly specifying the value of the defaulted parameter will fix this issue. Fixed example: diff --git a/compiler/rustc_error_codes/src/error_codes/E0794.md b/compiler/rustc_error_codes/src/error_codes/E0794.md index c8f73de95a214..dcbe2b97c852f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0794.md +++ b/compiler/rustc_error_codes/src/error_codes/E0794.md @@ -14,7 +14,7 @@ let _ = foo::<'static>; The type of a concrete instance of a generic function is universally quantified over late-bound lifetime parameters. This is because we want the function to -work for any lifetime substituted for the late-bound lifetime parameter, no +work for any lifetime instantiated for the late-bound lifetime parameter, no matter where the function is called. Consequently, it doesn't make sense to specify arguments for late-bound lifetime parameters, since they are not resolved until the function's call site(s). @@ -56,7 +56,7 @@ let bar_fn3 = bar::; // OK In the definition of `bar`, the lifetime parameter `'a` is late-bound, while `'b` is early-bound. This is reflected in the type annotation for `bar_fn`, -where `'a` is universally quantified and `'b` is substituted by a specific +where `'a` is universally quantified and `'b` is instantiated with a specific lifetime. It is not allowed to explicitly specify early-bound lifetime arguments when late-bound lifetime parameters are present (as for `bar_fn2`, see [issue #42868](https://github.com/rust-lang/rust/issues/42868)), although diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index a7a1c69b9bed6..85d30112514d5 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2536,7 +2536,7 @@ pub struct OpaqueTy<'hir> { /// lifetimes that are captured from the function signature they originate from. /// /// This is done by generating a new early-bound lifetime parameter local to the - /// opaque which is substituted in the function signature with the late-bound + /// opaque which is instantiated in the function signature with the late-bound /// lifetime. /// /// This mapping associated a captured lifetime (first parameter) with the new diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index d6f604c180bf6..4e96393bb9bd7 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -131,6 +131,8 @@ hir_analysis_function_not_have_default_implementation = function doesn't have a hir_analysis_functions_names_duplicated = functions names are duplicated .note = all `#[rustc_must_implement_one_of]` arguments must be unique +hir_analysis_generic_args_on_overridden_impl = could not resolve generic parameters on overridden impl + hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default` .label = cannot specialize default item `{$ident}` .ok_label = parent `impl` is here @@ -365,8 +367,6 @@ hir_analysis_static_mut_ref_lint = {$shared}reference of mutable static is disco hir_analysis_static_specialize = cannot specialize on `'static` lifetime -hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl - hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature .note = this item must mention the opaque type in its signature in order to be able to register hidden types diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs index 1ae267d1a4059..7157382c883ed 100644 --- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -336,12 +336,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { let projection_ty = if let ty::AssocKind::Fn = assoc_kind { let mut emitted_bad_param_err = None; - // If we have an method return type bound, then we need to substitute + // If we have an method return type bound, then we need to instantiate // the method's early bound params with suitable late-bound params. let mut num_bound_vars = candidate.bound_vars().len(); let args = candidate.skip_binder().args.extend_to(tcx, assoc_item.def_id, |param, _| { - let subst = match param.kind { + let arg = match param.kind { ty::GenericParamDefKind::Lifetime => ty::Region::new_bound( tcx, ty::INNERMOST, @@ -379,7 +379,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { } }; num_bound_vars += 1; - subst + arg }); // Next, we need to check that the return-type notation is being used on @@ -402,12 +402,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { // Finally, move the fn return type's bound vars over to account for the early bound // params (and trait ref's late bound params). This logic is very similar to - // `Predicate::subst_supertrait`, and it's no coincidence why. + // `rustc_middle::ty::predicate::Clause::instantiate_supertrait` + // and it's no coincidence why. let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output); - let subst_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args); + let instantiation_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args); let bound_vars = tcx.late_bound_vars(binding.hir_id); - ty::Binder::bind_with_vars(subst_output, bound_vars) + ty::Binder::bind_with_vars(instantiation_output, bound_vars) } else { // Append the generic arguments of the associated type to the `trait_ref`. candidate.map_bound(|trait_ref| { diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index aa826c1f26805..614e5f9d32b7c 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -1,6 +1,6 @@ use super::IsMethodCall; use crate::astconv::{ - errors::prohibit_assoc_ty_binding, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, + errors::prohibit_assoc_ty_binding, CreateInstantiationsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition, }; use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs}; @@ -177,9 +177,9 @@ pub fn create_args_for_parent_generic_args<'tcx: 'a, 'a>( has_self: bool, self_ty: Option>, arg_count: &GenericArgCountResult, - ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>, + ctx: &mut impl CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>, ) -> GenericArgsRef<'tcx> { - // Collect the segments of the path; we need to substitute arguments + // Collect the segments of the path; we need to instantiate arguments // for parameters throughout the entire path (wherever there are // generic parameters). let mut parent_defs = tcx.generics_of(def_id); @@ -191,7 +191,7 @@ pub fn create_args_for_parent_generic_args<'tcx: 'a, 'a>( } // We manually build up the generic arguments, rather than using convenience - // methods in `subst.rs`, so that we can iterate over the arguments and + // methods in `rustc_middle/src/ty/generic_args.rs`, so that we can iterate over the arguments and // parameters in lock-step linearly, instead of trying to match each pair. let mut args: SmallVec<[ty::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count); // Iterate over each segment of the path. diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 1ae3ebaebbbb7..6b6be2b3d53e8 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -214,7 +214,7 @@ pub struct GenericArgCountResult { pub correct: Result<(), GenericArgCountMismatch>, } -pub trait CreateSubstsForGenericArgsCtxt<'a, 'tcx> { +pub trait CreateInstantiationsForGenericArgsCtxt<'a, 'tcx> { fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool); fn provided_kind( @@ -366,8 +366,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if generics.has_self { if generics.parent.is_some() { - // The parent is a trait so it should have at least one subst - // for the `Self` type. + // The parent is a trait so it should have at least one + // generic parameter for the `Self` type. assert!(!parent_args.is_empty()) } else { // This item (presumably a trait) needs a self-type. @@ -402,7 +402,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { return (tcx.mk_args(parent_args), arg_count); } - struct SubstsForAstPathCtxt<'a, 'tcx> { + struct InstantiationsForAstPathCtxt<'a, 'tcx> { astconv: &'a (dyn AstConv<'tcx> + 'a), def_id: DefId, generic_args: &'a GenericArgs<'tcx>, @@ -411,7 +411,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { infer_args: bool, } - impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for SubstsForAstPathCtxt<'a, 'tcx> { + impl<'a, 'tcx> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx> + for InstantiationsForAstPathCtxt<'a, 'tcx> + { fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool) { if did == self.def_id { (Some(self.generic_args), self.infer_args) @@ -556,7 +558,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } - let mut args_ctx = SubstsForAstPathCtxt { + let mut args_ctx = InstantiationsForAstPathCtxt { astconv: self, def_id, span, @@ -2412,8 +2414,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let self_ty = self.tcx().type_of(parent).instantiate_identity(); let generic_self_ty = ty::GenericArg::from(self_ty); - let substs = self.tcx().mk_args_from_iter(std::iter::once(generic_self_ty)); - sig.instantiate(self.tcx(), substs) + let args = self.tcx().mk_args_from_iter(std::iter::once(generic_self_ty)); + sig.instantiate(self.tcx(), args) } else { sig.instantiate_identity() }; diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index 2d85ad5789ecc..cbbf560076e27 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -175,7 +175,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => { let pred = bound_predicate.rebind(pred); - // A `Self` within the original bound will be substituted with a + // A `Self` within the original bound will be instantiated with a // `trait_object_dummy_self`, so check for that. let references_self = match pred.skip_binder().term.unpack() { ty::TermKind::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()), diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 7250dc81faf8b..ae0f27a6f559b 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1030,7 +1030,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) match t.kind() { ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)), ty::Array(ty, _) => check_non_exhaustive(tcx, *ty), - ty::Adt(def, subst) => { + ty::Adt(def, args) => { if !def.did().is_local() { let non_exhaustive = def.is_variant_list_non_exhaustive() || def @@ -1042,13 +1042,13 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) return ControlFlow::Break(( def.descr(), def.did(), - subst, + args, non_exhaustive, )); } } def.all_fields() - .map(|field| field.ty(tcx, subst)) + .map(|field| field.ty(tcx, args)) .try_for_each(|t| check_non_exhaustive(tcx, t)) } _ => ControlFlow::Continue(()), diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 6edd68f1baebe..69a02b73a7987 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -125,9 +125,9 @@ fn check_method_is_structurally_compatible<'tcx>( /// <'b> fn(t: &'i0 U0, m: &'b N0) -> Foo /// ``` /// -/// We now want to extract and substitute the type of the *trait* +/// We now want to extract and instantiate the type of the *trait* /// method and compare it. To do so, we must create a compound -/// substitution by combining `trait_to_impl_args` and +/// instantiation by combining `trait_to_impl_args` and /// `impl_to_placeholder_args`, and also adding a mapping for the method /// type parameters. We extend the mapping to also include /// the method parameters. @@ -146,11 +146,11 @@ fn check_method_is_structurally_compatible<'tcx>( /// vs `'b`). However, the normal subtyping rules on fn types handle /// this kind of equivalency just fine. /// -/// We now use these substitutions to ensure that all declared bounds are -/// satisfied by the implementation's method. +/// We now use these generic parameters to ensure that all declared bounds +/// are satisfied by the implementation's method. /// /// We do this by creating a parameter environment which contains a -/// substitution corresponding to `impl_to_placeholder_args`. We then build +/// generic parameter corresponding to `impl_to_placeholder_args`. We then build /// `trait_to_placeholder_args` and use it to convert the predicates contained /// in the `trait_m` generics to the placeholder form. /// @@ -454,7 +454,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( let impl_trait_ref = tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity(); // First, check a few of the same things as `compare_impl_method`, - // just so we don't ICE during substitution later. + // just so we don't ICE during instantiation later. check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; let trait_to_impl_args = impl_trait_ref.args; @@ -543,7 +543,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // } // ``` // .. to compile. However, since we use both the normalized and unnormalized - // inputs and outputs from the substituted trait signature, we will end up + // inputs and outputs from the instantiated trait signature, we will end up // seeing the hidden type of an RPIT in the signature itself. Naively, this // means that we will use the hidden type to imply the hidden type's own // well-formedness. @@ -699,7 +699,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound // region args that are synthesized during AST lowering. These are args // that are appended to the parent args (trait and trait method). However, - // we're trying to infer the unsubstituted type value of the RPITIT inside + // we're trying to infer the uninstantiated type value of the RPITIT inside // the *impl*, so we can later use the impl's method args to normalize // an RPITIT to a concrete type (`confirm_impl_trait_in_trait_candidate`). // @@ -711,7 +711,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // guarantee that the indices from the trait args and impl args line up. // So to fix this, we subtract the number of trait args and add the number of // impl args to *renumber* these early-bound regions to their corresponding - // indices in the impl's substitutions list. + // indices in the impl's generic parameters list. // // Also, we only need to account for a difference in trait and impl args, // since we previously enforce that the trait method and impl method have the diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 7b60457affa82..82a6b6b6f2cb5 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -124,14 +124,14 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( let infcx = tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(&infcx); - // Take the param-env of the adt and substitute the args that show up in + // Take the param-env of the adt and instantiate the args that show up in // the implementation's self type. This gives us the assumptions that the // self ty of the implementation is allowed to know just from it being a // well-formed adt, since that's all we're allowed to assume while proving // the Drop implementation is not specialized. // // We don't need to normalize this param-env or anything, since we're only - // substituting it with free params, so no additional param-env normalization + // instantiating it with free params, so no additional param-env normalization // can occur on top of what has been done in the param_env query itself. let param_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args); diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index b74431983113a..2f8e065df3303 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -56,7 +56,7 @@ type variable is an instance of a type parameter. That is, given a generic function `fn foo(t: T)`, while checking the function `foo`, the type `ty_param(0)` refers to the type `T`, which is treated in abstract. However, when `foo()` is called, `T` will be -substituted for a fresh type variable `N`. This variable will +instantiated with a fresh type variable `N`. This variable will eventually be resolved to some concrete type (which might itself be a type parameter). diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 646a84b043c82..44a3d2d93740b 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -618,7 +618,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>( // The bounds we that we would require from `to_check` let mut bounds = FxHashSet::default(); - let (regions, types) = GATSubstCollector::visit(gat_def_id.to_def_id(), to_check); + let (regions, types) = GATArgsCollector::visit(gat_def_id.to_def_id(), to_check); // If both regions and types are empty, then this GAT isn't in the // set of types we are checking, and we shouldn't try to do clause analysis @@ -787,34 +787,34 @@ fn test_region_obligations<'tcx>( /// `>::GAT` and adds the arguments `P0..Pm` into /// the two vectors, `regions` and `types` (depending on their kind). For each /// parameter `Pi` also track the index `i`. -struct GATSubstCollector<'tcx> { +struct GATArgsCollector<'tcx> { gat: DefId, - // Which region appears and which parameter index its substituted for + // Which region appears and which parameter index its instantiated with regions: FxHashSet<(ty::Region<'tcx>, usize)>, - // Which params appears and which parameter index its substituted for + // Which params appears and which parameter index its instantiated with types: FxHashSet<(Ty<'tcx>, usize)>, } -impl<'tcx> GATSubstCollector<'tcx> { +impl<'tcx> GATArgsCollector<'tcx> { fn visit>>( gat: DefId, t: T, ) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) { let mut visitor = - GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() }; + GATArgsCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() }; t.visit_with(&mut visitor); (visitor.regions, visitor.types) } } -impl<'tcx> TypeVisitor> for GATSubstCollector<'tcx> { +impl<'tcx> TypeVisitor> for GATArgsCollector<'tcx> { type BreakTy = !; fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Alias(ty::Projection, p) if p.def_id == self.gat => { - for (idx, subst) in p.args.iter().enumerate() { - match subst.unpack() { + for (idx, arg) in p.args.iter().enumerate() { + match arg.unpack() { GenericArgKind::Lifetime(lt) if !lt.is_bound() => { self.regions.insert((lt, idx)); } @@ -1407,14 +1407,14 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id } } - // Check that trait predicates are WF when params are substituted by their defaults. + // Check that trait predicates are WF when params are instantiated with their defaults. // We don't want to overly constrain the predicates that may be written but we want to // catch cases where a default my never be applied such as `struct Foo`. // Therefore we check if a predicate which contains a single type param - // with a concrete default is WF with that default substituted. + // with a concrete default is WF with that default instantiated. // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`. // - // First we build the defaulted substitution. + // First we build the defaulted generic parameters. let args = GenericArgs::for_item(tcx, def_id.to_def_id(), |param, _| { match param.kind { GenericParamDefKind::Lifetime => { @@ -1428,7 +1428,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let default_ty = tcx.type_of(param.def_id).instantiate_identity(); // ... and it's not a dependent default, ... if !default_ty.has_param() { - // ... then substitute it with the default. + // ... then instantiate it with the default. return default_ty.into(); } } @@ -1441,7 +1441,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let default_ct = tcx.const_param_default(param.def_id).instantiate_identity(); // ... and it's not a dependent default, ... if !default_ct.has_param() { - // ... then substitute it with the default. + // ... then instantiate it with the default. return default_ct.into(); } } @@ -1451,7 +1451,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id } }); - // Now we build the substituted predicates. + // Now we build the instantiated predicates. let default_obligations = predicates .predicates .iter() @@ -1483,23 +1483,25 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id } let mut param_count = CountParams::default(); let has_region = pred.visit_with(&mut param_count).is_break(); - let substituted_pred = ty::EarlyBinder::bind(pred).instantiate(tcx, args); + let instantiated_pred = ty::EarlyBinder::bind(pred).instantiate(tcx, args); // Don't check non-defaulted params, dependent defaults (including lifetimes) // or preds with multiple params. - if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region + if instantiated_pred.has_non_region_param() + || param_count.params.len() > 1 + || has_region { None - } else if predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { + } else if predicates.predicates.iter().any(|&(p, _)| p == instantiated_pred) { // Avoid duplication of predicates that contain no parameters, for example. None } else { - Some((substituted_pred, sp)) + Some((instantiated_pred, sp)) } }) .map(|(pred, sp)| { // Convert each of those into an obligation. So if you have // something like `struct Foo`, we would - // take that predicate `T: Copy`, substitute to `String: Copy` + // take that predicate `T: Copy`, instantiated with `String: Copy` // (actually that happens in the previous `flat_map` call), // and then try to prove it (in this case, we'll fail). // diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 5a3878445937b..7d551fbf035a5 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -396,7 +396,7 @@ pub fn coerce_unsized_info<'tcx>( // // To check if this impl is legal, we would walk down // the fields of `Foo` and consider their types with - // both substitutes. We are looking to find that + // both generic parameters. We are looking to find that // exactly one (non-phantom) field has changed its // type, which we will expect to be the pointer that // is becoming fat (we could probably generalize this diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index e5e731bbe8c6d..9cc6c16c12639 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -71,7 +71,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, args: [N#0])`. // // This causes ICEs (#86580) when building the args for Foo in `fn foo() -> Foo { .. }` as - // we substitute the defaults with the partially built args when we build the args. Subst'ing + // we instantiate the defaults with the partially built args when we build the args. Instantiating // the `N#0` on the unevaluated const indexes into the empty args we're in the process of building. // // We fix this by having this function return the parent's generics ourselves and truncating the diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 1aa9c6929f819..c9cf43ddfc887 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1786,7 +1786,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { let bound_predicate = pred.kind(); match bound_predicate.skip_binder() { ty::ClauseKind::Trait(data) => { - // The order here needs to match what we would get from `subst_supertrait` + // The order here needs to match what we would get from + // `rustc_middle::ty::predicate::Clause::instantiate_supertrait` let pred_bound_vars = bound_predicate.bound_vars(); let mut all_bound_vars = bound_vars.clone(); all_bound_vars.extend(pred_bound_vars.iter()); diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 65d1ffa40e2ed..05efad3ccb313 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -119,7 +119,7 @@ pub fn identify_constrained_generic_params<'tcx>( /// * `::Item = T` -- a desugared ProjectionPredicate /// /// When we, for example, try to go over the trait-reference -/// `IntoIter as Trait`, we substitute the impl parameters with fresh +/// `IntoIter as Trait`, we instantiate the impl parameters with fresh /// variables and match them with the impl trait-ref, so we know that /// `$U = IntoIter`. /// diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index bec53693d6c94..cc4336f74d55b 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -372,8 +372,8 @@ pub struct ManualImplementation { } #[derive(Diagnostic)] -#[diag(hir_analysis_substs_on_overridden_impl)] -pub struct SubstsOnOverriddenImpl { +#[diag(hir_analysis_generic_args_on_overridden_impl)] +pub struct GenericArgsOnOverriddenImpl { #[primary_span] pub span: Span, } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 1b6a39d8162e0..beab89971606c 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -34,8 +34,8 @@ //! impl> SpecExtend for I { /* default impl */ } //! ``` //! -//! We get that the subst for `impl2` are `[T, std::vec::IntoIter]`. `T` is -//! constrained to be `::Item`, so we check only +//! We get that the generic pamameters for `impl2` are `[T, std::vec::IntoIter]`. +//! `T` is constrained to be `::Item`, so we check only //! `std::vec::IntoIter` for repeated parameters, which it doesn't have. The //! predicates of `impl1` are only `T: Sized`, which is also a predicate of //! `impl2`. So this specialization is sound. @@ -65,7 +65,7 @@ //! cause use after frees with purely safe code in the same way as specializing //! on traits with methods can. -use crate::errors::SubstsOnOverriddenImpl; +use crate::errors::GenericArgsOnOverriddenImpl; use crate::{constrained_generic_params as cgp, errors}; use rustc_data_structures::fx::FxHashSet; @@ -179,8 +179,8 @@ fn check_constness( } /// Given a specializing impl `impl1`, and the base impl `impl2`, returns two -/// substitutions `(S1, S2)` that equate their trait references. The returned -/// types are expressed in terms of the generics of `impl1`. +/// generic parameters `(S1, S2)` that equate their trait references. +/// The returned types are expressed in terms of the generics of `impl1`. /// /// Example /// @@ -228,13 +228,13 @@ fn get_impl_args( let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env); let Ok(impl2_args) = infcx.fully_resolve(impl2_args) else { let span = tcx.def_span(impl1_def_id); - let guar = tcx.dcx().emit_err(SubstsOnOverriddenImpl { span }); + let guar = tcx.dcx().emit_err(GenericArgsOnOverriddenImpl { span }); return Err(guar); }; Ok((impl1_args, impl2_args)) } -/// Returns a list of all of the unconstrained subst of the given impl. +/// Returns a list of all of the unconstrained generic parameters of the given impl. /// /// For example given the impl: /// diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index 0cb38094ceca5..0c0dbbe7ad9de 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -229,7 +229,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( /// Here, we should fetch the explicit predicates, which /// will give us `U: 'static` and `U: Outer`. The latter we /// can ignore, but we will want to process `U: 'static`, -/// applying the substitution as above. +/// applying the instantiation as above. fn check_explicit_predicates<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, @@ -316,7 +316,7 @@ fn check_explicit_predicates<'tcx>( /// Here, when processing the type of field `outer`, we would request the /// set of implicit predicates computed for `Inner` thus far. This will /// initially come back empty, but in next round we will get `U: 'b`. -/// We then apply the substitution `['b => 'a, U => T]` and thus get the +/// We then apply the instantiation `['b => 'a, U => T]` and thus get the /// requirement that `T: 'a` holds for `Outer`. fn check_inferred_predicates<'tcx>( tcx: TyCtxt<'tcx>, @@ -334,7 +334,7 @@ fn check_inferred_predicates<'tcx>( for (&predicate, &span) in predicates.as_ref().skip_binder() { // `predicate` is `U: 'b` in the example above. - // So apply the substitution to get `T: 'a`. + // So apply the instantiation to get `T: 'a`. let ty::OutlivesPredicate(arg, region) = predicates.rebind(predicate).instantiate(tcx, args); insert_outlives_predicate(tcx, arg, region, span, required_predicates); diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 7d145ea1f23a8..4d5dcbadc4a24 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -172,16 +172,16 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc trait_ref: ty::TraitRef { def_id: _, args, .. }, polarity: _, }) => { - for subst in &args[1..] { - subst.visit_with(&mut collector); + for arg in &args[1..] { + arg.visit_with(&mut collector); } } ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty: ty::AliasTy { args, .. }, term, }) => { - for subst in &args[1..] { - subst.visit_with(&mut collector); + for arg in &args[1..] { + arg.visit_with(&mut collector); } term.visit_with(&mut collector); } diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index aab78465f8c85..9380f9943f3ce 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -123,7 +123,7 @@ pub(super) fn check_fn<'a, 'tcx>( if let ty::Dynamic(..) = declared_ret_ty.kind() { // We have special-cased the case where the function is declared // `-> dyn Foo` and we don't actually relate it to the - // `fcx.ret_coercion`, so just substitute a type variable. + // `fcx.ret_coercion`, so just instantiate a type variable. actual_return_ty = fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span }); debug!("actual_return_ty replaced with {:?}", actual_return_ty); diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 549ad44d7e349..e98ace948f921 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -752,7 +752,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let mut obligations: Vec<_> = predicates .iter() .map(|predicate| { - // For each existential predicate (e.g., `?Self: Clone`) substitute + // For each existential predicate (e.g., `?Self: Clone`) instantiate // the type of the expression (e.g., `usize` in our example above) // and then require that the resulting predicate (e.g., `usize: Clone`) // holds (it does). diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 31c97aab7fb83..31295a106ae36 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1801,7 +1801,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // consistency. But they should be merged as much as possible. let fru_tys = if self.tcx.features().type_changing_struct_update { if adt.is_struct() { - // Make some fresh substitutions for our ADT type. + // Make some fresh generic parameters for our ADT type. let fresh_args = self.fresh_args_for_item(base_expr.span, adt.did()); // We do subtyping on the FRU fields first, so we can // learn exactly what types we expect the base expr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 7eb421ca8f5a9..1d2c88415393f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -15,7 +15,7 @@ use rustc_hir_analysis::astconv::generics::{ check_generic_arg_count_for_call, create_args_for_parent_generic_args, }; use rustc_hir_analysis::astconv::{ - AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch, + AstConv, CreateInstantiationsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, IsMethodCall, PathSeg, }; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; @@ -179,8 +179,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Given the args that we just converted from the HIR, try to - /// canonicalize them and store them as user-given substitutions - /// (i.e., substitutions that must be respected by the NLL check). + /// canonicalize them and store them as user-given parameters + /// (i.e., parameters that must be respected by the NLL check). /// /// This should be invoked **before any unifications have /// occurred**, so that annotations like `Vec<_>` are preserved @@ -733,7 +733,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Err(TypeError::Mismatch); } - // Record all the argument types, with the substitutions + // Record all the argument types, with the args // produced from the above subtyping unification. Ok(Some(formal_args.iter().map(|&ty| self.resolve_vars_if_possible(ty)).collect())) }) @@ -1163,7 +1163,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Now we have to compare the types that the user *actually* // provided against the types that were *expected*. If the user - // did not provide any types, then we want to substitute inference + // did not provide any types, then we want to instantiate inference // variables. If the user provided some types, we may still need // to add defaults. If the user provided *too many* types, that's // a problem. @@ -1253,14 +1253,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, }; - struct CreateCtorSubstsContext<'a, 'tcx> { + struct CreateCtorInstantiationsContext<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, span: Span, path_segs: &'a [PathSeg], infer_args_for_err: &'a FxHashSet, segments: &'tcx [hir::PathSegment<'tcx>], } - impl<'tcx, 'a> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for CreateCtorSubstsContext<'a, 'tcx> { + impl<'tcx, 'a> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx> + for CreateCtorInstantiationsContext<'a, 'tcx> + { fn args_for_def_id( &mut self, def_id: DefId, @@ -1384,7 +1386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { has_self, self_ty.map(|s| s.raw), &arg_count, - &mut CreateCtorSubstsContext { + &mut CreateCtorInstantiationsContext { fcx: self, span, path_segs: &path_segs, @@ -1402,18 +1404,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.add_required_obligations_for_hir(span, def_id, args, hir_id); - // Substitute the values for the type parameters into the type of + // Instantiate the values for the type parameters into the type of // the referenced item. let ty = tcx.type_of(def_id); assert!(!args.has_escaping_bound_vars()); assert!(!ty.skip_binder().has_escaping_bound_vars()); - let ty_substituted = self.normalize(span, ty.instantiate(tcx, args)); + let ty_instantiated = self.normalize(span, ty.instantiate(tcx, args)); if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty { // In the case of `Foo::method` and `>::method`, if `method` // is inherent, there is no `Self` parameter; instead, the impl needs // type parameters, which we can infer by unifying the provided `Self` - // with the substituted impl type. + // with the instantiated impl type. // This also occurs for an enum variant on a type alias. let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args)); let self_ty = self.normalize(span, self_ty); @@ -1434,13 +1436,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted); + debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_instantiated); self.write_args(hir_id, args); - (ty_substituted, res) + (ty_instantiated, res) } - /// Add all the obligations that are required, substituting and normalized appropriately. + /// Add all the obligations that are required, instantiated and normalized appropriately. pub(crate) fn add_required_obligations_for_hir( &self, span: Span, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 6aa986b0df4c9..f0631dd4b5fb8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -21,7 +21,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; }; - let Some(unsubstituted_pred) = self + let Some(uninstantiated_pred) = self .tcx .predicates_of(def_id) .instantiate_identity(self.tcx) @@ -34,7 +34,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let generics = self.tcx.generics_of(def_id); let (predicate_args, predicate_self_type_to_point_at) = - match unsubstituted_pred.kind().skip_binder() { + match uninstantiated_pred.kind().skip_binder() { ty::ClauseKind::Trait(pred) => { (pred.trait_ref.args.to_vec(), Some(pred.self_ty().into())) } @@ -343,10 +343,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind && let generics = self.0.tcx.generics_of(self.1) && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) - && let Some(subst) = + && let Some(arg) = ty::GenericArgs::identity_for_item(self.0.tcx, self.1).get(index as usize) { - ControlFlow::Break(*subst) + ControlFlow::Break(*arg) } else { ty.super_visit_with(self) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 193c9a4b90879..d68e20541ef0f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2133,17 +2133,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr_ty: Ty<'tcx>, ) -> bool { let tcx = self.tcx; - let (adt, substs, unwrap) = match expected.kind() { + let (adt, args, unwrap) = match expected.kind() { // In case Option is wanted, but * is provided, suggest calling new - ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => { - let nonzero_type = substs.type_at(0); // Unwrap option type. - let ty::Adt(adt, substs) = nonzero_type.kind() else { + ty::Adt(adt, args) if tcx.is_diagnostic_item(sym::Option, adt.did()) => { + let nonzero_type = args.type_at(0); // Unwrap option type. + let ty::Adt(adt, args) = nonzero_type.kind() else { return false; }; - (adt, substs, "") + (adt, args, "") } // In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types. - ty::Adt(adt, substs) => (adt, substs, ".unwrap()"), + ty::Adt(adt, args) => (adt, args, ".unwrap()"), _ => return false, }; @@ -2165,7 +2165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ("NonZeroI128", tcx.types.i128), ]; - let int_type = substs.type_at(0); + let int_type = args.type_at(0); let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| { if *t == int_type && self.can_coerce(expr_ty, *t) { Some(nonzero_alias) } else { None } diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 3a44c6c241041..4e9cb92919afb 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -7,7 +7,7 @@ use rustc_hir::GenericArg; use rustc_hir_analysis::astconv::generics::{ check_generic_arg_count_for_call, create_args_for_parent_generic_args, }; -use rustc_hir_analysis::astconv::{AstConv, CreateSubstsForGenericArgsCtxt, IsMethodCall}; +use rustc_hir_analysis::astconv::{AstConv, CreateInstantiationsForGenericArgsCtxt, IsMethodCall}; use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk}; use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; @@ -95,7 +95,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // Adjust the self expression the user provided and obtain the adjusted type. let self_ty = self.adjust_self_ty(unadjusted_self_ty, pick); - // Create substitutions for the method's type parameters. + // Create generic args for the method's type parameters. let rcvr_args = self.fresh_receiver_args(self_ty, pick); let all_args = self.instantiate_method_args(pick, segment, rcvr_args); @@ -246,11 +246,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { target } - /// Returns a set of substitutions for the method *receiver* where all type and region - /// parameters are instantiated with fresh variables. This substitution does not include any + /// Returns a set of generic parameters for the method *receiver* where all type and region + /// parameters are instantiated with fresh variables. This generic paramters does not include any /// parameters declared on the method itself. /// - /// Note that this substitution may include late-bound regions from the impl level. If so, + /// Note that this generic parameters may include late-bound regions from the impl level. If so, /// these are instantiated later in the `instantiate_method_sig` routine. fn fresh_receiver_args( &mut self, @@ -272,8 +272,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self.extract_existential_trait_ref(self_ty, |this, object_ty, principal| { // The object data has no entry for the Self // Type. For the purposes of this method call, we - // substitute the object type itself. This - // wouldn't be a sound substitution in all cases, + // instantiate the object type itself. This + // wouldn't be a sound instantiation in all cases, // since each instance of the object type is a // different existential and hence could match // distinct types (e.g., if `Self` appeared as an @@ -362,16 +362,18 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { IsMethodCall::Yes, ); - // Create subst for early-bound lifetime parameters, combining - // parameters from the type and those from the method. + // Create generic paramters for early-bound lifetime parameters, + // combining parameters from the type and those from the method. assert_eq!(generics.parent_count, parent_args.len()); - struct MethodSubstsCtxt<'a, 'tcx> { + struct MethodInstantiationsCtxt<'a, 'tcx> { cfcx: &'a ConfirmContext<'a, 'tcx>, pick: &'a probe::Pick<'tcx>, seg: &'a hir::PathSegment<'tcx>, } - impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for MethodSubstsCtxt<'a, 'tcx> { + impl<'a, 'tcx> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx> + for MethodInstantiationsCtxt<'a, 'tcx> + { fn args_for_def_id( &mut self, def_id: DefId, @@ -437,7 +439,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { false, None, &arg_count_correct, - &mut MethodSubstsCtxt { cfcx: self, pick, seg }, + &mut MethodInstantiationsCtxt { cfcx: self, pick, seg }, ); // When the method is confirmed, the `args` includes @@ -538,15 +540,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { debug!("instantiate_method_sig(pick={:?}, all_args={:?})", pick, all_args); // Instantiate the bounds on the method with the - // type/early-bound-regions substitutions performed. There can + // type/early-bound-regions instatiations performed. There can // be no late-bound regions appearing here. let def_id = pick.item.def_id; let method_predicates = self.tcx.predicates_of(def_id).instantiate(self.tcx, all_args); - debug!("method_predicates after subst = {:?}", method_predicates); + debug!("method_predicates after instantitation = {:?}", method_predicates); let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, all_args); - debug!("type scheme substituted, sig={:?}", sig); + debug!("type scheme instantiated, sig={:?}", sig); let sig = self.instantiate_binder_with_fresh_vars(sig); debug!("late-bound lifetimes from method instantiated, sig={:?}", sig); diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 804d6ff2cb577..fb969c82d8ae5 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -38,7 +38,7 @@ pub struct MethodCallee<'tcx> { pub args: GenericArgsRef<'tcx>, /// Instantiated method signature, i.e., it has been - /// substituted, normalized, and has had late-bound + /// instantiated, normalized, and has had late-bound /// lifetimes replaced with inference variables. pub sig: ty::FnSig<'tcx>, } @@ -395,7 +395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); let mut obligations = vec![]; - // Instantiate late-bound regions and substitute the trait + // Instantiate late-bound regions and instantiate the trait // parameters into the method type to get the actual method type. // // N.B., instantiate late-bound regions before normalizing the diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index a446c7aa42bb6..d7edc70bce82e 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -111,7 +111,7 @@ pub(crate) struct Candidate<'tcx> { // The way this is handled is through `xform_self_ty`. It contains // the receiver type of this candidate, but `xform_self_ty`, // `xform_ret_ty` and `kind` (which contains the predicates) have the - // generic parameters of this candidate substituted with the *same set* + // generic parameters of this candidate instantiated with the *same set* // of inference variables, which acts as some weird sort of "query". // // When we check out a candidate, we require `xform_self_ty` to be @@ -799,7 +799,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // the `Self` type. An [`ObjectSafetyViolation::SupertraitSelf`] error // will be reported by `object_safety.rs` if the method refers to the // `Self` type anywhere other than the receiver. Here, we use a - // substitution that replaces `Self` with the object type itself. Hence, + // instantiation that replaces `Self` with the object type itself. Hence, // a `&self` method will wind up with an argument type like `&dyn Trait`. let trait_ref = principal.with_self_ty(self.tcx, self_ty); self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| { @@ -1857,8 +1857,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { assert!(!args.has_escaping_bound_vars()); // It is possible for type parameters or early-bound lifetimes - // to appear in the signature of `self`. The substitutions we - // are given do not include type/lifetime parameters for the + // to appear in the signature of `self`. The generic parameters + // we are given do not include type/lifetime parameters for the // method yet. So create fresh variables here for those too, // if there are any. let generics = self.tcx.generics_of(method); @@ -1889,7 +1889,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.instantiate_bound_regions_with_erased(xform_fn_sig) } - /// Gets the type of an impl and generate substitutions with inference vars. + /// Gets the type of an impl and generate generic parameters with inference vars. fn impl_ty_and_args( &self, impl_def_id: DefId, @@ -1913,7 +1913,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// late-bound regions with 'static. Otherwise, if we were going to replace late-bound /// regions with actual region variables as is proper, we'd have to ensure that the same /// region got replaced with the same variable, which requires a bit more coordination - /// and/or tracking the substitution and + /// and/or tracking the instantiations and /// so forth. fn instantiate_bound_regions_with_erased(&self, value: ty::Binder<'tcx, T>) -> T where diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index 1eaaf30043b44..6c5715b323c9e 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -357,7 +357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PlaceOp::Deref => None, PlaceOp::Index => { // We would need to recover the `T` used when we resolve `<_ as Index>::index` - // in try_index_step. This is the subst at index 1. + // in try_index_step. This is the arg at index 1. // // Note: we should *not* use `expr_ty` of index_expr here because autoderef // during coercions can cause type of index_expr to differ from `T` (#72002). diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 94f6c06157efe..c95e7dfbc3db2 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -1,6 +1,6 @@ // Type resolution: the phase that finds all the types in the AST with // unresolved type variables and replaces "ty_var" types with their -// substitutions. +// generic parameters. use crate::FnCtxt; use rustc_data_structures::unord::ExtendUnord; @@ -616,7 +616,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { self.write_ty_to_typeck_results(hir_id, n_ty); debug!(?n_ty); - // Resolve any substitutions + // Resolve any generic parameters if let Some(args) = self.fcx.typeck_results.borrow().node_args_opt(hir_id) { let args = self.resolve(args, &span); debug!("write_args_to_tcx({:?}, {:?})", hir_id, args); diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs similarity index 80% rename from compiler/rustc_infer/src/infer/canonical/substitute.rs rename to compiler/rustc_infer/src/infer/canonical/instantiate.rs index e0b97bb160cab..f6b583151fdf3 100644 --- a/compiler/rustc_infer/src/infer/canonical/substitute.rs +++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs @@ -1,4 +1,4 @@ -//! This module contains code to substitute new values into a +//! This module contains code to instantiate new values into a //! `Canonical<'tcx, T>`. //! //! For an overview of what canonicalization is and how it fits into @@ -16,17 +16,17 @@ use rustc_middle::ty::{self, TyCtxt}; pub trait CanonicalExt<'tcx, V> { /// Instantiate the wrapped value, replacing each canonical value /// with the value given in `var_values`. - fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V + fn instantiate(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V where V: TypeFoldable>; - /// Allows one to apply a substitute to some subset of + /// Allows one to apply a instantiation to some subset of /// `self.value`. Invoke `projection_fn` with `self.value` to get /// a value V that is expressed in terms of the same canonical /// variables bound in `self` (usually this extracts from subset - /// of `self`). Apply the substitution `var_values` to this value + /// of `self`). Apply the instantiation `var_values` to this value /// V, replacing each of the canonical variables. - fn substitute_projected( + fn instantiate_projected( &self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>, @@ -37,14 +37,14 @@ pub trait CanonicalExt<'tcx, V> { } impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> { - fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V + fn instantiate(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V where V: TypeFoldable>, { - self.substitute_projected(tcx, var_values, |value| value.clone()) + self.instantiate_projected(tcx, var_values, |value| value.clone()) } - fn substitute_projected( + fn instantiate_projected( &self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>, @@ -55,14 +55,14 @@ impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> { { assert_eq!(self.variables.len(), var_values.len()); let value = projection_fn(&self.value); - substitute_value(tcx, var_values, value) + instantiate_value(tcx, var_values, value) } } -/// Substitute the values from `var_values` into `value`. `var_values` +/// Instantiate the values from `var_values` into `value`. `var_values` /// must be values for the set of canonical variables that appear in /// `value`. -pub(super) fn substitute_value<'tcx, T>( +pub(super) fn instantiate_value<'tcx, T>( tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>, value: T, diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 1f68a5a9c6179..1d203a29b1492 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -30,24 +30,24 @@ use rustc_middle::ty::GenericArg; use rustc_middle::ty::{self, List, Ty, TyCtxt}; use rustc_span::Span; +pub use instantiate::CanonicalExt; pub use rustc_middle::infer::canonical::*; -pub use substitute::CanonicalExt; mod canonicalizer; +mod instantiate; pub mod query_response; -mod substitute; impl<'tcx> InferCtxt<'tcx> { - /// Creates a substitution S for the canonical value with fresh + /// Creates an instantiation S for the canonical value with fresh /// inference variables and applies it to the canonical value. - /// Returns both the instantiated result *and* the substitution S. + /// Returns both the instantiated result *and* the instantiation S. /// /// This can be invoked as part of constructing an /// inference context at the start of a query (see /// `InferCtxtBuilder::build_with_canonical`). It basically /// brings the canonical value "into scope" within your new infcx. /// - /// At the end of processing, the substitution S (once + /// At the end of processing, the instantiation S (once /// canonicalized) then represents the values that you computed /// for each of the canonical inputs to your query. pub fn instantiate_canonical_with_fresh_inference_vars( @@ -73,14 +73,14 @@ impl<'tcx> InferCtxt<'tcx> { let canonical_inference_vars = self.instantiate_canonical_vars(span, canonical.variables, |ui| universes[ui]); - let result = canonical.substitute(self.tcx, &canonical_inference_vars); + let result = canonical.instantiate(self.tcx, &canonical_inference_vars); (result, canonical_inference_vars) } /// Given the "infos" about the canonical variables from some /// canonical, creates fresh variables with the same /// characteristics (see `instantiate_canonical_var` for - /// details). You can then use `substitute` to instantiate the + /// details). You can then use `instantiate` to instantiate the /// canonical variable with these inference variables. fn instantiate_canonical_vars( &self, diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 1f071a9ff0bc3..216b2e70abff6 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -7,7 +7,7 @@ //! //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html -use crate::infer::canonical::substitute::{substitute_value, CanonicalExt}; +use crate::infer::canonical::instantiate::{instantiate_value, CanonicalExt}; use crate::infer::canonical::{ Canonical, CanonicalQueryResponse, CanonicalVarValues, Certainty, OriginalQueryValues, QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse, @@ -189,18 +189,18 @@ impl<'tcx> InferCtxt<'tcx> { where R: Debug + TypeFoldable>, { - let InferOk { value: result_subst, mut obligations } = - self.query_response_substitution(cause, param_env, original_values, query_response)?; + let InferOk { value: result_args, mut obligations } = + self.query_response_instantiation(cause, param_env, original_values, query_response)?; obligations.extend(self.query_outlives_constraints_into_obligations( cause, param_env, &query_response.value.region_constraints.outlives, - &result_subst, + &result_args, )); let user_result: R = - query_response.substitute_projected(self.tcx, &result_subst, |q_r| q_r.value.clone()); + query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone()); Ok(InferOk { value: user_result, obligations }) } @@ -225,11 +225,11 @@ impl<'tcx> InferCtxt<'tcx> { /// basic operations as `instantiate_query_response_and_region_obligations` but /// it returns its result differently: /// - /// - It creates a substitution `S` that maps from the original + /// - It creates an instantiation `S` that maps from the original /// query variables to the values computed in the query /// result. If any errors arise, they are propagated back as an /// `Err` result. - /// - In the case of a successful substitution, we will append + /// - In the case of a successful instantiation, we will append /// `QueryOutlivesConstraint` values onto the /// `output_query_region_constraints` vector for the solver to /// use (if an error arises, some values may also be pushed, but @@ -239,7 +239,7 @@ impl<'tcx> InferCtxt<'tcx> { /// that must be processed. In this case, those subobligations /// are propagated back in the return value. /// - Finally, the query result (of type `R`) is propagated back, - /// after applying the substitution `S`. + /// after applying the instantiation `S`. pub fn instantiate_nll_query_response_and_region_obligations( &self, cause: &ObligationCause<'tcx>, @@ -251,8 +251,13 @@ impl<'tcx> InferCtxt<'tcx> { where R: Debug + TypeFoldable>, { - let InferOk { value: result_subst, mut obligations } = self - .query_response_substitution_guess(cause, param_env, original_values, query_response)?; + let InferOk { value: result_args, mut obligations } = self + .query_response_instantiation_guess( + cause, + param_env, + original_values, + query_response, + )?; // Compute `QueryOutlivesConstraint` values that unify each of // the original values `v_o` that was canonicalized into a @@ -262,7 +267,7 @@ impl<'tcx> InferCtxt<'tcx> { for (index, original_value) in original_values.var_values.iter().enumerate() { // ...with the value `v_r` of that variable from the query. - let result_value = query_response.substitute_projected(self.tcx, &result_subst, |v| { + let result_value = query_response.instantiate_projected(self.tcx, &result_args, |v| { v.var_values[BoundVar::new(index)] }); match (original_value.unpack(), result_value.unpack()) { @@ -321,7 +326,7 @@ impl<'tcx> InferCtxt<'tcx> { // ...also include the other query region constraints from the query. output_query_region_constraints.outlives.extend( query_response.value.region_constraints.outlives.iter().filter_map(|&r_c| { - let r_c = substitute_value(self.tcx, &result_subst, r_c); + let r_c = instantiate_value(self.tcx, &result_args, r_c); // Screen out `'a: 'a` cases. let ty::OutlivesPredicate(k1, r2) = r_c.0; @@ -336,26 +341,26 @@ impl<'tcx> InferCtxt<'tcx> { .region_constraints .member_constraints .iter() - .map(|p_c| substitute_value(self.tcx, &result_subst, p_c.clone())), + .map(|p_c| instantiate_value(self.tcx, &result_args, p_c.clone())), ); let user_result: R = - query_response.substitute_projected(self.tcx, &result_subst, |q_r| q_r.value.clone()); + query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone()); Ok(InferOk { value: user_result, obligations }) } /// Given the original values and the (canonicalized) result from - /// computing a query, returns a substitution that can be applied + /// computing a query, returns an instantiation that can be applied /// to the query result to convert the result back into the /// original namespace. /// - /// The substitution also comes accompanied with subobligations + /// The instantiation also comes accompanied with subobligations /// that arose from unification; these might occur if (for /// example) we are doing lazy normalization and the value /// assigned to a type variable is unified with an unnormalized /// projection. - fn query_response_substitution( + fn query_response_instantiation( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -366,11 +371,11 @@ impl<'tcx> InferCtxt<'tcx> { R: Debug + TypeFoldable>, { debug!( - "query_response_substitution(original_values={:#?}, query_response={:#?})", + "query_response_instantiation(original_values={:#?}, query_response={:#?})", original_values, query_response, ); - let mut value = self.query_response_substitution_guess( + let mut value = self.query_response_instantiation_guess( cause, param_env, original_values, @@ -378,7 +383,7 @@ impl<'tcx> InferCtxt<'tcx> { )?; value.obligations.extend( - self.unify_query_response_substitution_guess( + self.unify_query_response_instantiation_guess( cause, param_env, original_values, @@ -392,7 +397,7 @@ impl<'tcx> InferCtxt<'tcx> { } /// Given the original values and the (canonicalized) result from - /// computing a query, returns a **guess** at a substitution that + /// computing a query, returns a **guess** at an instantiation that /// can be applied to the query result to convert the result back /// into the original namespace. This is called a **guess** /// because it uses a quick heuristic to find the values for each @@ -401,7 +406,7 @@ impl<'tcx> InferCtxt<'tcx> { /// variable instead. Therefore, the result of this method must be /// properly unified #[instrument(level = "debug", skip(self, cause, param_env))] - fn query_response_substitution_guess( + fn query_response_instantiation_guess( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -450,7 +455,7 @@ impl<'tcx> InferCtxt<'tcx> { if let ty::Bound(debruijn, b) = *result_value.kind() { // ...in which case we would set `canonical_vars[0]` to `Some(?U)`. - // We only allow a `ty::INNERMOST` index in substitutions. + // We only allow a `ty::INNERMOST` index in generic parameters. assert_eq!(debruijn, ty::INNERMOST); opt_values[b.var] = Some(*original_value); } @@ -460,7 +465,7 @@ impl<'tcx> InferCtxt<'tcx> { if let ty::ReBound(debruijn, br) = *result_value { // ... in which case we would set `canonical_vars[0]` to `Some('static)`. - // We only allow a `ty::INNERMOST` index in substitutions. + // We only allow a `ty::INNERMOST` index in generic parameters. assert_eq!(debruijn, ty::INNERMOST); opt_values[br.var] = Some(*original_value); } @@ -469,7 +474,7 @@ impl<'tcx> InferCtxt<'tcx> { if let ty::ConstKind::Bound(debruijn, b) = result_value.kind() { // ...in which case we would set `canonical_vars[0]` to `Some(const X)`. - // We only allow a `ty::INNERMOST` index in substitutions. + // We only allow a `ty::INNERMOST` index in generic parameters. assert_eq!(debruijn, ty::INNERMOST); opt_values[b] = Some(*original_value); } @@ -477,10 +482,10 @@ impl<'tcx> InferCtxt<'tcx> { } } - // Create a result substitution: if we found a value for a + // Create result arguments: if we found a value for a // given variable in the loop above, use that. Otherwise, use // a fresh inference variable. - let result_subst = CanonicalVarValues { + let result_args = CanonicalVarValues { var_values: self.tcx.mk_args_from_iter( query_response.variables.iter().enumerate().map(|(index, info)| { if info.universe() != ty::UniverseIndex::ROOT { @@ -511,8 +516,8 @@ impl<'tcx> InferCtxt<'tcx> { // Carry all newly resolved opaque types to the caller's scope for &(a, b) in &query_response.value.opaque_types { - let a = substitute_value(self.tcx, &result_subst, a); - let b = substitute_value(self.tcx, &result_subst, b); + let a = instantiate_value(self.tcx, &result_args, a); + let b = instantiate_value(self.tcx, &result_args, b); debug!(?a, ?b, "constrain opaque type"); // We use equate here instead of, for example, just registering the // opaque type's hidden value directly, because we may be instantiating @@ -532,7 +537,7 @@ impl<'tcx> InferCtxt<'tcx> { ); } - Ok(InferOk { value: result_subst, obligations }) + Ok(InferOk { value: result_args, obligations }) } /// Given a "guess" at the values for the canonical variables in @@ -540,13 +545,13 @@ impl<'tcx> InferCtxt<'tcx> { /// query result. Often, but not always, this is a no-op, because /// we already found the mapping in the "guessing" step. /// - /// See also: `query_response_substitution_guess` - fn unify_query_response_substitution_guess( + /// See also: [`Self::query_response_instantiation_guess`] + fn unify_query_response_instantiation_guess( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, - result_subst: &CanonicalVarValues<'tcx>, + result_args: &CanonicalVarValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, ()> where @@ -554,15 +559,15 @@ impl<'tcx> InferCtxt<'tcx> { { // A closure that yields the result value for the given // canonical variable; this is taken from - // `query_response.var_values` after applying the substitution - // `result_subst`. - let substituted_query_response = |index: BoundVar| -> GenericArg<'tcx> { - query_response.substitute_projected(self.tcx, result_subst, |v| v.var_values[index]) + // `query_response.var_values` after applying the instantiation + // by `result_args`. + let instantiated_query_response = |index: BoundVar| -> GenericArg<'tcx> { + query_response.instantiate_projected(self.tcx, result_args, |v| v.var_values[index]) }; // Unify the original value for each variable with the value - // taken from `query_response` (after applying `result_subst`). - self.unify_canonical_vars(cause, param_env, original_values, substituted_query_response) + // taken from `query_response` (after applying `result_args`). + self.unify_canonical_vars(cause, param_env, original_values, instantiated_query_response) } /// Converts the region constraints resulting from a query into an @@ -571,11 +576,11 @@ impl<'tcx> InferCtxt<'tcx> { &'a self, cause: &'a ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - unsubstituted_region_constraints: &'a [QueryOutlivesConstraint<'tcx>], - result_subst: &'a CanonicalVarValues<'tcx>, + uninstantiated_region_constraints: &'a [QueryOutlivesConstraint<'tcx>], + result_args: &'a CanonicalVarValues<'tcx>, ) -> impl Iterator> + 'a + Captures<'tcx> { - unsubstituted_region_constraints.iter().map(move |&constraint| { - let predicate = substitute_value(self.tcx, result_subst, constraint); + uninstantiated_region_constraints.iter().map(move |&constraint| { + let predicate = instantiate_value(self.tcx, result_args, constraint); self.query_outlives_constraint_to_obligation(predicate, cause.clone(), param_env) }) } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 78ef70398e5ed..0bf4598608f2a 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -679,7 +679,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { /// inference context that contains each of the bound values /// within instantiated as a fresh variable. The `f` closure is /// invoked with the new infcx, along with the instantiated value - /// `V` and a substitution `S`. This substitution `S` maps from + /// `V` and a instantiation `S`. This instantiation `S` maps from /// the bound values in `C` to their instantiated values in `V` /// (in other words, `S(C) = V`). pub fn build_with_canonical( @@ -691,8 +691,8 @@ impl<'tcx> InferCtxtBuilder<'tcx> { T: TypeFoldable>, { let infcx = self.build(); - let (value, subst) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); - (infcx, value, subst) + let (value, args) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); + (infcx, value, args) } pub fn build(&mut self) -> InferCtxt<'tcx> { @@ -1194,13 +1194,13 @@ impl<'tcx> InferCtxt<'tcx> { } GenericParamDefKind::Type { .. } => { // Create a type inference variable for the given - // type parameter definition. The substitutions are + // type parameter definition. The generic parameters are // for actual parameters that may be referred to by // the default of this type parameter, if it exists. // e.g., `struct Foo(...);` when // used in a path such as `Foo::::new()` will // use an inference variable for `C` with `[T, U]` - // as the substitutions for the default, `(T, U)`. + // as the generic parameters for the default, `(T, U)`. let ty_var_id = self.inner.borrow_mut().type_variables().new_var( self.universe(), TypeVariableOrigin { @@ -1256,7 +1256,7 @@ impl<'tcx> InferCtxt<'tcx> { ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid), ty).into() } - /// Given a set of generics defined on a type or impl, returns a substitution mapping each + /// Given a set of generics defined on a type or impl, returns the generic parameters mapping each /// type/region parameter to a fresh inference variable. pub fn fresh_args_for_item(&self, span: Span, def_id: DefId) -> GenericArgsRef<'tcx> { GenericArgs::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param)) @@ -1411,7 +1411,7 @@ impl<'tcx> InferCtxt<'tcx> { T: TypeFoldable>, { if !value.has_infer() { - return value; // Avoid duplicated subst-folding. + return value; // Avoid duplicated type-folding. } let mut r = InferenceLiteralEraser { tcx: self.tcx }; value.fold_with(&mut r) @@ -1458,7 +1458,7 @@ impl<'tcx> InferCtxt<'tcx> { // Instantiates the bound variables in a given binder with fresh inference // variables in the current universe. // - // Use this method if you'd like to find some substitution of the binder's + // Use this method if you'd like to find some generic parameters of the binder's // variables (e.g. during a method call). If there isn't a [`BoundRegionConversionTime`] // that corresponds to your use case, consider whether or not you should // use [`InferCtxt::enter_forall`] instead. @@ -1603,10 +1603,10 @@ impl<'tcx> InferCtxt<'tcx> { /// Resolves and evaluates a constant. /// /// The constant can be located on a trait like `::C`, in which case the given - /// substitutions and environment are used to resolve the constant. Alternatively if the - /// constant has generic parameters in scope the substitutions are used to evaluate the value of + /// generic parameters and environment are used to resolve the constant. Alternatively if the + /// constant has generic parameters in scope the instantiations are used to evaluate the value of /// the constant. For example in `fn foo() { let _ = [0; bar::()]; }` the repeat count - /// constant `bar::()` requires a substitution for `T`, if the substitution for `T` is still + /// constant `bar::()` requires a instantiation for `T`, if the instantiation for `T` is still /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is /// returned. /// @@ -1652,7 +1652,7 @@ impl<'tcx> InferCtxt<'tcx> { let unevaluated = ty::UnevaluatedConst { def: unevaluated.def, args: args_erased }; // The return value is the evaluated value which doesn't contain any reference to inference - // variables, thus we don't need to substitute back the original values. + // variables, thus we don't need to instantiate back the original values. tcx.const_eval_resolve_for_typeck(param_env_erased, unevaluated, span) } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 46c4f80cb0cb7..ec674407e523d 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -219,7 +219,7 @@ impl<'tcx> InferCtxt<'tcx> { /// ``` /// /// As indicating in the comments above, each of those references - /// is (in the compiler) basically a substitution (`args`) + /// is (in the compiler) basically generic paramters (`args`) /// applied to the type of a suitable `def_id` (which identifies /// `Foo1` or `Foo2`). /// 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 236dc4ec38484..d547f51f38199 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -25,7 +25,7 @@ use crate::infer::region_constraints::VerifyIfEq; /// * `None` if `some_type` cannot be made equal to `test_ty`, /// no matter the values of the variables in `exists`. /// * `Some(r)` with a suitable bound (typically the value of `bound_region`, modulo -/// any bound existential variables, which will be substituted) for the +/// any bound existential variables, which will be instantiated) for the /// type under test. /// /// NB: This function uses a simplistic, syntactic version of type equality. @@ -59,7 +59,7 @@ pub fn extract_verify_if_eq<'tcx>( } } else { // The region does not contain any bound variables, so we don't need - // to do any substitution. + // to do any instantiation. // // Example: // diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 5d2f51c689b95..24b351988bf69 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -277,7 +277,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { /// ``` /// /// If we were given the `DefId` of `Foo::Bar`, we would return - /// `'a`. You could then apply the substitutions from the + /// `'a`. You could then apply the instantiations from the /// projection to convert this into your namespace. This also /// works if the user writes `where >::Bar: 'a` on /// the trait. In fact, it works by searching for just such a diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 417c8695e248b..bc16d613ccbcd 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -183,14 +183,14 @@ where fn relate_item_args( &mut self, item_def_id: DefId, - a_subst: ty::GenericArgsRef<'tcx>, - b_subst: ty::GenericArgsRef<'tcx>, + a_arg: ty::GenericArgsRef<'tcx>, + b_arg: ty::GenericArgsRef<'tcx>, ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> { if self.ambient_variance == ty::Variance::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). - relate::relate_args_invariantly(self, a_subst, b_subst) + relate::relate_args_invariantly(self, a_arg, b_arg) } else { let tcx = self.tcx(); let opt_variances = tcx.variances_of(item_def_id); @@ -198,8 +198,8 @@ where self, item_def_id, opt_variances, - a_subst, - b_subst, + a_arg, + b_arg, false, ) } diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 58b8110157bfb..8b81eac873909 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -118,7 +118,7 @@ pub enum TypeVariableOriginKind { AdjustmentType, /// In type check, when we are type checking a function that - /// returns `-> dyn Foo`, we substitute a type variable for the + /// returns `-> dyn Foo`, we instantiate a type variable with the /// return type for diagnostic purposes. DynReturnFn, LatticeVariable, diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 50190058a7688..e9df0505cbbdc 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -285,7 +285,8 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { let obligations = predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| { elaboratable.child_with_derived_cause( - clause.subst_supertrait(tcx, &bound_clause.rebind(data.trait_ref)), + clause + .instantiate_supertrait(tcx, &bound_clause.rebind(data.trait_ref)), span, bound_clause.rebind(data), index, diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index e544c2a26e82d..7b65c11bc3c82 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -53,7 +53,7 @@ impl<'tcx> ty::TypeFoldable> for CanonicalVarInfos<'tcx> { /// A set of values corresponding to the canonical variables from some /// `Canonical`. You can give these values to -/// `canonical_value.substitute` to substitute them into the canonical +/// `canonical_value.instantiate` to instantiate them into the canonical /// value at the right places. /// /// When you canonicalize a value `V`, you get back one of these diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 5f9e7f6e36854..e8aca5f2e7d85 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -11,13 +11,13 @@ use rustc_session::lint; use rustc_span::{Span, DUMMY_SP}; impl<'tcx> TyCtxt<'tcx> { - /// Evaluates a constant without providing any substitutions. This is useful to evaluate consts + /// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts /// that can't take any generic arguments like statics, const items or enum discriminants. If a /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned. #[instrument(skip(self), level = "debug")] pub fn const_eval_poly(self, def_id: DefId) -> EvalToConstValueResult<'tcx> { - // In some situations def_id will have substitutions within scope, but they aren't allowed - // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions + // In some situations def_id will have generic parameters within scope, but they aren't allowed + // to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self, def_id); @@ -29,10 +29,10 @@ impl<'tcx> TyCtxt<'tcx> { /// Resolves and evaluates a constant. /// /// The constant can be located on a trait like `::C`, in which case the given - /// substitutions and environment are used to resolve the constant. Alternatively if the - /// constant has generic parameters in scope the substitutions are used to evaluate the value of + /// generic parameters and environment are used to resolve the constant. Alternatively if the + /// constant has generic parameters in scope the generic parameters are used to evaluate the value of /// the constant. For example in `fn foo() { let _ = [0; bar::()]; }` the repeat count - /// constant `bar::()` requires a substitution for `T`, if the substitution for `T` is still + /// constant `bar::()` requires a instantiation for `T`, if the instantiation for `T` is still /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is /// returned. #[instrument(level = "debug", skip(self))] @@ -214,13 +214,13 @@ impl<'tcx> TyCtxtAt<'tcx> { } impl<'tcx> TyCtxtEnsure<'tcx> { - /// Evaluates a constant without providing any substitutions. This is useful to evaluate consts + /// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts /// that can't take any generic arguments like statics, const items or enum discriminants. If a /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned. #[instrument(skip(self), level = "debug")] pub fn const_eval_poly(self, def_id: DefId) { - // In some situations def_id will have substitutions within scope, but they aren't allowed - // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions + // In some situations def_id will have generic parameters within scope, but they aren't allowed + // to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self.tcx, def_id); diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 6937df7bb1897..3cd251caf5e3c 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -186,7 +186,7 @@ impl<'tcx> MonoItem<'tcx> { MonoItem::GlobalAsm(..) => return true, }; - !tcx.subst_and_check_impossible_predicates((def_id, &args)) + !tcx.instantiate_and_check_impossible_predicates((def_id, &args)) } pub fn local_span(&self, tcx: TyCtxt<'tcx>) -> Option { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 938fba0ed0981..50c0f53ae3a38 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2078,9 +2078,9 @@ rustc_queries! { desc { "normalizing `{:?}`", goal.value.value.value } } - query subst_and_check_impossible_predicates(key: (DefId, GenericArgsRef<'tcx>)) -> bool { + query instantiate_and_check_impossible_predicates(key: (DefId, GenericArgsRef<'tcx>)) -> bool { desc { |tcx| - "checking impossible substituted predicates: `{}`", + "checking impossible instantiated predicates: `{}`", tcx.def_path_str(key.0) } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 894acf3c2aa5f..8e5f026b4c27c 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -721,7 +721,7 @@ impl<'tcx, N> ImplSource<'tcx, N> { } /// Identifies a particular impl in the source, along with a set of -/// substitutions from the impl's type/lifetime parameters. The +/// generic parameters from the impl's type/lifetime parameters. The /// `nested` vector corresponds to the nested obligations attached to /// the impl's type parameters. /// diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 28eba133c76df..e3050007c7b3c 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -49,7 +49,8 @@ pub type EvaluationCache<'tcx> = Cache< /// parameters don't unify with regular types, but they *can* unify /// with variables from blanket impls, and (unless we know its bounds /// will always be satisfied) picking the blanket impl will be wrong -/// for at least *some* substitutions. To make this concrete, if we have +/// for at least *some* generic parameters. To make this concrete, if +/// we have /// /// ```rust, ignore /// trait AsDebug { type Out: fmt::Debug; fn debug(self) -> Self::Out; } diff --git a/compiler/rustc_middle/src/traits/util.rs b/compiler/rustc_middle/src/traits/util.rs index fd5302dc75b13..3419827a74275 100644 --- a/compiler/rustc_middle/src/traits/util.rs +++ b/compiler/rustc_middle/src/traits/util.rs @@ -37,7 +37,7 @@ impl<'tcx> Elaborator<'tcx> { let super_predicates = self.tcx.super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map( |&(pred, _)| { - let clause = pred.subst_supertrait(self.tcx, &trait_ref); + let clause = pred.instantiate_supertrait(self.tcx, &trait_ref); self.visited.insert(clause).then_some(clause) }, ); diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index 417f1932c6f90..425a2dbd89071 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -3,7 +3,7 @@ use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; use crate::ty::{self, InferConst, Ty, TyCtxt}; /// A type "A" *matches* "B" if the fresh types in B could be -/// substituted with values so as to make it equal to A. Matching is +/// instantiated with values so as to make it equal to A. Matching is /// intended to be used only on freshened types, and it basically /// indicates if the non-freshened versions of A and B could have been /// unified. diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index a930c7e8ebf80..23771073745ff 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -235,7 +235,7 @@ impl<'tcx> Const<'tcx> { // FIXME(const_generics): We currently have to special case parameters because `min_const_generics` // does not provide the parents generics to anonymous constants. We still allow generic const // parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to - // ever try to substitute the generic parameters in their bodies. + // ever try to instantiate the generic parameters in their bodies. match expr.kind { hir::ExprKind::Path(hir::QPath::Resolved( _, diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 3e64f9a2a9095..b57d4f372a7f9 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -418,10 +418,10 @@ impl<'tcx> TyCtxt<'tcx> { // Shifter // // Shifts the De Bruijn indices on all escaping bound vars by a -// fixed amount. Useful in substitution or when otherwise introducing +// fixed amount. Useful in instantiation or when otherwise introducing // a binding level that is not intended to capture the existing bound // vars. See comment on `shift_vars_through_binders` method in -// `subst.rs` for more details. +// `rustc_middle/src/ty/generic_args.rs` for more details. struct Shifter<'tcx> { tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index b9fff660a03b9..84de12b23a06e 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -803,13 +803,13 @@ impl<'tcx, T: TypeFoldable>> ty::EarlyBinder { } /////////////////////////////////////////////////////////////////////////// -// The actual substitution engine itself is a type folder. +// The actual instantiation engine itself is a type folder. struct ArgFolder<'a, 'tcx> { tcx: TyCtxt<'tcx>, args: &'a [GenericArg<'tcx>], - /// Number of region binders we have passed through while doing the substitution + /// Number of region binders we have passed through while doing the instantiation binders_passed: u32, } @@ -834,7 +834,7 @@ impl<'a, 'tcx> TypeFolder> for ArgFolder<'a, 'tcx> { #[inline(never)] fn region_param_out_of_range(data: ty::EarlyParamRegion, args: &[GenericArg<'_>]) -> ! { bug!( - "Region parameter out of range when substituting in region {} (index={}, args = {:?})", + "Region parameter out of range when instantiating in region {} (index={}, args = {:?})", data.name, data.index, args, @@ -845,7 +845,7 @@ impl<'a, 'tcx> TypeFolder> for ArgFolder<'a, 'tcx> { #[inline(never)] fn region_param_invalid(data: ty::EarlyParamRegion, other: GenericArgKind<'_>) -> ! { bug!( - "Unexpected parameter {:?} when substituting in region {} (index={})", + "Unexpected parameter {:?} when instantiating in region {} (index={})", other, data.name, data.index @@ -854,7 +854,7 @@ impl<'a, 'tcx> TypeFolder> for ArgFolder<'a, 'tcx> { // Note: This routine only handles regions that are bound on // type declarations and other outer declarations, not those - // bound in *fn types*. Region substitution of the bound + // bound in *fn types*. Region instantiation of the bound // regions that appear in a function signature is done using // the specialized routine `ty::replace_late_regions()`. match *r { @@ -913,7 +913,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> { #[inline(never)] fn type_param_expected(&self, p: ty::ParamTy, ty: Ty<'tcx>, kind: GenericArgKind<'tcx>) -> ! { bug!( - "expected type for `{:?}` ({:?}/{}) but found {:?} when substituting, args={:?}", + "expected type for `{:?}` ({:?}/{}) but found {:?} when instantiating, args={:?}", p, ty, p.index, @@ -926,7 +926,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> { #[inline(never)] fn type_param_out_of_range(&self, p: ty::ParamTy, ty: Ty<'tcx>) -> ! { bug!( - "type parameter `{:?}` ({:?}/{}) out of range when substituting, args={:?}", + "type parameter `{:?}` ({:?}/{}) out of range when instantiating, args={:?}", p, ty, p.index, @@ -955,7 +955,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> { kind: GenericArgKind<'tcx>, ) -> ! { bug!( - "expected const for `{:?}` ({:?}/{}) but found {:?} when substituting args={:?}", + "expected const for `{:?}` ({:?}/{}) but found {:?} when instantiating args={:?}", p, ct, p.index, @@ -968,7 +968,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> { #[inline(never)] fn const_param_out_of_range(&self, p: ty::ParamConst, ct: ty::Const<'tcx>) -> ! { bug!( - "const parameter `{:?}` ({:?}/{}) out of range when substituting args={:?}", + "const parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}", p, ct, p.index, @@ -976,8 +976,8 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> { ) } - /// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs - /// when we are substituting a type with escaping bound vars into a context where we have + /// It is sometimes necessary to adjust the De Bruijn indices during instantiation. This occurs + /// when we are instantating a type with escaping bound vars into a context where we have /// passed through binders. That's quite a mouthful. Let's see an example: /// /// ``` @@ -997,7 +997,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> { /// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip /// over the inner binder (remember that we count De Bruijn indices from 1). However, in the /// definition of `MetaFunc`, the binder is not visible, so the type `&'a i32` will have a - /// De Bruijn index of 1. It's only during the substitution that we can see we must increase the + /// De Bruijn index of 1. It's only during the instantiation that we can see we must increase the /// depth by 1 to account for the binder that we passed through. /// /// As a second example, consider this twist: @@ -1015,7 +1015,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> { /// // DebruijnIndex of 1 | /// // DebruijnIndex of 2 /// ``` - /// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the + /// As indicated in the diagram, here the same type `&'a i32` is instantiated once, but in the /// first case we do not increase the De Bruijn index and in the second case we do. The reason /// is that only in the second case have we passed through a fn binder. fn shift_vars_through_binders>>(&self, val: T) -> T { diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 4821ae3f08735..c81d9dfbc7d60 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -125,7 +125,7 @@ pub struct GenericParamCount { /// Information about the formal type/lifetime parameters associated /// with an item or method. Analogous to `hir::Generics`. /// -/// The ordering of parameters is the same as in `Subst` (excluding child generics): +/// The ordering of parameters is the same as in [`ty::GenericArg`] (excluding child generics): /// `Self` (optionally), `Lifetime` params..., `Type` params... #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub struct Generics { @@ -140,7 +140,7 @@ pub struct Generics { pub has_self: bool, pub has_late_bound_regions: Option, - // The index of the host effect when substituted. (i.e. might be index to parent args) + // The index of the host effect when instantiated. (i.e. might be index to parent args) pub host_effect_index: Option, } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 8848d216f5b49..b49cc51e982ab 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -19,7 +19,7 @@ use std::fmt; /// /// Monomorphization happens on-the-fly and no monomorphized MIR is ever created. Instead, this type /// simply couples a potentially generic `InstanceDef` with some args, and codegen and const eval -/// will do all required substitution as they run. +/// will do all required instantiations as they run. /// /// Note: the `Lift` impl is currently not used by rustc, but is used by /// rustc_codegen_cranelift when the `jit` feature is enabled. @@ -138,7 +138,7 @@ pub enum InstanceDef<'tcx> { } impl<'tcx> Instance<'tcx> { - /// Returns the `Ty` corresponding to this `Instance`, with generic substitutions applied and + /// Returns the `Ty` corresponding to this `Instance`, with generic instantiations applied and /// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization. pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> { let ty = tcx.type_of(self.def.def_id()); @@ -298,11 +298,11 @@ impl<'tcx> InstanceDef<'tcx> { } /// Returns `true` when the MIR body associated with this instance should be monomorphized - /// by its users (e.g. codegen or miri) by substituting the `args` from `Instance` (see + /// by its users (e.g. codegen or miri) by instantiating the `args` from `Instance` (see /// `Instance::args_for_mir_body`). /// /// Otherwise, returns `false` only for some kinds of shims where the construction of the MIR - /// body should perform necessary substitutions. + /// body should perform necessary instantiations. pub fn has_polymorphic_mir_body(&self) -> bool { match *self { InstanceDef::CloneShim(..) @@ -672,13 +672,13 @@ impl<'tcx> Instance<'tcx> { /// Depending on the kind of `InstanceDef`, the MIR body associated with an /// instance is expressed in terms of the generic parameters of `self.def_id()`, and in other - /// cases the MIR body is expressed in terms of the types found in the substitution array. - /// In the former case, we want to substitute those generic types and replace them with the + /// cases the MIR body is expressed in terms of the types found in the generic parameter array. + /// In the former case, we want to instantiate those generic types and replace them with the /// values from the args when monomorphizing the function body. But in the latter case, we - /// don't want to do that substitution, since it has already been done effectively. + /// don't want to do that instantiation, since it has already been done effectively. /// /// This function returns `Some(args)` in the former case and `None` otherwise -- i.e., if - /// this function returns `None`, then the MIR body does not require substitution during + /// this function returns `None`, then the MIR body does not require instantiation during /// codegen. fn args_for_mir_body(&self) -> Option> { self.def.has_polymorphic_mir_body().then_some(self.args) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c9137f374a238..6370c8bd5bb50 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -728,7 +728,7 @@ impl From for TermVid { /// the `GenericPredicates` are expressed in terms of the bound type /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance /// represented a set of bounds for some particular instantiation, -/// meaning that the generic parameters have been substituted with +/// meaning that the generic parameters have been instantiated with /// their values. /// /// Example: @@ -1654,7 +1654,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair. + /// Returns the possibly-auto-generated MIR of a [`ty::InstanceDef`]. #[instrument(skip(self), level = "debug")] pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> { match instance { diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 27c436c82f53e..d4c8f5900f9ee 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -135,7 +135,7 @@ impl<'tcx> TyCtxt<'tcx> { } /// Monomorphizes a type from the AST by first applying the - /// in-scope substitutions and then normalizing any associated + /// in-scope instantiations and then normalizing any associated /// types. /// Panics if normalization fails. In case normalization might fail /// use `try_instantiate_and_normalize_erasing_regions` instead. @@ -149,12 +149,12 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable>, { - let substituted = value.instantiate(self, param_args); - self.normalize_erasing_regions(param_env, substituted) + let instantiated = value.instantiate(self, param_args); + self.normalize_erasing_regions(param_env, instantiated) } /// Monomorphizes a type from the AST by first applying the - /// in-scope substitutions and then trying to normalize any associated + /// in-scope instantiations and then trying to normalize any associated /// types. Contrary to `instantiate_and_normalize_erasing_regions` this does /// not assume that normalization succeeds. #[instrument(level = "debug", skip(self))] @@ -167,8 +167,8 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable>, { - let substituted = value.instantiate(self, param_args); - self.try_normalize_erasing_regions(param_env, substituted) + let instantiated = value.instantiate(self, param_args); + self.try_normalize_erasing_regions(param_env, instantiated) } } diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 5ca88ec31029c..fa5265c58e430 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -164,9 +164,9 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { } ty::Param(param) => { - // Look it up in the substitution list. + // Look it up in the generic parameters list. match self.map.get(&ty.into()).map(|k| k.unpack()) { - // Found it in the substitution list; replace with the parameter from the + // Found it in the generic parameters list; replace with the parameter from the // opaque type. Some(GenericArgKind::Type(t1)) => t1, Some(u) => panic!("type mapped to unexpected kind: {u:?}"), @@ -199,9 +199,9 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { // Find a const parameter match ct.kind() { ty::ConstKind::Param(..) => { - // Look it up in the substitution list. + // Look it up in the generic parameters list. match self.map.get(&ct.into()).map(|k| k.unpack()) { - // Found it in the substitution list, replace with the parameter from the + // Found it in the generic parameters list, replace with the parameter from the // opaque type. Some(GenericArgKind::Const(c1)) => c1, Some(u) => panic!("const mapped to unexpected kind: {u:?}"), diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 7c5b49512ae50..200811940ed76 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -323,7 +323,7 @@ impl<'tcx> ty::List> { /// and `U` as parameter 1. /// /// Trait references also appear in object types like `Foo`, but in -/// that case the `Self` parameter is absent from the substitutions. +/// that case the `Self` parameter is absent from the generic parameters. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct TraitRef<'tcx> { @@ -406,7 +406,7 @@ impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> { /// ```ignore (illustrative) /// exists T. T: Trait<'a, 'b, X, Y> /// ``` -/// The substitutions don't include the erased `Self`, only trait +/// The generic parameters don't include the erased `Self`, only trait /// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] @@ -481,8 +481,8 @@ impl<'tcx> ExistentialProjection<'tcx> { /// reference. pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> { let def_id = tcx.parent(self.def_id); - let subst_count = tcx.generics_of(def_id).count() - 1; - let args = tcx.mk_args(&self.args[..subst_count]); + let args_count = tcx.generics_of(def_id).count() - 1; + let args = tcx.mk_args(&self.args[..args_count]); ty::ExistentialTraitRef { def_id, args } } @@ -534,12 +534,12 @@ impl<'tcx> PolyExistentialProjection<'tcx> { } impl<'tcx> Clause<'tcx> { - /// Performs a substitution suitable for going from a + /// Performs a instantiation suitable for going from a /// poly-trait-ref to supertraits that must hold if that /// poly-trait-ref holds. This is slightly different from a normal - /// substitution in terms of what happens with bound regions. See + /// instantiation in terms of what happens with bound regions. See /// lengthy comment below for details. - pub fn subst_supertrait( + pub fn instantiate_supertrait( self, tcx: TyCtxt<'tcx>, trait_ref: &ty::PolyTraitRef<'tcx>, @@ -556,7 +556,7 @@ impl<'tcx> Clause<'tcx> { // we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we // knew that `Foo<'x>` (for any 'x) then we also know that // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from - // normal substitution. + // normal instantiation. // // In terms of why this is sound, the idea is that whenever there // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>` @@ -582,7 +582,7 @@ impl<'tcx> Clause<'tcx> { // - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x` // has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`, // where both `'x` and `'b` would have a DB index of 1. - // The substitution from the input trait-ref is therefore going to be + // The instantiation from the input trait-ref is therefore going to be // `'a => 'x` (where `'x` has a DB index of 1). // - The supertrait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an // early-bound parameter and `'b` is a late-bound parameter with a @@ -591,17 +591,17 @@ impl<'tcx> Clause<'tcx> { // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>` // just as we wanted. // - // There is only one catch. If we just apply the substitution `'a - // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will - // adjust the DB index because we substituting into a binder (it + // There is only one catch. If we just apply the instantiation `'a + // => 'x` to `for<'b> Bar1<'a,'b>`, the instantiation code will + // adjust the DB index because we instantiating into a binder (it // tries to be so smart...) resulting in `for<'x> for<'b> // Bar1<'x,'b>` (we have no syntax for this, so use your // imagination). Basically the 'x will have DB index of 2 and 'b // will have DB index of 1. Not quite what we want. So we apply - // the substitution to the *contents* of the trait reference, + // the instantiation to the *contents* of the trait reference, // rather than the trait reference itself (put another way, the - // substitution code expects equal binding levels in the values - // from the substitution and the value being substituted into, and + // instantiation code expects equal binding levels in the values + // from the instantiation and the value being instantiated into, and // this trick achieves that). // Working through the second example: diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f592acd4b6ff5..a3d5f1f195510 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -208,7 +208,7 @@ impl<'tcx> ClosureArgs<'tcx> { } } - /// Returns the substitutions of the closure's parent. + /// Returns the generic parameters of the closure's parent. pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] { self.split().parent_args } @@ -615,7 +615,7 @@ impl<'tcx> CoroutineArgs<'tcx> { } } - /// Returns the substitutions of the coroutine's parent. + /// Returns the generic parameters of the coroutine's parent. pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] { self.split().parent_args } @@ -819,7 +819,7 @@ impl<'tcx> UpvarArgs<'tcx> { /// inherited from the item that defined the inline const, /// - R represents the type of the constant. /// -/// When the inline const is instantiated, `R` is substituted as the actual inferred +/// When the inline const is instantiated, `R` is instantiated as the actual inferred /// type of the constant. The reason that `R` is represented as an extra type parameter /// is the same reason that [`ClosureArgs`] have `CS` and `U` as type parameters: /// inline const can reference lifetimes that are internal to the creating function. @@ -858,7 +858,7 @@ impl<'tcx> InlineConstArgs<'tcx> { } } - /// Returns the substitutions of the inline const's parent. + /// Returns the generic parameters of the inline const's parent. pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] { self.split().parent_args } @@ -1105,13 +1105,13 @@ where pub struct AliasTy<'tcx> { /// The parameters of the associated or opaque item. /// - /// For a projection, these are the substitutions for the trait and the - /// GAT substitutions, if there are any. + /// For a projection, these are the generic parameters for the trait and the + /// GAT parameters, if there are any. /// - /// For an inherent projection, they consist of the self type and the GAT substitutions, + /// For an inherent projection, they consist of the self type and the GAT parameters, /// if there are any. /// - /// For RPIT the substitutions are for the generics of the function, + /// For RPIT the generic parameters are for the generics of the function, /// while for TAIT it is used for the generic parameters of the alias. pub args: GenericArgsRef<'tcx>, @@ -1235,15 +1235,15 @@ impl<'tcx> AliasTy<'tcx> { /// The following methods work only with inherent associated type projections. impl<'tcx> AliasTy<'tcx> { - /// Transform the substitutions to have the given `impl` args as the base and the GAT args on top of that. + /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that. /// /// Does the following transformation: /// /// ```text /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m] /// - /// I_i impl subst - /// P_j GAT subst + /// I_i impl args + /// P_j GAT args /// ``` pub fn rebase_inherent_args_onto_impl( self, @@ -1690,7 +1690,7 @@ impl<'tcx> Ty<'tcx> { debug_assert_eq!( closure_args.len(), tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 3, - "closure constructed with incorrect substitutions" + "closure constructed with incorrect generic parameters" ); Ty::new(tcx, Closure(def_id, closure_args)) } @@ -1704,7 +1704,7 @@ impl<'tcx> Ty<'tcx> { debug_assert_eq!( closure_args.len(), tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 5, - "closure constructed with incorrect substitutions" + "closure constructed with incorrect generic parameters" ); Ty::new(tcx, CoroutineClosure(def_id, closure_args)) } @@ -1718,7 +1718,7 @@ impl<'tcx> Ty<'tcx> { debug_assert_eq!( coroutine_args.len(), tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 6, - "coroutine constructed with incorrect number of substitutions" + "coroutine constructed with incorrect number of generic parameters" ); Ty::new(tcx, Coroutine(def_id, coroutine_args)) } @@ -2530,7 +2530,7 @@ impl<'tcx> Ty<'tcx> { } /// Returns `true` when the outermost type cannot be further normalized, - /// resolved, or substituted. This includes all primitive types, but also + /// resolved, or instantiated. This includes all primitive types, but also /// things like ADTs and trait objects, sice even if their arguments or /// nested types may be further simplified, the outermost [`TyKind`] or /// type constructor remains the same. diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index ad41a674dd8cd..0fae0c55dcf20 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -49,19 +49,19 @@ pub struct TypeckResults<'tcx> { /// typeck::check::fn_ctxt for details. node_types: ItemLocalMap>, - /// Stores the type parameters which were substituted to obtain the type + /// Stores the type parameters which were instantiated to obtain the type /// of this node. This only applies to nodes that refer to entities /// parameterized by type parameters, such as generic fns, types, or /// other items. node_args: ItemLocalMap>, /// This will either store the canonicalized types provided by the user - /// or the substitutions that the user explicitly gave (if any) attached + /// or the generic parameters that the user explicitly gave (if any) attached /// to `id`. These will not include any inferred values. The canonical form /// is used to capture things like `_` or other unspecified values. /// /// For example, if the user wrote `foo.collect::>()`, then the - /// canonical substitutions would include only `for { Vec }`. + /// canonical generic parameters would include only `for { Vec }`. /// /// See also `AscribeUserType` statement in MIR. user_provided_types: ItemLocalMap>, @@ -329,7 +329,7 @@ impl<'tcx> TypeckResults<'tcx> { } /// Returns the type of a pattern as a monotype. Like [`expr_ty`], this function - /// doesn't provide type parameter substitutions. + /// doesn't provide type parameter args. /// /// [`expr_ty`]: TypeckResults::expr_ty pub fn pat_ty(&self, pat: &hir::Pat<'_>) -> Ty<'tcx> { @@ -341,9 +341,9 @@ impl<'tcx> TypeckResults<'tcx> { /// NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in /// some cases, we insert `Adjustment` annotations such as auto-deref or /// auto-ref. The type returned by this function does not consider such - /// adjustments. See `expr_ty_adjusted()` instead. + /// adjustments. See [`Self::expr_ty_adjusted`] instead. /// - /// NB (2): This type doesn't provide type parameter substitutions; e.g., if you + /// NB (2): This type doesn't provide type parameter args; e.g., if you /// ask for the type of `id` in `id(3)`, it will return `fn(&isize) -> isize` /// instead of `fn(ty) -> T with T = isize`. pub fn expr_ty(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> { @@ -608,7 +608,7 @@ pub enum UserType<'tcx> { Ty(Ty<'tcx>), /// The canonical type is the result of `type_of(def_id)` with the - /// given substitutions applied. + /// given generic parameters applied. TypeOf(DefId, UserArgs<'tcx>), } @@ -617,7 +617,7 @@ pub trait IsIdentity { } impl<'tcx> IsIdentity for CanonicalUserType<'tcx> { - /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`, + /// Returns `true` if this represents the generic parameters of the form `[?0, ?1, ?2]`, /// i.e., each thing is mapped to a canonical variable with the same index. fn is_identity(&self) -> bool { match self.value { @@ -631,7 +631,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> { match kind.unpack() { GenericArgKind::Type(ty) => match ty.kind() { ty::Bound(debruijn, b) => { - // We only allow a `ty::INNERMOST` index in substitutions. + // We only allow a `ty::INNERMOST` index in generic parameters. assert_eq!(*debruijn, ty::INNERMOST); cvar == b.var } @@ -640,7 +640,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> { GenericArgKind::Lifetime(r) => match *r { ty::ReBound(debruijn, br) => { - // We only allow a `ty::INNERMOST` index in substitutions. + // We only allow a `ty::INNERMOST` index in generic parameters. assert_eq!(debruijn, ty::INNERMOST); cvar == br.var } @@ -649,7 +649,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> { GenericArgKind::Const(ct) => match ct.kind() { ty::ConstKind::Bound(debruijn, b) => { - // We only allow a `ty::INNERMOST` index in substitutions. + // We only allow a `ty::INNERMOST` index in generic parameters. assert_eq!(debruijn, ty::INNERMOST); cvar == b } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 35adcc33480ca..61b2977a45f60 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -801,7 +801,7 @@ impl<'tcx> Cx<'tcx> { let user_provided_type = match res { // A reference to something callable -- e.g., a fn, method, or // a tuple-struct or tuple-variant. This has the type of a - // `Fn` but with the user-given substitutions. + // `Fn` but with the user-given generic parameters. Res::Def(DefKind::Fn, _) | Res::Def(DefKind::AssocFn, _) | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) @@ -812,7 +812,7 @@ impl<'tcx> Cx<'tcx> { // A unit struct/variant which is used as a value (e.g., // `None`). This has the type of the enum/struct that defines - // this variant -- but with the substitutions given by the + // this variant -- but with the generic parameters given by the // user. Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => { self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new) diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs index 9106b4d33fcd1..52c9cf14ac872 100644 --- a/compiler/rustc_mir_build/src/thir/util.rs +++ b/compiler/rustc_mir_build/src/thir/util.rs @@ -7,7 +7,7 @@ pub(crate) trait UserAnnotatedTyHelpers<'tcx> { fn typeck_results(&self) -> &ty::TypeckResults<'tcx>; /// Looks up the type associated with this hir-id and applies the - /// user-given substitutions; the hir-id must map to a suitable + /// user-given generic parameters; the hir-id must map to a suitable /// type. fn user_args_applied_to_ty_of_hir_id( &self, diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 94077c63057c8..430d9572e7594 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -36,10 +36,10 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b ty::Tuple(tys) => { depth == 0 || tys.iter().any(|ty| may_contain_reference(ty, depth - 1, tcx)) } - ty::Adt(adt, subst) => { + ty::Adt(adt, args) => { depth == 0 || adt.variants().iter().any(|v| { - v.fields.iter().any(|f| may_contain_reference(f.ty(tcx, subst), depth - 1, tcx)) + v.fields.iter().any(|f| may_contain_reference(f.ty(tcx, args), depth - 1, tcx)) }) } // Conservative fallback diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs index a6750911394b0..ca63f5550ae2e 100644 --- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs +++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs @@ -205,8 +205,8 @@ pub fn deduced_param_attrs<'tcx>( |(arg_index, local_decl)| DeducedParamAttrs { read_only: !deduce_read_only.mutable_args.contains(arg_index) // We must normalize here to reveal opaques and normalize - // their substs, otherwise we'll see exponential blow-up in - // compile times: #113372 + // their generic parameters, otherwise we'll see exponential + // blow-up in compile times: #113372 && tcx .normalize_erasing_regions(param_env, local_decl.ty) .is_freeze(tcx, param_env), diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index f413bd9b31168..e935dc7f5eb54 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -63,7 +63,7 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> { impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { /// Emits a lint for function reference arguments bound by `fmt::Pointer` in calls to the - /// function defined by `def_id` with the substitutions `args_ref`. + /// function defined by `def_id` with the generic parameters `args_ref`. fn check_bound_args( &self, def_id: DefId, @@ -83,11 +83,11 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { for inner_ty in arg_def.walk().filter_map(|arg| arg.as_type()) { // If the inner type matches the type bound by `Pointer` if inner_ty == bound_ty { - // Do a substitution using the parameters from the callsite - let subst_ty = + // Do an instantiation using the parameters from the callsite + let instantiated_ty = EarlyBinder::bind(inner_ty).instantiate(self.tcx, args_ref); if let Some((fn_id, fn_args)) = - FunctionItemRefChecker::is_fn_ref(subst_ty) + FunctionItemRefChecker::is_fn_ref(instantiated_ty) { let mut span = self.nth_arg_span(args, arg_num); if span.from_expansion() { diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 2c7ae53055f74..8d4afd5b5dce5 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -853,10 +853,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { fn simplify_discriminant(&mut self, place: VnIndex) -> Option { if let Value::Aggregate(enum_ty, variant, _) = *self.get(place) - && let AggregateTy::Def(enum_did, enum_substs) = enum_ty + && let AggregateTy::Def(enum_did, enum_args) = enum_ty && let DefKind::Enum = self.tcx.def_kind(enum_did) { - let enum_ty = self.tcx.type_of(enum_did).instantiate(self.tcx, enum_substs); + let enum_ty = self.tcx.type_of(enum_did).instantiate(self.tcx, enum_args); let discr = self.ecx.discriminant_for_variant(enum_ty, variant).ok()?; return Some(self.insert_scalar(discr.to_scalar(), discr.layout.ty)); } @@ -899,13 +899,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { assert!(!fields.is_empty()); (AggregateTy::Tuple, FIRST_VARIANT) } - AggregateKind::Closure(did, substs) - | AggregateKind::CoroutineClosure(did, substs) - | AggregateKind::Coroutine(did, substs) => { - (AggregateTy::Def(did, substs), FIRST_VARIANT) - } - AggregateKind::Adt(did, variant_index, substs, _, None) => { - (AggregateTy::Def(did, substs), variant_index) + AggregateKind::Closure(did, args) + | AggregateKind::CoroutineClosure(did, args) + | AggregateKind::Coroutine(did, args) => (AggregateTy::Def(did, args), FIRST_VARIANT), + AggregateKind::Adt(did, variant_index, args, _, None) => { + (AggregateTy::Def(did, args), variant_index) } // Do not track unions. AggregateKind::Adt(_, _, _, _, Some(_)) => return None, diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 5b03bc361dd3c..f2b6dcac58632 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -80,7 +80,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( } // These have no own callable MIR. InstanceDef::Intrinsic(_) | InstanceDef::Virtual(..) => continue, - // These have MIR and if that MIR is inlined, substituted and then inlining is run + // These have MIR and if that MIR is inlined, instantiated and then inlining is run // again, a function item can end up getting inlined. Thus we'll be able to cause // a cycle that way InstanceDef::VTableShim(_) @@ -95,7 +95,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( // This shim does not call any other functions, thus there can be no recursion. InstanceDef::FnPtrAddrShim(..) => continue, InstanceDef::DropGlue(..) => { - // FIXME: A not fully substituted drop shim can cause ICEs if one attempts to + // FIXME: A not fully instantiated drop shim can cause ICEs if one attempts to // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this // needs some more analysis. if callee.has_param() { diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index f65eb5cbea938..75073537f5f82 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -211,7 +211,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { // Only bother looking more if it's easy to know what we're calling let Some((fn_def_id, fn_args)) = func.const_fn_def() else { return }; - // Clone needs one subst, so we can cheaply rule out other stuff + // Clone needs one arg, so we can cheaply rule out other stuff if fn_args.len() != 1 { return; } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 72d9ffe8ca573..9f30f2836f195 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -436,7 +436,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & // // We manually filter the predicates, skipping anything that's not // "global". We are in a potentially generic context - // (e.g. we are evaluating a function without substituting generic + // (e.g. we are evaluating a function without instantiating generic // parameters, so this filtering serves two purposes: // // 1. We skip evaluating any predicates that we would @@ -576,10 +576,10 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &inline::Inline, // Code from other crates may have storage markers, so this needs to happen after inlining. &remove_storage_markers::RemoveStorageMarkers, - // Inlining and substitution may introduce ZST and useless drops. + // Inlining and instantiation may introduce ZST and useless drops. &remove_zsts::RemoveZsts, &remove_unneeded_drops::RemoveUnneededDrops, - // Type substitution may create uninhabited enums. + // Type instantiation may create uninhabited enums. &uninhabited_enum_branching::UninhabitedEnumBranching, &unreachable_prop::UnreachablePropagation, &o1(simplify::SimplifyCfg::AfterUninhabitedEnumBranching), @@ -673,7 +673,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { } /// Fetch all the promoteds of an item and prepare their MIR bodies to be ready for -/// constant evaluation once all substitutions become known. +/// constant evaluation once all generic parameters become known. fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec> { if tcx.is_constructor(def.to_def_id()) { return tcx.arena.alloc(IndexVec::new()); diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index 05a3ac3cc7558..d5642be551375 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -44,7 +44,7 @@ use crate::ssa::{SsaLocals, StorageLiveLocals}; /// /// # Liveness /// -/// When performing a substitution, we must take care not to introduce uses of dangling locals. +/// When performing an instantiation, we must take care not to introduce uses of dangling locals. /// To ensure this, we walk the body with the `MaybeStorageDead` dataflow analysis: /// - if we want to replace `*x` by reborrow `*y` and `y` may be dead, we allow replacement and /// mark storage statements on `y` for removal; @@ -55,7 +55,7 @@ use crate::ssa::{SsaLocals, StorageLiveLocals}; /// /// For `&mut` borrows, we also need to preserve the uniqueness property: /// we must avoid creating a state where we interleave uses of `*_1` and `_2`. -/// To do it, we only perform full substitution of mutable borrows: +/// To do it, we only perform full instantiation of mutable borrows: /// we replace either all or none of the occurrences of `*_1`. /// /// Some care has to be taken when `_1` is copied in other locals. @@ -63,10 +63,10 @@ use crate::ssa::{SsaLocals, StorageLiveLocals}; /// _3 = *_1; /// _4 = _1 /// _5 = *_4 -/// In such cases, fully substituting `_1` means fully substituting all of the copies. +/// In such cases, fully instantiating `_1` means fully instantiating all of the copies. /// /// For immutable borrows, we do not need to preserve such uniqueness property, -/// so we perform all the possible substitutions without removing the `_1 = &_2` statement. +/// so we perform all the possible instantiations without removing the `_1 = &_2` statement. pub struct ReferencePropagation; impl<'tcx> MirPass<'tcx> for ReferencePropagation { diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 860d280be2950..75613a2c55555 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -477,7 +477,7 @@ struct CloneShimBuilder<'tcx> { impl<'tcx> CloneShimBuilder<'tcx> { fn new(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Self { - // we must subst the self_ty because it's + // we must instantiate the self_ty because it's // otherwise going to be TySelf and we can't index // or access fields of a Place of type TySelf. let sig = tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]); @@ -716,8 +716,8 @@ fn build_call_shim<'tcx>( call_kind: CallKind<'tcx>, ) -> Body<'tcx> { // `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used - // to substitute into the signature of the shim. It is not necessary for users of this - // MIR body to perform further substitutions (see `InstanceDef::has_polymorphic_mir_body`). + // to instantiate into the signature of the shim. It is not necessary for users of this + // MIR body to perform further instantiations (see `InstanceDef::has_polymorphic_mir_body`). let (sig_args, untuple_args) = if let ty::InstanceDef::FnPtrShim(_, ty) = instance { let sig = tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx)); diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index 1ed3b14e75504..e4fdbd6ae697d 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -170,7 +170,7 @@ impl SsaLocals { /// _c => _a /// _d => _a // transitively through _c /// - /// Exception: we do not see through the return place, as it cannot be substituted. + /// Exception: we do not see through the return place, as it cannot be instantiated. pub fn copy_classes(&self) -> &IndexSlice { &self.copy_classes } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 149e4c2cb08ef..6dde7872f560a 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -62,7 +62,7 @@ //! syntactic items in the source code. We find them by walking the HIR of the //! crate, and whenever we hit upon a public function, method, or static item, //! we create a mono item consisting of the items DefId and, since we only -//! consider non-generic items, an empty type-substitution set. (In eager +//! consider non-generic items, an empty type-parameters set. (In eager //! collection mode, during incremental compilation, all non-generic functions //! are considered as roots, as well as when the `-Clink-dead-code` option is //! specified. Functions marked `#[no_mangle]` and functions called by inlinable @@ -1383,11 +1383,11 @@ fn create_mono_items_for_default_impls<'tcx>( // items, we never actually check that the predicates of this impl are satisfied // in a empty reveal-all param env (i.e. with no assumptions). // - // Even though this impl has no type or const substitutions, because we don't + // Even though this impl has no type or const generic parameters, because we don't // consider higher-ranked predicates such as `for<'a> &'a mut [u8]: Copy` to // be trivially false. We must now check that the impl has no impossible-to-satisfy // predicates. - if tcx.subst_and_check_impossible_predicates((item.owner_id.to_def_id(), impl_args)) { + if tcx.instantiate_and_check_impossible_predicates((item.owner_id.to_def_id(), impl_args)) { return; } @@ -1404,7 +1404,7 @@ fn create_mono_items_for_default_impls<'tcx>( } // As mentioned above, the method is legal to eagerly instantiate if it - // only has lifetime substitutions. This is validated by + // only has lifetime generic parameters. This is validated by let args = trait_ref.args.extend_to(tcx, method.def_id, only_region_params); let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args); diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 009bd0b97b605..fb42532e247af 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -90,7 +90,7 @@ fn should_polymorphize<'tcx>( def_id: DefId, instance: ty::InstanceDef<'tcx>, ) -> bool { - // If an instance's MIR body is not polymorphic then the modified substitutions that are + // If an instance's MIR body is not polymorphic then the modified generic parameters that are // derived from polymorphization's result won't make any difference. if !instance.has_polymorphic_mir_body() { return false; diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index e11102c459e42..486396b067726 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -263,11 +263,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { for &(variant, field) in indices { match current_ty.kind() { - ty::Adt(def, subst) => { + ty::Adt(def, args) => { let field = &def.variant(variant).fields[field]; self.insert_def_id(field.did); - let field_ty = field.ty(self.tcx, subst); + let field_ty = field.ty(self.tcx, args); current_ty = self.tcx.normalize_erasing_regions(param_env, field_ty); } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index a8fe0cb6a1dc7..5b62731e20210 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -173,7 +173,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> { variant.fields.iter().enumerate().filter_map(move |(i, field)| { let ty = field.ty(cx.tcx, args); - // `field.ty()` doesn't normalize after substituting. + // `field.ty()` doesn't normalize after instantiating. let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty); let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx); let is_uninhabited = (cx.tcx.features().exhaustive_patterns diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 6d8e7ba937eee..9d8a9f5fce3e4 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -133,7 +133,7 @@ where if V::SHALLOW { ControlFlow::Continue(()) } else { - assoc_args.iter().try_for_each(|subst| subst.visit_with(self)) + assoc_args.iter().try_for_each(|arg| arg.visit_with(self)) } } @@ -209,7 +209,7 @@ where // Visitors searching for minimal visibility/reachability want to // conservatively approximate associated types like `Type::Alias` // as visible/reachable even if `Type` is private. - // Ideally, associated types should be substituted in the same way as + // Ideally, associated types should be instantiated in the same way as // free type aliases, but this isn't done yet. return ControlFlow::Continue(()); } @@ -230,7 +230,7 @@ where } else if kind == ty::Projection { self.visit_projection_ty(data) } else { - data.args.iter().try_for_each(|subst| subst.visit_with(self)) + data.args.iter().try_for_each(|arg| arg.visit_with(self)) }; } ty::Dynamic(predicates, ..) => { diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 94a1fb33f99c5..70d7200bf6005 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -369,7 +369,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); let instance = tables.instances[def]; - assert!(!instance.has_non_region_param(), "{instance:?} needs further substitution"); + assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation"); instance.ty(tables.tcx, ParamEnv::reveal_all()).stable(&mut *tables) } diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 646649293fc76..83e920e2f8ee4 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -99,7 +99,7 @@ fn get_symbol_hash<'tcx>( instance: Instance<'tcx>, // type of the item, without any generic - // parameters substituted; this is + // parameters instantiated; this is // included in the hash as a kind of // safeguard. item_type: Ty<'tcx>, diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 530221555c52e..72c8181152df0 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -251,8 +251,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { None => "M", }); - // Encode impl generic params if the substitutions contain parameters (implying - // polymorphization is enabled) and this isn't an inherent impl. + // Encode impl generic params if the generic parameters contain non-region parameters + // (implying polymorphization is enabled) and this isn't an inherent impl. if impl_trait_ref.is_some() && args.iter().any(|a| a.has_non_region_param()) { self.path_generic_args( |this| { diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index 819b070cf8b86..3b902dd80f59b 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -576,7 +576,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>( assert_eq!( old_ty, None, - "{} has two substitutions: {} and {}", + "{} has two generic parameters: {} and {}", proj.projection_ty, proj.term, old_ty.unwrap() diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index ecdae2521b933..1a6aa3f144c3e 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -192,11 +192,14 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { original_values: Vec>, response: CanonicalResponse<'tcx>, ) -> Result<(Certainty, Vec>>), NoSolution> { - let substitution = - Self::compute_query_response_substitution(self.infcx, &original_values, &response); + let instantiation = Self::compute_query_response_instantiation_values( + self.infcx, + &original_values, + &response, + ); let Response { var_values, external_constraints, certainty } = - response.substitute(self.tcx(), &substitution); + response.instantiate(self.tcx(), &instantiation); let nested_goals = Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values)?; @@ -209,10 +212,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok((certainty, nested_goals)) } - /// This returns the substitutions to instantiate the bound variables of + /// This returns the canoncial variable values to instantiate the bound variables of /// the canonical response. This depends on the `original_values` for the /// bound variables. - fn compute_query_response_substitution>( + fn compute_query_response_instantiation_values>( infcx: &InferCtxt<'tcx>, original_values: &[ty::GenericArg<'tcx>], response: &Canonical<'tcx, T>, @@ -369,10 +372,10 @@ impl<'tcx> inspect::ProofTreeBuilder<'tcx> { original_values: &[ty::GenericArg<'tcx>], state: inspect::CanonicalState<'tcx, T>, ) -> Result<(Vec>>, T), NoSolution> { - let substitution = - EvalCtxt::compute_query_response_substitution(infcx, original_values, &state); + let instantiation = + EvalCtxt::compute_query_response_instantiation_values(infcx, original_values, &state); - let inspect::State { var_values, data } = state.substitute(infcx.tcx, &substitution); + let inspect::State { var_values, data } = state.instantiate(infcx.tcx, &instantiation); let nested_goals = EvalCtxt::unify_query_var_values(infcx, param_env, original_values, var_values)?; diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index 69b6993043268..eab5962443696 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -312,8 +312,8 @@ fn rematch_unsize<'tcx>( let a_tail_ty = tail_field_ty.instantiate(tcx, a_args); let b_tail_ty = tail_field_ty.instantiate(tcx, b_args); - // Substitute just the unsizing params from B into A. The type after - // this substitution must be equal to B. This is so we don't unsize + // Instantiate just the unsizing params from B into A. The type after + // this instantiation must be equal to B. This is so we don't unsize // unrelated type parameters. let new_a_args = tcx.mk_args_from_iter( a_args @@ -349,7 +349,7 @@ fn rematch_unsize<'tcx>( let (a_last_ty, a_rest_tys) = a_tys.split_last().unwrap(); let b_last_ty = b_tys.last().unwrap(); - // Substitute just the tail field of B., and require that they're equal. + // Instantiate just the tail field of B., and require that they're equal. let unsized_a_ty = Ty::new_tup_from_iter(tcx, a_rest_tys.iter().chain([b_last_ty]).copied()); nested.extend( diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs index b2dff9b48ff38..52d2fe1e3ec22 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs @@ -1,7 +1,7 @@ //! Computes a normalizes-to (projection) goal for inherent associated types, //! `#![feature(inherent_associated_type)]`. Since astconv already determines //! which impl the IAT is being projected from, we just: -//! 1. instantiate substs, +//! 1. instantiate generic parameters, //! 2. equate the self type, and //! 3. instantiate and register where clauses. use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, QueryResult}; @@ -19,21 +19,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let expected = goal.predicate.term.ty().expect("inherent consts are treated separately"); let impl_def_id = tcx.parent(inherent.def_id); - let impl_substs = self.fresh_args_for_item(impl_def_id); + let impl_args = self.fresh_args_for_item(impl_def_id); // Equate impl header and add impl where clauses self.eq( goal.param_env, inherent.self_ty(), - tcx.type_of(impl_def_id).instantiate(tcx, impl_substs), + tcx.type_of(impl_def_id).instantiate(tcx, impl_args), )?; // Equate IAT with the RHS of the project goal - let inherent_substs = inherent.rebase_inherent_args_onto_impl(impl_substs, tcx); + let inherent_args = inherent.rebase_inherent_args_onto_impl(impl_args, tcx); self.eq( goal.param_env, expected, - tcx.type_of(inherent.def_id).instantiate(tcx, inherent_substs), + tcx.type_of(inherent.def_id).instantiate(tcx, inherent_args), ) .expect("expected goal term to be fully unconstrained"); @@ -46,7 +46,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.add_goals( GoalSource::Misc, tcx.predicates_of(inherent.def_id) - .instantiate(tcx, inherent_substs) + .instantiate(tcx, inherent_args) .into_iter() .map(|(pred, _)| goal.with(tcx, pred)), ); diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 044832224e5c1..32b46c7ac4441 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -877,8 +877,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let a_tail_ty = tail_field_ty.instantiate(tcx, a_args); let b_tail_ty = tail_field_ty.instantiate(tcx, b_args); - // Substitute just the unsizing params from B into A. The type after - // this substitution must be equal to B. This is so we don't unsize + // Instantiate just the unsizing params from B into A. The type after + // this instantiation must be equal to B. This is so we don't unsize // unrelated type parameters. let new_a_args = tcx.mk_args_from_iter( a_args @@ -927,7 +927,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap(); let &b_last_ty = b_tys.last().unwrap(); - // Substitute just the tail field of B., and require that they're equal. + // Instantiate just the tail field of B., and require that they're equal. let unsized_a_ty = Ty::new_tup_from_iter(tcx, a_rest_tys.iter().copied().chain([b_last_ty])); self.eq(goal.param_env, unsized_a_ty, b_ty)?; diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index cbe9a238b1c28..e48bd437f59c5 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -84,7 +84,7 @@ impl TrackAmbiguityCauses { /// If there are types that satisfy both impls, returns `Some` /// with a suitably-freshened `ImplHeader` with those types -/// substituted. Otherwise, returns `None`. +/// instantiated. Otherwise, returns `None`. #[instrument(skip(tcx, skip_leak_check), level = "debug")] pub fn overlapping_impls( tcx: TyCtxt<'_>, @@ -561,21 +561,21 @@ pub fn trait_ref_is_knowable<'tcx, E: Debug>( ) -> Result, E> { if orphan_check_trait_ref(trait_ref, InCrate::Remote, &mut lazily_normalize_ty)?.is_ok() { // A downstream or cousin crate is allowed to implement some - // substitution of this trait-ref. + // generic parameters of this trait-ref. return Ok(Err(Conflict::Downstream)); } if trait_ref_is_local_or_fundamental(tcx, trait_ref) { // This is a local or fundamental trait, so future-compatibility // is no concern. We know that downstream/cousin crates are not - // allowed to implement a substitution of this trait ref, which - // means impls could only come from dependencies of this crate, - // which we already know about. + // allowed to implement a generic parameter of this trait ref, + // which means impls could only come from dependencies of this + // crate, which we already know about. return Ok(Ok(())); } // This is a remote non-fundamental trait, so if another crate - // can be the "final owner" of a substitution of this trait-ref, + // can be the "final owner" of the generic parameters of this trait-ref, // they are allowed to implement it future-compatibly. // // However, if we are a final owner, then nobody else can be, @@ -628,8 +628,8 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe /// /// The current rule is that a trait-ref orphan checks in a crate C: /// -/// 1. Order the parameters in the trait-ref in subst order - Self first, -/// others linearly (e.g., `>` is U < V < W). +/// 1. Order the parameters in the trait-ref in generic parameters order +/// - Self first, others linearly (e.g., `>` is U < V < W). /// 2. Of these type parameters, there is at least one type parameter /// in which, walking the type as a tree, you can reach a type local /// to C where all types in-between are fundamental types. Call the @@ -696,7 +696,7 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe /// /// Because we never perform negative reasoning generically (coherence does /// not involve type parameters), this can be interpreted as doing the full -/// orphan check (using InCrate::Local mode), substituting non-local known +/// orphan check (using InCrate::Local mode), instantiating non-local known /// types for all inference variables. /// /// This allows for crates to future-compatibly add impls as long as they diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs index ca43436848bae..15d064d4036ea 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs @@ -242,7 +242,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { self.tcx.lang_items().fn_once_trait(), ] { let Some(trait_def_id) = trait_def_id else { continue }; - // Make a fresh inference variable so we can determine what the substitutions + // Make a fresh inference variable so we can determine what the generic parameters // of the trait are. let var = self.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index ceff718764685..f0773fd1671e2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -814,7 +814,7 @@ impl<'tcx> OnUnimplementedFormatString { tcx.dcx(), self.span, E0231, - "only named substitution parameters are allowed" + "only named generic parameters are allowed" ) .emit(); result = Err(reported); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index eb75b04ed1c0d..c7b56aac7e55b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -635,7 +635,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { | hir::Node::ImplItem(hir::ImplItem { generics, .. }) if param_ty => { - // We skip the 0'th subst (self) because we do not want + // We skip the 0'th arg (self) because we do not want // to consider the predicate as not suggestible if the // self type is an arg position `impl Trait` -- instead, // we handle that by adding ` + Bound` below. @@ -2343,7 +2343,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err: &mut DiagnosticBuilder<'tcx>, ) { // First, look for an `ExprBindingObligation`, which means we can get - // the unsubstituted predicate list of the called function. And check + // the uninstantiated predicate list of the called function. And check // that the predicate that we failed to satisfy is a `Fn`-like trait. if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = cause && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 7d14395850b04..e192c8a04fd67 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -2426,16 +2426,16 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // known, since we don't dispatch based on region // relationships. - // Pick the first substitution that still contains inference variables as the one + // Pick the first generic parameter that still contains inference variables as the one // we're going to emit an error for. If there are none (see above), fall back to // a more general error. - let subst = data.trait_ref.args.iter().find(|s| s.has_non_region_infer()); + let arg = data.trait_ref.args.iter().find(|s| s.has_non_region_infer()); - let mut err = if let Some(subst) = subst { + let mut err = if let Some(arg) = arg { self.emit_inference_failure_err( obligation.cause.body_id, span, - subst, + arg, ErrorCode::E0283, true, ) @@ -2473,9 +2473,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer { if let Some(e) = self.tainted_by_errors() - && subst.is_none() + && arg.is_none() { - // If `subst.is_none()`, then this is probably two param-env + // If `arg.is_none()`, then this is probably two param-env // candidates or impl candidates that are equal modulo lifetimes. // Therefore, if we've already emitted an error, just skip this // one, since it's not particularly actionable. @@ -2509,7 +2509,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); } - if let Some(ty::GenericArgKind::Type(_)) = subst.map(|subst| subst.unpack()) + if let Some(ty::GenericArgKind::Type(_)) = arg.map(|arg| arg.unpack()) && let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) { @@ -2687,23 +2687,23 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // other `Foo` impls are incoherent. return guar; } - let subst = data + let arg = data .projection_ty .args .iter() .chain(Some(data.term.into_arg())) .find(|g| g.has_non_region_infer()); - if let Some(subst) = subst { + if let Some(arg) = arg { self.emit_inference_failure_err( obligation.cause.body_id, span, - subst, + arg, ErrorCode::E0284, true, ) .with_note(format!("cannot satisfy `{predicate}`")) } else { - // If we can't find a substitution, just print a generic error + // If we can't find a generic parameter, just print a generic error struct_span_code_err!( self.dcx(), span, @@ -2722,18 +2722,18 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let Some(e) = self.tainted_by_errors() { return e; } - let subst = data.walk().find(|g| g.is_non_region_infer()); - if let Some(subst) = subst { + let arg = data.walk().find(|g| g.is_non_region_infer()); + if let Some(arg) = arg { let err = self.emit_inference_failure_err( obligation.cause.body_id, span, - subst, + arg, ErrorCode::E0284, true, ); err } else { - // If we can't find a substitution, just print a generic error + // If we can't find a generic parameter, just print a generic error struct_span_code_err!( self.dcx(), span, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index a7f6021d57a96..7caaccab63bc1 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -443,11 +443,11 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec( +fn instantiate_and_check_impossible_predicates<'tcx>( tcx: TyCtxt<'tcx>, key: (DefId, GenericArgsRef<'tcx>), ) -> bool { - debug!("subst_and_check_impossible_predicates(key={:?})", key); + debug!("instantiate_and_check_impossible_predicates(key={:?})", key); let mut predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates; @@ -461,7 +461,7 @@ fn subst_and_check_impossible_predicates<'tcx>( predicates.retain(|predicate| !predicate.has_param()); let result = impossible_predicates(tcx, predicates); - debug!("subst_and_check_impossible_predicates(key={:?}) = {:?}", key, result); + debug!("instantiate_and_check_impossible_predicates(key={:?}) = {:?}", key, result); result } @@ -548,7 +548,7 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, - subst_and_check_impossible_predicates, + instantiate_and_check_impossible_predicates, check_tys_might_be_eq: misc::check_tys_might_be_eq, is_impossible_associated_item, ..*providers diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 3289dfe343e1a..29a4a078fe03f 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -263,7 +263,7 @@ fn predicates_reference_self( predicates .predicates .iter() - .map(|&(predicate, sp)| (predicate.subst_supertrait(tcx, &trait_ref), sp)) + .map(|&(predicate, sp)| (predicate.instantiate_supertrait(tcx, &trait_ref), sp)) .filter_map(|predicate| predicate_references_self(tcx, predicate)) .collect() } @@ -607,7 +607,7 @@ fn virtual_call_violations_for_method<'tcx>( errors } -/// Performs a type substitution to produce the version of `receiver_ty` when `Self = self_ty`. +/// Performs a type instantiation to produce the version of `receiver_ty` when `Self = self_ty`. /// For example, for `receiver_ty = Rc` and `self_ty = Foo`, returns `Rc`. fn receiver_for_self_ty<'tcx>( tcx: TyCtxt<'tcx>, @@ -682,7 +682,7 @@ fn object_ty_for_trait<'tcx>( /// ``` /// /// where `Foo[X => Y]` means "the same type as `Foo`, but with `X` replaced with `Y`" -/// (substitution notation). +/// (instantiation notation). /// /// Some examples of receiver types and their required obligation: /// - `&'a mut self` requires `&'a mut Self: DispatchFromDyn<&'a mut dyn Trait>`, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 054402acb5c5c..049877bc5fed4 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -266,7 +266,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>( // universe just created. Otherwise, we can end up with something like `for<'a> I: 'a`, // which isn't quite what we want. Ideally, we want either an implied // `for<'a where I: 'a> I: 'a` or we want to "lazily" check these hold when we - // substitute concrete regions. There is design work to be done here; until then, + // instantiate concrete regions. There is design work to be done here; until then, // however, this allows experimenting potential GAT features without running into // well-formedness issues. let new_obligations = obligations @@ -1115,7 +1115,7 @@ impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { /// as Trait>::Item`. The result is always a type (and possibly /// additional obligations). If ambiguity arises, which implies that /// there are unresolved type variables in the projection, we will -/// substitute a fresh type variable `$X` and generate a new +/// instantiate it with a fresh type variable `$X` and generate a new /// obligation `::Item == $X` for later. pub fn normalize_projection_type<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, @@ -1400,7 +1400,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( cause.span, cause.body_id, // FIXME(inherent_associated_types): Since we can't pass along the self type to the - // cause code, inherent projections will be printed with identity substitutions in + // cause code, inherent projections will be printed with identity instantiation in // diagnostics which is not ideal. // Consider creating separate cause codes for this specific situation. if span.is_dummy() { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs index 0aaeacb6a239a..aca16950223c5 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs @@ -116,7 +116,7 @@ fn relate_mir_and_user_args<'tcx>( ocx.register_obligation(Obligation::new(tcx, cause, param_env, instantiated_predicate)); } - // Now prove the well-formedness of `def_id` with `substs`. + // Now prove the well-formedness of `def_id` with `args`. // Note for some items, proving the WF of `ty` is not sufficient because the // well-formedness of an item may depend on the WF of gneneric args not present in the // item's type. Currently this is true for associated consts, e.g.: diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 83d23597c0cd8..423ed0f7105be 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -170,7 +170,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>( } // Compute the obligations for `arg` to be well-formed. If `arg` is - // an unresolved inference variable, just substituted an empty set + // an unresolved inference variable, just instantiated an empty set // -- because the return type here is going to be things we *add* // to the environment, it's always ok for this set to be smaller // than the ultimate set. (Note: normally there won't be diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index f9a292c2bd7ff..bafb8c10bf1ca 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -557,7 +557,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.predicate.def_id(), obligation.predicate.skip_binder().trait_ref.self_ty(), |impl_def_id| { - // Before we create the substitutions and everything, first + // Before we create the generic parameters and everything, first // consider a "quick reject". This avoids creating more types // and so forth that we need to. let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 6ca249339791c..2ce33a4d122d9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -444,7 +444,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> { debug!(?obligation, ?impl_def_id, "confirm_impl_candidate"); - // First, create the substitutions by matching the impl again, + // First, create the generic parameters by matching the impl again, // this time not in a probe. let args = self.rematch_impl(impl_def_id, obligation); debug!(?args, "impl args"); @@ -585,7 +585,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // higher-ranked things. // Prevent, e.g., `dyn Iterator`. for bound in self.tcx().item_bounds(assoc_type).transpose_iter() { - let subst_bound = if defs.count() == 0 { + let arg_bound = if defs.count() == 0 { bound.instantiate(tcx, trait_predicate.trait_ref.args) } else { let mut args = smallvec::SmallVec::with_capacity(defs.count()); @@ -649,7 +649,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - subst_bound, + arg_bound, &mut nested, ); nested.push(obligation.with(tcx, normalized_bound)); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ac6cfcdeb5950..368427dfb27ca 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1684,7 +1684,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Return `Yes` if the obligation's predicate type applies to the env_predicate, and /// `No` if it does not. Return `Ambiguous` in the case that the projection type is a GAT, - /// and applying this env_predicate constrains any of the obligation's GAT substitutions. + /// and applying this env_predicate constrains any of the obligation's GAT parameters. /// /// This behavior is a somewhat of a hack to prevent over-constraining inference variables /// in cases like #91762. @@ -2673,7 +2673,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } /// Returns the obligations that are implied by instantiating an - /// impl or trait. The obligations are substituted and fully + /// impl or trait. The obligations are instantiated and fully /// normalized. This is used when confirming an impl or default /// impl. #[instrument(level = "debug", skip(self, cause, param_env))] @@ -2698,7 +2698,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // U: Iterator, U: Sized, // V: Iterator, V: Sized, // ::Item: Copy - // When we substitute, say, `V => IntoIter, U => $0`, the last + // When we instantiate, say, `V => IntoIter, U => $0`, the last // obligation will normalize to `<$0 as Iterator>::Item = $1` and // `$1: Copy`, so we must ensure the obligations are emitted in // that order. diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 8e0fa79c97748..be066e45d0a80 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -41,17 +41,17 @@ pub struct OverlapError<'tcx> { pub involves_placeholder: bool, } -/// Given a subst for the requested impl, translate it to a subst +/// Given the generic parameters for the requested impl, translate it to the generic parameters /// appropriate for the actual item definition (whether it be in that impl, /// a parent impl, or the trait). /// /// When we have selected one impl, but are actually using item definitions from /// a parent impl providing a default, we need a way to translate between the /// type parameters of the two impls. Here the `source_impl` is the one we've -/// selected, and `source_args` is a substitution of its generics. +/// selected, and `source_args` is its generic parameters. /// And `target_node` is the impl/trait we're actually going to get the -/// definition from. The resulting substitution will map from `target_node`'s -/// generics to `source_impl`'s generics as instantiated by `source_subst`. +/// definition from. The resulting instantiation will map from `target_node`'s +/// generics to `source_impl`'s generics as instantiated by `source_args`. /// /// For example, consider the following scenario: /// @@ -62,7 +62,7 @@ pub struct OverlapError<'tcx> { /// ``` /// /// Suppose we have selected "source impl" with `V` instantiated with `u32`. -/// This function will produce a substitution with `T` and `U` both mapping to `u32`. +/// This function will produce an instantiation with `T` and `U` both mapping to `u32`. /// /// where-clauses add some trickiness here, because they can be used to "define" /// an argument indirectly: @@ -72,7 +72,7 @@ pub struct OverlapError<'tcx> { /// where I: Iterator, T: Clone /// ``` /// -/// In a case like this, the substitution for `T` is determined indirectly, +/// In a case like this, the instantiation for `T` is determined indirectly, /// through associated type projection. We deal with such cases by using /// *fulfillment* to relate the two impls, requiring that all projections are /// resolved. @@ -109,7 +109,7 @@ pub fn translate_args_with_cause<'tcx>( let source_trait_ref = infcx.tcx.impl_trait_ref(source_impl).unwrap().instantiate(infcx.tcx, source_args); - // translate the Self and Param parts of the substitution, since those + // translate the Self and Param parts of the generic parameters, since those // vary across impls let target_args = match target_node { specialization_graph::Node::Impl(target_impl) => { @@ -121,8 +121,8 @@ pub fn translate_args_with_cause<'tcx>( fulfill_implication(infcx, param_env, source_trait_ref, source_impl, target_impl, cause) .unwrap_or_else(|()| { bug!( - "When translating substitutions from {source_impl:?} to {target_impl:?}, \ - the expected specialization failed to hold" + "When translating generic parameters from {source_impl:?} to \ + {target_impl:?}, the expected specialization failed to hold" ) }) } @@ -200,7 +200,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, } /// Attempt to fulfill all obligations of `target_impl` after unification with -/// `source_trait_ref`. If successful, returns a substitution for *all* the +/// `source_trait_ref`. If successful, returns the generic parameters for *all* the /// generics of `target_impl`, including both those needed to unify with /// `source_trait_ref` and those whose identity is determined via a where /// clause in the impl. @@ -247,7 +247,7 @@ fn fulfill_implication<'tcx>( }; // Needs to be `in_snapshot` because this function is used to rebase - // substitutions, which may happen inside of a select within a probe. + // generic parameters, which may happen inside of a select within a probe. let ocx = ObligationCtxt::new(infcx); // attempt to prove all of the predicates for impl2 given those for impl1 // (which are packed up in penv) @@ -269,7 +269,7 @@ fn fulfill_implication<'tcx>( debug!("fulfill_implication: an impl for {:?} specializes {:?}", source_trait, target_trait); - // Now resolve the *substitution* we built for the target earlier, replacing + // Now resolve the *generic parameters* we built for the target earlier, replacing // the inference variables inside with whatever we got from fulfillment. Ok(infcx.resolve_vars_if_possible(target_args)) } diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index c40ed10e52ff3..af172eb071323 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -128,7 +128,7 @@ impl<'tcx> TraitAliasExpander<'tcx> { debug!(?predicates); let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| { - pred.subst_supertrait(tcx, &trait_ref) + pred.instantiate_supertrait(tcx, &trait_ref) .as_trait_clause() .map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span)) }); diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index d39583b5c7d88..3c0316fce171d 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -124,7 +124,7 @@ fn prepare_vtable_segments_inner<'tcx, T>( .predicates .into_iter() .filter_map(move |(pred, _)| { - pred.subst_supertrait(tcx, &inner_most_trait_ref).as_trait_clause() + pred.instantiate_supertrait(tcx, &inner_most_trait_ref).as_trait_clause() }); // Find an unvisited supertrait diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index b4f13ee95a652..c727ef53d5552 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -380,7 +380,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { .filter(|(_, arg)| !arg.has_escaping_bound_vars()) .map(|(i, arg)| { let mut cause = traits::ObligationCause::misc(self.span, self.body_id); - // The first subst is the self ty - use the correct span for it. + // The first arg is the self ty - use the correct span for it. if i == 0 { if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) = item.map(|i| &i.kind) diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 21a016e29d699..07089d5f19ec0 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -42,7 +42,7 @@ fn normalize_projection_ty<'tcx>( ); ocx.register_obligations(obligations); // #112047: With projections and opaques, we are able to create opaques that - // are recursive (given some substitution of the opaque's type variables). + // are recursive (given some generic parameters of the opaque's type variables). // In that case, we may only realize a cycle error when calling // `normalize_erasing_regions` in mono. if !ocx.infcx.next_trait_solver() { diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 0542ef4ecf902..638c9a53d22ab 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -50,7 +50,7 @@ fn fn_sig_for_fn_abi<'tcx>( // `tests/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping // track of a polymorphization `ParamEnv` to allow normalizing later. // - // We normalize the `fn_sig` again after substituting at a later point. + // We normalize the `fn_sig` again after instantiating at a later point. let mut sig = match *ty.kind() { ty::FnDef(def_id, args) => tcx .fn_sig(def_id) @@ -163,7 +163,7 @@ fn fn_sig_for_fn_abi<'tcx>( // a separate def-id for these bodies. if let InstanceDef::CoroutineKindShim { target_kind, .. } = instance.def { // Grab the parent coroutine-closure. It has the same args for the purposes - // of substitution, so this will be okay to do. + // of instantiation, so this will be okay to do. let ty::CoroutineClosure(_, coroutine_closure_args) = *tcx .instantiate_and_normalize_erasing_regions( args, diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index f20ded355b1cd..96f8148bf7204 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -741,7 +741,7 @@ fn coroutine_layout<'tcx>( ) -> Result, &'tcx LayoutError<'tcx>> { use SavedLocalEligibility::*; let tcx = cx.tcx; - let subst_field = |ty: Ty<'tcx>| EarlyBinder::bind(ty).instantiate(tcx, args); + let instantiate_field = |ty: Ty<'tcx>| EarlyBinder::bind(ty).instantiate(tcx, args); let Some(info) = tcx.coroutine_layout(def_id) else { return Err(error(cx, LayoutError::Unknown(ty))); @@ -763,7 +763,7 @@ fn coroutine_layout<'tcx>( let tag_layout = cx.tcx.mk_layout(LayoutS::scalar(cx, tag)); let promoted_layouts = ineligible_locals.iter().map(|local| { - let field_ty = subst_field(info.field_tys[local].ty); + let field_ty = instantiate_field(info.field_tys[local].ty); let uninit_ty = Ty::new_maybe_uninit(tcx, field_ty); Ok(cx.spanned_layout_of(uninit_ty, info.field_tys[local].source_info.span)?.layout) }); @@ -838,7 +838,7 @@ fn coroutine_layout<'tcx>( Ineligible(_) => false, }) .map(|local| { - let field_ty = subst_field(info.field_tys[*local].ty); + let field_ty = instantiate_field(info.field_tys[*local].ty); Ty::new_maybe_uninit(tcx, field_ty) }); diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 7b3d2ab22cfa4..48339e6120ad3 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -264,9 +264,9 @@ fn drop_tys_helper<'tcx>( ) -> NeedsDropResult>> { iter.into_iter().try_fold(Vec::new(), |mut vec, subty| { match subty.kind() { - ty::Adt(adt_id, subst) => { + ty::Adt(adt_id, args) => { for subty in tcx.adt_drop_tys(adt_id.did())? { - vec.push(EarlyBinder::bind(subty).instantiate(tcx, subst)); + vec.push(EarlyBinder::bind(subty).instantiate(tcx, args)); } } _ => vec.push(subty), @@ -300,7 +300,10 @@ fn drop_tys_helper<'tcx>( } else { let field_tys = adt_def.all_fields().map(|field| { let r = tcx.type_of(field.did).instantiate(tcx, args); - debug!("drop_tys_helper: Subst into {:?} with {:?} getting {:?}", field, args, r); + debug!( + "drop_tys_helper: Instantiate into {:?} with {:?} getting {:?}", + field, args, r + ); r }); if only_significant { @@ -363,7 +366,7 @@ fn adt_drop_tys<'tcx>( .map(|components| tcx.mk_type_list(&components)) } // If `def_id` refers to a generic ADT, the queries above and below act as if they had been handed -// a `tcx.make_ty(def, identity_args)` and as such it is legal to substitute the generic parameters +// a `tcx.make_ty(def, identity_args)` and as such it is legal to instantiate the generic parameters // of the ADT into the outputted `ty`s. fn adt_significant_drop_tys( tcx: TyCtxt<'_>, diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index ef67317a601ac..329cf32cad5ea 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -155,7 +155,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { // Collect opaque types nested within the associated type bounds of this opaque type. // We use identity args here, because we already know that the opaque type uses - // only generic parameters, and thus substituting would not give us more information. + // only generic parameters, and thus instantiating would not give us more information. for (pred, span) in self .tcx .explicit_item_bounds(alias_ty.def_id) @@ -211,7 +211,7 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { // in the same impl block. if let Some(parent_trait_ref) = self.parent_trait_ref() { // If the trait ref of the associated item and the impl differs, - // then we can't use the impl's identity substitutions below, so + // then we can't use the impl's identity args below, so // just skip. if alias_ty.trait_ref(self.tcx) == parent_trait_ref { let parent = self.parent().expect("we should have a parent here"); @@ -258,11 +258,11 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { for field in variant.fields.iter() { // Don't use the `ty::Adt` args, we either // * found the opaque in the args - // * will find the opaque in the unsubstituted fields - // The only other situation that can occur is that after substituting, + // * will find the opaque in the uninstantiated fields + // The only other situation that can occur is that after instantiating, // some projection resolves to an opaque that we would have otherwise - // not found. While we could substitute and walk those, that would mean we - // would have to walk all substitutions of an Adt, which can quickly + // not found. While we could instantiate and walk those, that would mean we + // would have to walk all generic parameters of an Adt, which can quickly // degenerate into looking at an exponential number of types. let ty = self.tcx.type_of(field.did).instantiate_identity(); self.visit_spanned(self.tcx.def_span(field.did), ty); @@ -306,7 +306,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInAssocTypeCollector<'tcx> { .parent_trait_ref() .expect("impl trait in assoc type collector used on non-assoc item"); // If the trait ref of the associated item and the impl differs, - // then we can't use the impl's identity substitutions below, so + // then we can't use the impl's identity args below, so // just skip. if alias_ty.trait_ref(self.0.tcx) == parent_trait_ref { let parent = self.0.parent().expect("we should have a parent here"); diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index 70f1f099688b8..3ca2aba7c0462 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs @@ -73,8 +73,8 @@ fn representability_adt_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Representab // At this point, we know that the item of the ADT type is representable; // but the type parameters may cause a cycle with an upstream type let params_in_repr = tcx.params_in_repr(adt.did()); - for (i, subst) in args.iter().enumerate() { - if let ty::GenericArgKind::Type(ty) = subst.unpack() { + for (i, arg) in args.iter().enumerate() { + if let ty::GenericArgKind::Type(ty) = arg.unpack() { if params_in_repr.contains(i as u32) { rtry!(representability_ty(tcx, ty)); } @@ -103,8 +103,8 @@ fn params_in_repr_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, params_in_repr: &mut match *ty.kind() { ty::Adt(adt, args) => { let inner_params_in_repr = tcx.params_in_repr(adt.did()); - for (i, subst) in args.iter().enumerate() { - if let ty::GenericArgKind::Type(ty) = subst.unpack() { + for (i, arg) in args.iter().enumerate() { + if let ty::GenericArgKind::Type(ty) = arg.unpack() { if inner_params_in_repr.contains(i as u32) { params_in_repr_ty(tcx, ty, params_in_repr); } diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index bc57d6daf4779..1da26cfc24275 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -5,7 +5,7 @@ bitflags! { /// over the type itself. #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub struct TypeFlags: u32 { - // Does this have parameters? Used to determine whether substitution is + // Does this have parameters? Used to determine whether instantiation is // required. /// Does this have `Param`? const HAS_TY_PARAM = 1 << 0; diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index 777c649fabd68..cf13f066cbf8f 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -64,17 +64,17 @@ use self::RegionKind::*; /// /// ## Bound Regions /// -/// These are regions that are stored behind a binder and must be substituted +/// These are regions that are stored behind a binder and must be instantiated /// with some concrete region before being used. There are two kind of /// bound regions: early-bound, which are bound in an item's `Generics`, -/// and are substituted by an `GenericArgs`, and late-bound, which are part of -/// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are substituted by +/// and are instantiated by an `GenericArgs`, and late-bound, which are part of +/// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are instantiated by /// the likes of `liberate_late_bound_regions`. The distinction exists /// because higher-ranked lifetimes aren't supported in all places. See [1][2]. /// /// Unlike `Param`s, bound regions are not supposed to exist "in the wild" /// outside their binder, e.g., in types passed to type inference, and -/// should first be substituted (by placeholder regions, free regions, +/// should first be instantiated (by placeholder regions, free regions, /// or region variables). /// /// ## Placeholder and Free Regions @@ -101,7 +101,7 @@ use self::RegionKind::*; /// `RePlaceholder` is designed for this purpose. In these contexts, /// there's also the risk that some inference variable laying around will /// get unified with your placeholder region: if you want to check whether -/// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a` +/// `for<'a> Foo<'_>: 'a`, and you instantiate your bound region `'a` /// with a placeholder region `'%a`, the variable `'_` would just be /// instantiated to the placeholder region `'%a`, which is wrong because /// the inference variable is supposed to satisfy the relation diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index a4fe572067b03..d389933fd2dfa 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -143,7 +143,7 @@ pub enum TyKind { /// For example, the type `List` would be represented using the `AdtDef` /// for `struct List` and the args `[i32]`. /// - /// Note that generic parameters in fields only get lazily substituted + /// Note that generic parameters in fields only get lazily instantiated /// by using something like `adt_def.all_fields().map(|field| field.ty(tcx, args))`. Adt(I::AdtDef, I::GenericArgs), @@ -197,14 +197,14 @@ pub enum TyKind { /// The anonymous type of a closure. Used to represent the type of `|a| a`. /// - /// Closure args contain both the - potentially substituted - generic parameters + /// Closure args contain both the - potentially instantiated - generic parameters /// of its parent and some synthetic parameters. See the documentation for /// `ClosureArgs` for more details. Closure(I::DefId, I::GenericArgs), /// The anonymous type of a closure. Used to represent the type of `async |a| a`. /// - /// Coroutine-closure args contain both the - potentially substituted - generic + /// Coroutine-closure args contain both the - potentially instantiated - generic /// parameters of its parent and some synthetic parameters. See the documentation /// for `CoroutineClosureArgs` for more details. CoroutineClosure(I::DefId, I::GenericArgs), diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs index fb83dae571423..de045f6b56ce9 100644 --- a/compiler/stable_mir/src/compiler_interface.rs +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -124,7 +124,7 @@ pub trait Context { /// Get the body of an Instance which is already monomorphized. fn instance_body(&self, instance: InstanceDef) -> Option; - /// Get the instance type with generic substitutions applied and lifetimes erased. + /// Get the instance type with generic instantiations applied and lifetimes erased. fn instance_ty(&self, instance: InstanceDef) -> Ty; /// Get the instantiation types. diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs index 6c791ae855225..97f57d2c7b359 100644 --- a/compiler/stable_mir/src/mir/mono.rs +++ b/compiler/stable_mir/src/mir/mono.rs @@ -57,7 +57,7 @@ impl Instance { with(|cx| cx.is_foreign_item(self.def.def_id())) } - /// Get the instance type with generic substitutions applied and lifetimes erased. + /// Get the instance type with generic instantiations applied and lifetimes erased. pub fn ty(&self) -> Ty { with(|context| context.instance_ty(self.def)) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 89977934cde9f..efe2816fbe63f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1796,7 +1796,7 @@ fn maybe_expand_private_type_alias<'tcx>( } else { Lifetime::elided() }; - args.insert(param.def_id.to_def_id(), SubstParam::Lifetime(cleaned)); + args.insert(param.def_id.to_def_id(), InstantiationParam::Lifetime(cleaned)); } indices.lifetimes += 1; } @@ -1813,9 +1813,15 @@ fn maybe_expand_private_type_alias<'tcx>( _ => None, }); if let Some(ty) = type_ { - args.insert(param.def_id.to_def_id(), SubstParam::Type(clean_ty(ty, cx))); + args.insert( + param.def_id.to_def_id(), + InstantiationParam::Type(clean_ty(ty, cx)), + ); } else if let Some(default) = *default { - args.insert(param.def_id.to_def_id(), SubstParam::Type(clean_ty(default, cx))); + args.insert( + param.def_id.to_def_id(), + InstantiationParam::Type(clean_ty(default, cx)), + ); } indices.types += 1; } @@ -1832,7 +1838,7 @@ fn maybe_expand_private_type_alias<'tcx>( _ => None, }); if let Some(_) = const_ { - args.insert(param.def_id.to_def_id(), SubstParam::Constant); + args.insert(param.def_id.to_def_id(), InstantiationParam::Constant); } // FIXME(const_generics_defaults) indices.consts += 1; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 6710193f9611a..96b4d1a45f6ea 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2542,14 +2542,14 @@ pub(crate) enum TypeBindingKind { /// ``` /// /// `public_fn`'s docs will show it as returning `Vec`, since `PrivAlias` is private. -/// [`SubstParam`] is used to record that `T` should be mapped to `i32`. -pub(crate) enum SubstParam { +/// [`InstantiationParam`] is used to record that `T` should be mapped to `i32`. +pub(crate) enum InstantiationParam { Type(Type), Lifetime(Lifetime), Constant, } -impl SubstParam { +impl InstantiationParam { pub(crate) fn as_ty(&self) -> Option<&Type> { if let Self::Type(ty) = self { Some(ty) } else { None } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 9eb62c258923f..28ccda39e4de2 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -44,10 +44,10 @@ pub(crate) struct DocContext<'tcx> { /// Used while populating `external_traits` to ensure we don't process the same trait twice at /// the same time. pub(crate) active_extern_traits: DefIdSet, - // The current set of parameter substitutions, + // The current set of parameter instantiations, // for expanding type aliases at the HIR level: - /// Table `DefId` of type, lifetime, or const parameter -> substituted type, lifetime, or const - pub(crate) args: DefIdMap, + /// Table `DefId` of type, lifetime, or const parameter -> instantiated type, lifetime, or const + pub(crate) args: DefIdMap, pub(crate) current_type_aliases: DefIdMap, /// Table synthetic type parameter for `impl Trait` in argument position -> bounds pub(crate) impl_trait_bounds: FxHashMap>, @@ -84,10 +84,10 @@ impl<'tcx> DocContext<'tcx> { } /// Call the closure with the given parameters set as - /// the substitutions for a type alias' RHS. + /// the generic parameters for a type alias' RHS. pub(crate) fn enter_alias( &mut self, - args: DefIdMap, + args: DefIdMap, def_id: DefId, f: F, ) -> R From db8cb766e23e5438007c8dd12f3392b7f41be56e Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Mon, 12 Feb 2024 16:24:41 +0900 Subject: [PATCH 09/17] Fix failing test --- tests/ui/on-unimplemented/bad-annotation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/on-unimplemented/bad-annotation.rs b/tests/ui/on-unimplemented/bad-annotation.rs index f05436b8c048a..4c6610f886433 100644 --- a/tests/ui/on-unimplemented/bad-annotation.rs +++ b/tests/ui/on-unimplemented/bad-annotation.rs @@ -25,7 +25,7 @@ trait BadAnnotation2 {} #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] -//~^ only named substitution parameters are allowed +//~^ only named generic parameters are allowed trait BadAnnotation3 {} From 8959434c70c2d3de86f5a1539792fa06de3c5715 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Mon, 12 Feb 2024 18:09:39 +0900 Subject: [PATCH 10/17] Fix failing test --- tests/ui/on-unimplemented/bad-annotation.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/on-unimplemented/bad-annotation.stderr b/tests/ui/on-unimplemented/bad-annotation.stderr index a8d3c8680faae..9bb9423788c20 100644 --- a/tests/ui/on-unimplemented/bad-annotation.stderr +++ b/tests/ui/on-unimplemented/bad-annotation.stderr @@ -17,7 +17,7 @@ error[E0230]: there is no parameter `C` on trait `BadAnnotation2` LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0231]: only named substitution parameters are allowed +error[E0231]: only named generic parameters are allowed --> $DIR/bad-annotation.rs:27:1 | LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] From 83a850f2a1259eb05ef444c81bcb5869d6dbf336 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Mon, 12 Feb 2024 09:06:45 -0300 Subject: [PATCH 11/17] Add lahfsahf and prfchw target feature --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 1 + compiler/rustc_codegen_ssa/src/target_features.rs | 2 ++ compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 2 ++ compiler/rustc_target/src/target_features.rs | 2 ++ tests/ui/check-cfg/well-known-values.stderr | 2 +- tests/ui/target-feature/gate.rs | 2 ++ tests/ui/target-feature/gate.stderr | 2 +- 8 files changed, 13 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 4bb400b187989..e48479c8da279 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -213,6 +213,7 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> { ("x86", "rdrand") => LLVMFeature::new("rdrnd"), ("x86", "bmi1") => LLVMFeature::new("bmi"), ("x86", "cmpxchg16b") => LLVMFeature::new("cx16"), + ("x86", "lahfsahf") => LLVMFeature::new("sahf"), ("aarch64", "rcpc2") => LLVMFeature::new("rcpc-immo"), ("aarch64", "dpb") => LLVMFeature::new("ccpp"), ("aarch64", "dpb2") => LLVMFeature::new("ccdp"), diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 3694e41a0e089..ee1d548b23190 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -77,6 +77,8 @@ pub fn from_target_feature( Some(sym::aarch64_ver_target_feature) => rust_features.aarch64_ver_target_feature, Some(sym::csky_target_feature) => rust_features.csky_target_feature, Some(sym::loongarch_target_feature) => rust_features.loongarch_target_feature, + Some(sym::lahfsahf_target_feature) => rust_features.lahfsahf_target_feature, + Some(sym::prfchw_target_feature) => rust_features.prfchw_target_feature, Some(name) => bug!("unknown target feature gate {}", name), None => true, }; diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index efb0b1fbabbc8..9012b731a1323 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -301,9 +301,11 @@ declare_features! ( (unstable, csky_target_feature, "1.73.0", Some(44839)), (unstable, ermsb_target_feature, "1.49.0", Some(44839)), (unstable, hexagon_target_feature, "1.27.0", Some(44839)), + (unstable, lahfsahf_target_feature, "CURRENT_RUSTC_VERSION", Some(44839)), (unstable, loongarch_target_feature, "1.73.0", Some(44839)), (unstable, mips_target_feature, "1.27.0", Some(44839)), (unstable, powerpc_target_feature, "1.27.0", Some(44839)), + (unstable, prfchw_target_feature, "CURRENT_RUSTC_VERSION", Some(44839)), (unstable, riscv_target_feature, "1.45.0", Some(44839)), (unstable, rtm_target_feature, "1.35.0", Some(44839)), (unstable, sse4a_target_feature, "1.27.0", Some(44839)), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index aa912c93c08c6..9cc4613bfb41f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -932,6 +932,7 @@ symbols! { kreg0, label, label_break_value, + lahfsahf_target_feature, lang, lang_items, large_assignments, @@ -1240,6 +1241,7 @@ symbols! { prelude, prelude_import, preserves_flags, + prfchw_target_feature, print_macro, println_macro, proc_dash_macro: "proc-macro", diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index c350a37975d23..04943fa3879fb 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -218,10 +218,12 @@ const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[ ("fma", Stable), ("fxsr", Stable), ("gfni", Unstable(sym::avx512_target_feature)), + ("lahfsahf", Unstable(sym::lahfsahf_target_feature)), ("lzcnt", Stable), ("movbe", Stable), ("pclmulqdq", Stable), ("popcnt", Stable), + ("prfchw", Unstable(sym::prfchw_target_feature)), ("rdrand", Stable), ("rdseed", Stable), ("rtm", Unstable(sym::rtm_target_feature)), diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 652e573d6ef32..7eeaa31cbb6c5 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -143,7 +143,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt` + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` diff --git a/tests/ui/target-feature/gate.rs b/tests/ui/target-feature/gate.rs index 971a4654b4cec..d6a191d7850b7 100644 --- a/tests/ui/target-feature/gate.rs +++ b/tests/ui/target-feature/gate.rs @@ -19,6 +19,8 @@ // gate-test-aarch64_ver_target_feature // gate-test-csky_target_feature // gate-test-loongarch_target_feature +// gate-test-lahfsahf_target_feature +// gate-test-prfchw_target_feature #[target_feature(enable = "avx512bw")] //~^ ERROR: currently unstable diff --git a/tests/ui/target-feature/gate.stderr b/tests/ui/target-feature/gate.stderr index d281f0a6ab922..31198f73c208f 100644 --- a/tests/ui/target-feature/gate.stderr +++ b/tests/ui/target-feature/gate.stderr @@ -1,5 +1,5 @@ error[E0658]: the target feature `avx512bw` is currently unstable - --> $DIR/gate.rs:23:18 + --> $DIR/gate.rs:25:18 | LL | #[target_feature(enable = "avx512bw")] | ^^^^^^^^^^^^^^^^^^^ From a313ffb8844d51f6048be35b1b0ea39e7dfc48c7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 12 Feb 2024 14:52:20 +0100 Subject: [PATCH 12/17] add another test for promoteds-in-static --- .../static-promoted-to-mutable-static.rs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/ui/consts/static-promoted-to-mutable-static.rs diff --git a/tests/ui/consts/static-promoted-to-mutable-static.rs b/tests/ui/consts/static-promoted-to-mutable-static.rs new file mode 100644 index 0000000000000..d49ba478dbc82 --- /dev/null +++ b/tests/ui/consts/static-promoted-to-mutable-static.rs @@ -0,0 +1,33 @@ +// check-pass +#![allow(non_camel_case_types, non_upper_case_globals, static_mut_ref)] + +pub struct wl_interface { + pub version: i32 +} + +pub struct Interface { + pub other_interfaces: &'static [&'static Interface], + pub c_ptr: Option<&'static wl_interface>, +} + +pub static mut wl_callback_interface: wl_interface = wl_interface { + version: 0, +}; + +pub static WL_CALLBACK_INTERFACE: Interface = Interface { + other_interfaces: &[], + c_ptr: Some(unsafe { &wl_callback_interface }), +}; + +// This static contains a promoted that points to a static that points to a mutable static. +pub static WL_SURFACE_INTERFACE: Interface = Interface { + other_interfaces: &[&WL_CALLBACK_INTERFACE], + c_ptr: None, +}; + +// And another variant of the same thing, this time with interior mutability. +use std::sync::OnceLock; +static LAZY_INIT: OnceLock = OnceLock::new(); +static LAZY_INIT_REF: &[&OnceLock] = &[&LAZY_INIT]; + +fn main() {} From cdea33aa2e40b6b40dfd8c13ad3954900f41d310 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 12 Feb 2024 12:00:33 -0500 Subject: [PATCH 13/17] Update books --- src/doc/edition-guide | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/edition-guide b/src/doc/edition-guide index baafacc6d8701..76bd48a273a0e 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit baafacc6d8701269dab1e1e333f3547fb54b5a59 +Subproject commit 76bd48a273a0e0413a3bf22c699112d41497b99e diff --git a/src/doc/reference b/src/doc/reference index a0b119535e774..8227666de13f6 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit a0b119535e7740f68494c4f0582f7ad008b00ccd +Subproject commit 8227666de13f6e7bb32dea9dc42e841adb5ce4b7 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 179256a445d61..e188d5d466f7f 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 179256a445d6144f5f371fdefb993f48f33978b0 +Subproject commit e188d5d466f7f3ff9f1d518393235f4fe951be46 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index ec287e3327776..1f30cc7cca9a3 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit ec287e332777627185be4798ad22599ffe7b84aa +Subproject commit 1f30cc7cca9a3433bc1872abdc98960b36c21ca0 From 915200fbe077786370bf40aac30aae36dd0ff71b Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 13 Dec 2023 14:40:19 +0100 Subject: [PATCH 14/17] Lint on reference casting to bigger underlying allocation --- compiler/rustc_lint/messages.ftl | 5 + compiler/rustc_lint/src/lints.rs | 14 +- compiler/rustc_lint/src/reference_casting.rs | 73 +++++++- tests/ui/cast/cast-rfc0401.rs | 12 +- tests/ui/lint/reference_casting.rs | 105 +++++++++++- tests/ui/lint/reference_casting.stderr | 165 ++++++++++++++++++- 6 files changed, 356 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 5652a34103b09..785895e0ab823 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -319,6 +319,11 @@ lint_invalid_nan_comparisons_lt_le_gt_ge = incorrect NaN comparison, NaN is not lint_invalid_reference_casting_assign_to_ref = assigning to `&T` is undefined behavior, consider using an `UnsafeCell` .label = casting happend here +lint_invalid_reference_casting_bigger_layout = casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + .label = casting happend here + .alloc = backing allocation comes from here + .layout = casting from `{$from_ty}` ({$from_size} bytes) to `{$to_ty}` ({$to_size} bytes) + lint_invalid_reference_casting_borrow_as_mut = casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` .label = casting happend here diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 42d9760f8aa14..7445e2e80b407 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -716,7 +716,7 @@ pub enum InvalidFromUtf8Diag { // reference_casting.rs #[derive(LintDiagnostic)] -pub enum InvalidReferenceCastingDiag { +pub enum InvalidReferenceCastingDiag<'tcx> { #[diag(lint_invalid_reference_casting_borrow_as_mut)] #[note(lint_invalid_reference_casting_note_book)] BorrowAsMut { @@ -733,6 +733,18 @@ pub enum InvalidReferenceCastingDiag { #[note(lint_invalid_reference_casting_note_ty_has_interior_mutability)] ty_has_interior_mutability: Option<()>, }, + #[diag(lint_invalid_reference_casting_bigger_layout)] + #[note(lint_layout)] + BiggerLayout { + #[label] + orig_cast: Option, + #[label(lint_alloc)] + alloc: Span, + from_ty: Ty<'tcx>, + from_size: u64, + to_ty: Ty<'tcx>, + to_size: u64, + }, } // hidden_unicode_codepoints.rs diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 9e6cca8531784..9d67fd4b892e7 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -1,6 +1,7 @@ use rustc_ast::Mutability; use rustc_hir::{Expr, ExprKind, UnOp}; -use rustc_middle::ty::{self, TypeAndMut}; +use rustc_middle::ty::layout::LayoutOf as _; +use rustc_middle::ty::{self, layout::TyAndLayout, TypeAndMut}; use rustc_span::sym; use crate::{lints::InvalidReferenceCastingDiag, LateContext, LateLintPass, LintContext}; @@ -38,13 +39,12 @@ declare_lint_pass!(InvalidReferenceCasting => [INVALID_REFERENCE_CASTING]); impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if let Some((e, pat)) = borrow_or_assign(cx, expr) { - if matches!(pat, PatternKind::Borrow { mutbl: Mutability::Mut } | PatternKind::Assign) { - let init = cx.expr_or_init(e); + let init = cx.expr_or_init(e); + let orig_cast = if init.span != e.span { Some(init.span) } else { None }; - let Some(ty_has_interior_mutability) = is_cast_from_ref_to_mut_ptr(cx, init) else { - return; - }; - let orig_cast = if init.span != e.span { Some(init.span) } else { None }; + if matches!(pat, PatternKind::Borrow { mutbl: Mutability::Mut } | PatternKind::Assign) + && let Some(ty_has_interior_mutability) = is_cast_from_ref_to_mut_ptr(cx, init) + { let ty_has_interior_mutability = ty_has_interior_mutability.then_some(()); cx.emit_span_lint( @@ -63,6 +63,23 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { }, ); } + + if let Some((from_ty_layout, to_ty_layout, e_alloc)) = + is_cast_to_bigger_memory_layout(cx, init) + { + cx.emit_span_lint( + INVALID_REFERENCE_CASTING, + expr.span, + InvalidReferenceCastingDiag::BiggerLayout { + orig_cast, + alloc: e_alloc.span, + from_ty: from_ty_layout.ty, + from_size: from_ty_layout.layout.size().bytes(), + to_ty: to_ty_layout.ty, + to_size: to_ty_layout.layout.size().bytes(), + }, + ); + } } } } @@ -151,6 +168,48 @@ fn is_cast_from_ref_to_mut_ptr<'tcx>( } } +fn is_cast_to_bigger_memory_layout<'tcx>( + cx: &LateContext<'tcx>, + orig_expr: &'tcx Expr<'tcx>, +) -> Option<(TyAndLayout<'tcx>, TyAndLayout<'tcx>, Expr<'tcx>)> { + let end_ty = cx.typeck_results().node_type(orig_expr.hir_id); + + let ty::RawPtr(TypeAndMut { ty: inner_end_ty, mutbl: _ }) = end_ty.kind() else { + return None; + }; + + let (e, _) = peel_casts(cx, orig_expr); + let start_ty = cx.typeck_results().node_type(e.hir_id); + + let ty::Ref(_, inner_start_ty, _) = start_ty.kind() else { + return None; + }; + + // try to find the underlying allocation + let e_alloc = cx.expr_or_init(e); + let e_alloc = + if let ExprKind::AddrOf(_, _, inner_expr) = e_alloc.kind { inner_expr } else { e_alloc }; + let alloc_ty = cx.typeck_results().node_type(e_alloc.hir_id); + + // if we do not find it we bail out, as this may not be UB + // see https://github.com/rust-lang/unsafe-code-guidelines/issues/256 + if alloc_ty.is_any_ptr() { + return None; + } + + let from_layout = cx.layout_of(*inner_start_ty).ok()?; + let alloc_layout = cx.layout_of(alloc_ty).ok()?; + let to_layout = cx.layout_of(*inner_end_ty).ok()?; + + if to_layout.layout.size() > from_layout.layout.size() + && to_layout.layout.size() > alloc_layout.layout.size() + { + Some((from_layout, to_layout, *e_alloc)) + } else { + None + } +} + fn peel_casts<'tcx>(cx: &LateContext<'tcx>, mut e: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, bool) { let mut gone_trough_unsafe_cell_raw_get = false; diff --git a/tests/ui/cast/cast-rfc0401.rs b/tests/ui/cast/cast-rfc0401.rs index 9a98754161544..424feeba0c467 100644 --- a/tests/ui/cast/cast-rfc0401.rs +++ b/tests/ui/cast/cast-rfc0401.rs @@ -81,14 +81,14 @@ fn main() assert_eq!(u as *const u16, p as *const u16); // ptr-ptr-cast (Length vtables) - let mut l : [u8; 2] = [0,1]; - let w: *mut [u16; 2] = &mut l as *mut [u8; 2] as *mut _; - let w: *mut [u16] = unsafe {&mut *w}; - let w_u8 : *const [u8] = w as *const [u8]; - assert_eq!(unsafe{&*w_u8}, &l); + let mut l : [u16; 2] = [0,1]; + let w: *mut [u8; 2] = &mut l as *mut [u16; 2] as *mut _; + let w: *mut [u8] = unsafe {&mut *w}; + let w_u16 : *const [u16] = w as *const [u16]; + assert_eq!(unsafe{&*w_u16}, &l); let s: *mut str = w as *mut str; - let l_via_str = unsafe{&*(s as *const [u8])}; + let l_via_str = unsafe{&*(s as *const [u16])}; assert_eq!(&l, l_via_str); // ptr-ptr-cast (Length vtables, check length is preserved) diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 84267c0af032a..63541943d65c1 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -30,7 +30,7 @@ unsafe fn ref_to_mut() { //~^ ERROR casting `&T` to `&mut T` is undefined behavior let _num = &mut *(num as *const i32).cast::().cast_mut().cast_const().cast_mut(); //~^ ERROR casting `&T` to `&mut T` is undefined behavior - let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32); + let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i8); //~^ ERROR casting `&T` to `&mut T` is undefined behavior let _num = &mut *std::mem::transmute::<_, *mut i32>(num); //~^ ERROR casting `&T` to `&mut T` is undefined behavior @@ -141,6 +141,109 @@ unsafe fn assign_to_ref() { } } +#[repr(align(16))] +struct I64(i64); + +#[repr(C)] +struct Mat3 { + a: Vec3, + b: Vec3, + c: Vec3, +} + +#[repr(C)] +struct Vec3(T, T, T); + +unsafe fn bigger_layout() { + { + let num = &mut 3i32; + + let _num = &*(num as *const i32 as *const i64); + //~^ ERROR casting references to a bigger memory layout + let _num = &mut *(num as *mut i32 as *mut i64); + //~^ ERROR casting references to a bigger memory layout + let _num = &mut *(num as *mut i32 as *mut I64); + //~^ ERROR casting references to a bigger memory layout + std::ptr::write(num as *mut i32 as *mut i64, 2); + //~^ ERROR casting references to a bigger memory layout + + let _num = &mut *(num as *mut i32); + } + + { + let num = &mut [0i32; 3]; + + let _num = &mut *(num as *mut _ as *mut [i64; 2]); + //~^ ERROR casting references to a bigger memory layout + std::ptr::write_unaligned(num as *mut _ as *mut [i32; 4], [0, 0, 1, 1]); + //~^ ERROR casting references to a bigger memory layout + + let _num = &mut *(num as *mut _ as *mut [u32; 3]); + let _num = &mut *(num as *mut _ as *mut [u32; 2]); + } + + { + let num = &mut [0i32; 3] as &mut [i32]; + + let _num = &mut *(num as *mut _ as *mut i128); + //~^ ERROR casting references to a bigger memory layout + let _num = &mut *(num as *mut _ as *mut [i64; 4]); + //~^ ERROR casting references to a bigger memory layout + + let _num = &mut *(num as *mut _ as *mut [u32]); + let _num = &mut *(num as *mut _ as *mut [i16]); + } + + { + let mat3 = Mat3 { a: Vec3(0i32, 0, 0), b: Vec3(0, 0, 0), c: Vec3(0, 0, 0) }; + + let _num = &mut *(&mat3 as *const _ as *mut [[i64; 3]; 3]); + //~^ ERROR casting `&T` to `&mut T` + //~^^ ERROR casting references to a bigger memory layout + let _num = &*(&mat3 as *const _ as *mut [[i64; 3]; 3]); + //~^ ERROR casting references to a bigger memory layout + + let _num = &*(&mat3 as *const _ as *mut [[i32; 3]; 3]); + } + + { + let mut l: [u8; 2] = [0,1]; + let w: *mut [u16; 2] = &mut l as *mut [u8; 2] as *mut _; + let w: *mut [u16] = unsafe {&mut *w}; + //~^ ERROR casting references to a bigger memory layout + } + + { + fn foo() -> [i32; 1] { todo!() } + + let num = foo(); + let _num = &*(&num as *const i32 as *const i64); + //~^ ERROR casting references to a bigger memory layout + let _num = &*(&foo() as *const i32 as *const i64); + //~^ ERROR casting references to a bigger memory layout + } + + { + fn bar(_a: &[i32; 2]) -> &[i32; 1] { todo!() } + + let num = bar(&[0, 0]); + let _num = &*(num as *const i32 as *const i64); + let _num = &*(bar(&[0, 0]) as *const i32 as *const i64); + } + + { + fn foi() -> T { todo!() } + + let num = foi::(); + let _num = &*(&num as *const i32 as *const i64); + //~^ ERROR casting references to a bigger memory layout + } + + unsafe fn from_ref(this: &i32) -> &i64 { + &*(this as *const i32 as *const i64) + } +} + const RAW_PTR: *mut u8 = 1 as *mut u8; unsafe fn no_warn() { let num = &3i32; diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr index 374a58d7b7b0d..26af60b6bc516 100644 --- a/tests/ui/lint/reference_casting.stderr +++ b/tests/ui/lint/reference_casting.stderr @@ -66,8 +66,8 @@ LL | let _num = &mut *(num as *const i32).cast::().cast_mut().cast_cons error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:33:16 | -LL | let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit @@ -373,5 +373,164 @@ LL | *(this as *const _ as *mut _) = a; | = note: for more information, visit -error: aborting due to 42 previous errors +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:161:20 + | +LL | let num = &mut 3i32; + | ---- backing allocation comes from here +LL | +LL | let _num = &*(num as *const i32 as *const i64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: casting from `i32` (4 bytes) to `i64` (8 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:163:20 + | +LL | let num = &mut 3i32; + | ---- backing allocation comes from here +... +LL | let _num = &mut *(num as *mut i32 as *mut i64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: casting from `i32` (4 bytes) to `i64` (8 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:165:20 + | +LL | let num = &mut 3i32; + | ---- backing allocation comes from here +... +LL | let _num = &mut *(num as *mut i32 as *mut I64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: casting from `i32` (4 bytes) to `I64` (16 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:167:9 + | +LL | let num = &mut 3i32; + | ---- backing allocation comes from here +... +LL | std::ptr::write(num as *mut i32 as *mut i64, 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: casting from `i32` (4 bytes) to `i64` (8 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:176:20 + | +LL | let num = &mut [0i32; 3]; + | --------- backing allocation comes from here +LL | +LL | let _num = &mut *(num as *mut _ as *mut [i64; 2]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: casting from `[i32; 3]` (12 bytes) to `[i64; 2]` (16 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:178:9 + | +LL | let num = &mut [0i32; 3]; + | --------- backing allocation comes from here +... +LL | std::ptr::write_unaligned(num as *mut _ as *mut [i32; 4], [0, 0, 1, 1]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: casting from `[i32; 3]` (12 bytes) to `[i32; 4]` (16 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:188:20 + | +LL | let num = &mut [0i32; 3] as &mut [i32]; + | --------- backing allocation comes from here +LL | +LL | let _num = &mut *(num as *mut _ as *mut i128); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: casting from `[i32; 3]` (12 bytes) to `i128` (16 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:190:20 + | +LL | let num = &mut [0i32; 3] as &mut [i32]; + | --------- backing allocation comes from here +... +LL | let _num = &mut *(num as *mut _ as *mut [i64; 4]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: casting from `[i32; 3]` (12 bytes) to `[i64; 4]` (32 bytes) + +error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` + --> $DIR/reference_casting.rs:200:20 + | +LL | let _num = &mut *(&mat3 as *const _ as *mut [[i64; 3]; 3]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:200:20 + | +LL | let _num = &mut *(&mat3 as *const _ as *mut [[i64; 3]; 3]); + | ^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | backing allocation comes from here + | + = note: casting from `Mat3` (36 bytes) to `[[i64; 3]; 3]` (72 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:203:20 + | +LL | let _num = &*(&mat3 as *const _ as *mut [[i64; 3]; 3]); + | ^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | backing allocation comes from here + | + = note: casting from `Mat3` (36 bytes) to `[[i64; 3]; 3]` (72 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:212:37 + | +LL | let w: *mut [u16; 2] = &mut l as *mut [u8; 2] as *mut _; + | -------------------------------- + | | | + | | backing allocation comes from here + | casting happend here +LL | let w: *mut [u16] = unsafe {&mut *w}; + | ^^^^^^^ + | + = note: casting from `[u8; 2]` (2 bytes) to `[u16; 2]` (4 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:220:20 + | +LL | let _num = &*(&num as *const i32 as *const i64); + | ^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | backing allocation comes from here + | + = note: casting from `[i32; 1]` (4 bytes) to `i64` (8 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:222:20 + | +LL | let _num = &*(&foo() as *const i32 as *const i64); + | ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | backing allocation comes from here + | + = note: casting from `[i32; 1]` (4 bytes) to `i64` (8 bytes) + +error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused + --> $DIR/reference_casting.rs:238:20 + | +LL | let _num = &*(&num as *const i32 as *const i64); + | ^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | backing allocation comes from here + | + = note: casting from `i32` (4 bytes) to `i64` (8 bytes) + +error: aborting due to 57 previous errors From 6a8f50e907a64117cc6dfaee7a98f28c5195e6cc Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 15 Dec 2023 11:30:16 +0100 Subject: [PATCH 15/17] Introduce small cache to avoid recomputing the same value twice --- compiler/rustc_lint/src/reference_casting.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 9d67fd4b892e7..519ab8bd50fe2 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -42,8 +42,15 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { let init = cx.expr_or_init(e); let orig_cast = if init.span != e.span { Some(init.span) } else { None }; + // small cache to avoid recomputing needlesly computing peel_casts of init + let mut peel_casts = { + let mut peel_casts_cache = None; + move || *peel_casts_cache.get_or_insert_with(|| peel_casts(cx, init)) + }; + if matches!(pat, PatternKind::Borrow { mutbl: Mutability::Mut } | PatternKind::Assign) - && let Some(ty_has_interior_mutability) = is_cast_from_ref_to_mut_ptr(cx, init) + && let Some(ty_has_interior_mutability) = + is_cast_from_ref_to_mut_ptr(cx, init, &mut peel_casts) { let ty_has_interior_mutability = ty_has_interior_mutability.then_some(()); @@ -65,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { } if let Some((from_ty_layout, to_ty_layout, e_alloc)) = - is_cast_to_bigger_memory_layout(cx, init) + is_cast_to_bigger_memory_layout(cx, init, &mut peel_casts) { cx.emit_span_lint( INVALID_REFERENCE_CASTING, @@ -141,6 +148,7 @@ fn borrow_or_assign<'tcx>( fn is_cast_from_ref_to_mut_ptr<'tcx>( cx: &LateContext<'tcx>, orig_expr: &'tcx Expr<'tcx>, + mut peel_casts: impl FnMut() -> (&'tcx Expr<'tcx>, bool), ) -> Option { let end_ty = cx.typeck_results().node_type(orig_expr.hir_id); @@ -149,7 +157,7 @@ fn is_cast_from_ref_to_mut_ptr<'tcx>( return None; } - let (e, need_check_freeze) = peel_casts(cx, orig_expr); + let (e, need_check_freeze) = peel_casts(); let start_ty = cx.typeck_results().node_type(e.hir_id); if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() { @@ -171,6 +179,7 @@ fn is_cast_from_ref_to_mut_ptr<'tcx>( fn is_cast_to_bigger_memory_layout<'tcx>( cx: &LateContext<'tcx>, orig_expr: &'tcx Expr<'tcx>, + mut peel_casts: impl FnMut() -> (&'tcx Expr<'tcx>, bool), ) -> Option<(TyAndLayout<'tcx>, TyAndLayout<'tcx>, Expr<'tcx>)> { let end_ty = cx.typeck_results().node_type(orig_expr.hir_id); @@ -178,7 +187,7 @@ fn is_cast_to_bigger_memory_layout<'tcx>( return None; }; - let (e, _) = peel_casts(cx, orig_expr); + let (e, _) = peel_casts(); let start_ty = cx.typeck_results().node_type(e.hir_id); let ty::Ref(_, inner_start_ty, _) = start_ty.kind() else { From 746bb7e13610df9a9f88222a74302b93456c1675 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 17 Dec 2023 17:28:24 +0100 Subject: [PATCH 16/17] Avoid UB in clippy transmute_ptr_to_ptr UI test --- src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed | 6 +++--- src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs | 6 +++--- src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed index 4e145693c553a..696def08f142d 100644 --- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed +++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed @@ -35,7 +35,7 @@ fn transmute_ptr_to_ptr() { // ref-ref transmutes; bad let _: &f32 = &*(&1u32 as *const u32 as *const f32); //~^ ERROR: transmute from a reference to a reference - let _: &f64 = &*(&1f32 as *const f32 as *const f64); + let _: &f32 = &*(&1f64 as *const f64 as *const f32); //~^ ERROR: transmute from a reference to a reference //:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not // the same type @@ -43,8 +43,8 @@ fn transmute_ptr_to_ptr() { //~^ ERROR: transmute from a reference to a reference let _: &GenericParam = &*(&GenericParam { t: 1u32 } as *const GenericParam as *const GenericParam); //~^ ERROR: transmute from a reference to a reference - let u8_ref: &u8 = &0u8; - let u64_ref: &u64 = unsafe { &*(u8_ref as *const u8 as *const u64) }; + let u64_ref: &u64 = &0u64; + let u8_ref: &u8 = unsafe { &*(u64_ref as *const u64 as *const u8) }; //~^ ERROR: transmute from a reference to a reference } diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs index 086aadc364740..0700d8c19576a 100644 --- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs +++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs @@ -35,7 +35,7 @@ fn transmute_ptr_to_ptr() { // ref-ref transmutes; bad let _: &f32 = std::mem::transmute(&1u32); //~^ ERROR: transmute from a reference to a reference - let _: &f64 = std::mem::transmute(&1f32); + let _: &f32 = std::mem::transmute(&1f64); //~^ ERROR: transmute from a reference to a reference //:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not // the same type @@ -43,8 +43,8 @@ fn transmute_ptr_to_ptr() { //~^ ERROR: transmute from a reference to a reference let _: &GenericParam = std::mem::transmute(&GenericParam { t: 1u32 }); //~^ ERROR: transmute from a reference to a reference - let u8_ref: &u8 = &0u8; - let u64_ref: &u64 = unsafe { std::mem::transmute(u8_ref) }; + let u64_ref: &u64 = &0u64; + let u8_ref: &u8 = unsafe { std::mem::transmute(u64_ref) }; //~^ ERROR: transmute from a reference to a reference } diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr index 9f8599921ec7d..6e3af1f733717 100644 --- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr +++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr @@ -22,8 +22,8 @@ LL | let _: &f32 = std::mem::transmute(&1u32); error: transmute from a reference to a reference --> $DIR/transmute_ptr_to_ptr.rs:38:23 | -LL | let _: &f64 = std::mem::transmute(&1f32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&1f32 as *const f32 as *const f64)` +LL | let _: &f32 = std::mem::transmute(&1f64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&1f64 as *const f64 as *const f32)` error: transmute from a reference to a reference --> $DIR/transmute_ptr_to_ptr.rs:42:27 @@ -38,10 +38,10 @@ LL | let _: &GenericParam = std::mem::transmute(&GenericParam { t: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam as *const GenericParam)` error: transmute from a reference to a reference - --> $DIR/transmute_ptr_to_ptr.rs:47:38 + --> $DIR/transmute_ptr_to_ptr.rs:47:36 | -LL | let u64_ref: &u64 = unsafe { std::mem::transmute(u8_ref) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(u8_ref as *const u8 as *const u64)` +LL | let u8_ref: &u8 = unsafe { std::mem::transmute(u64_ref) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(u64_ref as *const u64 as *const u8)` error: aborting due to 7 previous errors From e08c9d1f812b02e397c6ef618472a2e5586879b6 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 17 Dec 2023 18:40:49 +0100 Subject: [PATCH 17/17] Allow invalid ref casting in Miri unaligned_ref_addr_of test --- .../miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs index 470420acd5084..225feef72813e 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs @@ -1,6 +1,8 @@ // This should fail even without Stacked Borrows. //@compile-flags: -Zmiri-disable-stacked-borrows -Cdebug-assertions=no +#![allow(invalid_reference_casting)] // for u16 -> u32 + fn main() { // Try many times as this might work by chance. for _ in 0..20 {