about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
authorMahdi Dibaiee <mdibaiee@pm.me>2023-07-11 22:35:29 +0100
committerMahdi Dibaiee <mdibaiee@pm.me>2023-07-14 13:27:35 +0100
commite55583c4b831c601452117a8eb20af59779ef582 (patch)
tree575ada099c48a205145b0d39816fee6b05e8bad6 /compiler/rustc_middle/src
parentdf5c2cf9bc60fa935aef31a217d9fa0a328d7fe2 (diff)
downloadrust-e55583c4b831c601452117a8eb20af59779ef582.tar.gz
rust-e55583c4b831c601452117a8eb20af59779ef582.zip
refactor(rustc_middle): Substs -> GenericArg
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs6
-rw-r--r--compiler/rustc_middle/src/infer/mod.rs2
-rw-r--r--compiler/rustc_middle/src/middle/exported_symbols.rs10
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs20
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs57
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs14
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs12
-rw-r--r--compiler/rustc_middle/src/mir/query.rs8
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs8
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs12
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs28
-rw-r--r--compiler/rustc_middle/src/query/keys.rs10
-rw-r--r--compiler/rustc_middle/src/query/mod.rs22
-rw-r--r--compiler/rustc_middle/src/thir.rs16
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs10
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs8
-rw-r--r--compiler/rustc_middle/src/traits/query.rs4
-rw-r--r--compiler/rustc_middle/src/traits/specialization_graph.rs4
-rw-r--r--compiler/rustc_middle/src/traits/structural_impls.rs4
-rw-r--r--compiler/rustc_middle/src/ty/abstract_const.rs4
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs8
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs8
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs18
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs10
-rw-r--r--compiler/rustc_middle/src/ty/context.rs54
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs10
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs18
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs62
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs (renamed from compiler/rustc_middle/src/ty/subst.rs)277
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs44
-rw-r--r--compiler/rustc_middle/src/ty/impls_ty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs24
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs10
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs162
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs23
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs54
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs18
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs28
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs43
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs138
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs153
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs34
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs352
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs2
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs26
-rw-r--r--compiler/rustc_middle/src/ty/util.rs88
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs28
-rw-r--r--compiler/rustc_middle/src/util/call_kind.rs26
-rw-r--r--compiler/rustc_middle/src/util/find_self_call.rs10
51 files changed, 996 insertions, 999 deletions
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index d5e8330b3f6..81823118ab8 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -23,7 +23,7 @@
 
 use crate::infer::MemberConstraint;
 use crate::mir::ConstraintCategory;
-use crate::ty::subst::GenericArg;
+use crate::ty::GenericArg;
 use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt};
 use rustc_macros::HashStable;
 use smallvec::SmallVec;
@@ -63,7 +63,7 @@ impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> {
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable)]
 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
 pub struct CanonicalVarValues<'tcx> {
-    pub var_values: ty::SubstsRef<'tcx>,
+    pub var_values: ty::GenericArgsRef<'tcx>,
 }
 
 impl CanonicalVarValues<'_> {
@@ -429,7 +429,7 @@ impl<'tcx> CanonicalVarValues<'tcx> {
         infos: CanonicalVarInfos<'tcx>,
     ) -> CanonicalVarValues<'tcx> {
         CanonicalVarValues {
-            var_values: tcx.mk_substs_from_iter(infos.iter().enumerate().map(
+            var_values: tcx.mk_args_from_iter(infos.iter().enumerate().map(
                 |(i, info)| -> ty::GenericArg<'tcx> {
                     match info.kind {
                         CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => {
diff --git a/compiler/rustc_middle/src/infer/mod.rs b/compiler/rustc_middle/src/infer/mod.rs
index 2db59f37f40..493bb8a6823 100644
--- a/compiler/rustc_middle/src/infer/mod.rs
+++ b/compiler/rustc_middle/src/infer/mod.rs
@@ -15,7 +15,7 @@ use rustc_span::Span;
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
 pub struct MemberConstraint<'tcx> {
-    /// The `DefId` and substs of the opaque type causing this constraint.
+    /// The `DefId` and args of the opaque type causing this constraint.
     /// Used for error reporting.
     pub key: OpaqueTypeKey<'tcx>,
 
diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs
index 9041da9a060..f19812619b2 100644
--- a/compiler/rustc_middle/src/middle/exported_symbols.rs
+++ b/compiler/rustc_middle/src/middle/exported_symbols.rs
@@ -1,4 +1,4 @@
-use crate::ty::subst::SubstsRef;
+use crate::ty::GenericArgsRef;
 use crate::ty::{self, Ty, TyCtxt};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_macros::HashStable;
@@ -41,7 +41,7 @@ pub struct SymbolExportInfo {
 #[derive(Eq, PartialEq, Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
 pub enum ExportedSymbol<'tcx> {
     NonGeneric(DefId),
-    Generic(DefId, SubstsRef<'tcx>),
+    Generic(DefId, GenericArgsRef<'tcx>),
     DropGlue(Ty<'tcx>),
     ThreadLocalShim(DefId),
     NoDefId(ty::SymbolName<'tcx>),
@@ -53,15 +53,15 @@ impl<'tcx> ExportedSymbol<'tcx> {
     pub fn symbol_name_for_local_instance(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName<'tcx> {
         match *self {
             ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)),
-            ExportedSymbol::Generic(def_id, substs) => {
-                tcx.symbol_name(ty::Instance::new(def_id, substs))
+            ExportedSymbol::Generic(def_id, args) => {
+                tcx.symbol_name(ty::Instance::new(def_id, args))
             }
             ExportedSymbol::DropGlue(ty) => {
                 tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty))
             }
             ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance {
                 def: ty::InstanceDef::ThreadLocalShim(def_id),
-                substs: ty::InternalSubsts::empty(),
+                args: ty::GenericArgs::empty(),
             }),
             ExportedSymbol::NoDefId(symbol_name) => symbol_name,
         }
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 2435bc59ec0..372452ea29a 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -22,7 +22,7 @@ pub enum ErrorHandled {
     /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`.
     Reported(ReportedErrorInfo),
     /// Don't emit an error, the evaluation failed because the MIR was generic
-    /// and the substs didn't fully monomorphize it.
+    /// and the args didn't fully monomorphize it.
     TooGeneric,
 }
 
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 2d2cfee1b21..fbd667a87fe 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -138,7 +138,7 @@ use rustc_target::abi::{AddressSpace, Endian, HasDataLayout};
 
 use crate::mir;
 use crate::ty::codec::{TyDecoder, TyEncoder};
-use crate::ty::subst::GenericArgKind;
+use crate::ty::GenericArgKind;
 use crate::ty::{self, Instance, Ty, TyCtxt};
 
 pub use self::error::{
@@ -559,7 +559,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // However, formatting code relies on function identity (see #58320), so we only do
         // this for generic functions. Lifetime parameters are ignored.
         let is_generic = instance
-            .substs
+            .args
             .into_iter()
             .any(|kind| !matches!(kind.unpack(), GenericArgKind::Lifetime(_)));
         if is_generic {
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 9c97431f361..c9db0e7c11d 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -2,8 +2,8 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId}
 
 use crate::mir;
 use crate::query::{TyCtxtAt, TyCtxtEnsure};
-use crate::ty::subst::InternalSubsts;
 use crate::ty::visit::TypeVisitableExt;
+use crate::ty::GenericArgs;
 use crate::ty::{self, TyCtxt};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
@@ -20,8 +20,8 @@ impl<'tcx> TyCtxt<'tcx> {
         // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions
         // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
         // encountered.
-        let substs = InternalSubsts::identity_for_item(self, def_id);
-        let instance = ty::Instance::new(def_id, substs);
+        let args = GenericArgs::identity_for_item(self, def_id);
+        let instance = ty::Instance::new(def_id, args);
         let cid = GlobalId { instance, promoted: None };
         let param_env = self.param_env(def_id).with_reveal_all_normalized(self);
         self.const_eval_global_id(param_env, cid, None)
@@ -48,14 +48,14 @@ impl<'tcx> TyCtxt<'tcx> {
         //
         // When trying to evaluate constants containing inference variables,
         // use `Infcx::const_eval_resolve` instead.
-        if ct.substs.has_non_region_infer() {
+        if ct.args.has_non_region_infer() {
             bug!("did not expect inference variables here");
         }
 
         match ty::Instance::resolve(
             self, param_env,
             // FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
-            ct.def, ct.substs,
+            ct.def, ct.args,
         ) {
             Ok(Some(instance)) => {
                 let cid = GlobalId { instance, promoted: ct.promoted };
@@ -79,11 +79,11 @@ impl<'tcx> TyCtxt<'tcx> {
         //
         // When trying to evaluate constants containing inference variables,
         // use `Infcx::const_eval_resolve` instead.
-        if ct.substs.has_non_region_infer() {
+        if ct.args.has_non_region_infer() {
             bug!("did not expect inference variables here");
         }
 
-        match ty::Instance::resolve(self, param_env, ct.def, ct.substs) {
+        match ty::Instance::resolve(self, param_env, ct.def, ct.args) {
             Ok(Some(instance)) => {
                 let cid = GlobalId { instance, promoted: None };
                 self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| {
@@ -94,7 +94,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     // @lcnr believes that successfully evaluating even though there are
                     // used generic parameters is a bug of evaluation, so checking for it
                     // here does feel somewhat sensible.
-                    if !self.features().generic_const_exprs && ct.substs.has_non_region_param() {
+                    if !self.features().generic_const_exprs && ct.args.has_non_region_param() {
                         let def_kind = self.def_kind(instance.def_id());
                         assert!(
                             matches!(
@@ -221,8 +221,8 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
         // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions
         // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
         // encountered.
-        let substs = InternalSubsts::identity_for_item(self.tcx, def_id);
-        let instance = ty::Instance::new(def_id, substs);
+        let args = GenericArgs::identity_for_item(self.tcx, def_id);
+        let instance = ty::Instance::new(def_id, args);
         let cid = GlobalId { instance, promoted: None };
         let param_env =
             self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx).with_const();
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 28c50587800..97f53a59fd6 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -12,7 +12,7 @@ use crate::ty::print::{FmtPrinter, Printer};
 use crate::ty::visit::TypeVisitableExt;
 use crate::ty::{self, List, Ty, TyCtxt};
 use crate::ty::{AdtDef, InstanceDef, ScalarInt, UserTypeAnnotationIndex};
-use crate::ty::{GenericArg, InternalSubsts, SubstsRef};
+use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
 
 use rustc_data_structures::captures::Captures;
 use rustc_errors::{DiagnosticArgValue, DiagnosticMessage, ErrorGuaranteed, IntoDiagnosticArg};
@@ -1905,15 +1905,15 @@ impl<'tcx> Debug for Operand<'tcx> {
 
 impl<'tcx> Operand<'tcx> {
     /// Convenience helper to make a constant that refers to the fn
-    /// with given `DefId` and substs. Since this is used to synthesize
+    /// with given `DefId` and args. Since this is used to synthesize
     /// MIR, assumes `user_ty` is None.
     pub fn function_handle(
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-        substs: impl IntoIterator<Item = GenericArg<'tcx>>,
+        args: impl IntoIterator<Item = GenericArg<'tcx>>,
         span: Span,
     ) -> Self {
-        let ty = Ty::new_fn_def(tcx, def_id, substs);
+        let ty = Ty::new_fn_def(tcx, def_id, args);
         Operand::Constant(Box::new(Constant {
             span,
             user_ty: None,
@@ -1981,9 +1981,9 @@ impl<'tcx> Operand<'tcx> {
     ///
     /// While this is unlikely in general, it's the normal case of what you'll
     /// find as the `func` in a [`TerminatorKind::Call`].
-    pub fn const_fn_def(&self) -> Option<(DefId, SubstsRef<'tcx>)> {
+    pub fn const_fn_def(&self) -> Option<(DefId, GenericArgsRef<'tcx>)> {
         let const_ty = self.constant()?.literal.ty();
-        if let ty::FnDef(def_id, substs) = *const_ty.kind() { Some((def_id, substs)) } else { None }
+        if let ty::FnDef(def_id, args) = *const_ty.kind() { Some((def_id, args)) } else { None }
     }
 }
 
@@ -2137,12 +2137,12 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                         }
                     }
 
-                    AggregateKind::Adt(adt_did, variant, substs, _user_ty, _) => {
+                    AggregateKind::Adt(adt_did, variant, args, _user_ty, _) => {
                         ty::tls::with(|tcx| {
                             let variant_def = &tcx.adt_def(adt_did).variant(variant);
-                            let substs = tcx.lift(substs).expect("could not lift for printing");
+                            let args = tcx.lift(args).expect("could not lift for printing");
                             let name = FmtPrinter::new(tcx, Namespace::ValueNS)
-                                .print_def_path(variant_def.def_id, substs)?
+                                .print_def_path(variant_def.def_id, args)?
                                 .into_buffer();
 
                             match variant_def.ctor_kind() {
@@ -2159,10 +2159,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                         })
                     }
 
-                    AggregateKind::Closure(def_id, substs) => ty::tls::with(|tcx| {
+                    AggregateKind::Closure(def_id, args) => ty::tls::with(|tcx| {
                         let name = if tcx.sess.opts.unstable_opts.span_free_formats {
-                            let substs = tcx.lift(substs).unwrap();
-                            format!("[closure@{}]", tcx.def_path_str_with_substs(def_id, substs),)
+                            let args = tcx.lift(args).unwrap();
+                            format!("[closure@{}]", tcx.def_path_str_with_args(def_id, args),)
                         } else {
                             let span = tcx.def_span(def_id);
                             format!(
@@ -2493,7 +2493,7 @@ impl<'tcx> ConstantKind<'tcx> {
         };
         debug!("expr.kind: {:?}", expr.kind);
 
-        let ty = tcx.type_of(def).subst_identity();
+        let ty = tcx.type_of(def).instantiate_identity();
         debug!(?ty);
 
         // FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
@@ -2521,23 +2521,22 @@ impl<'tcx> ConstantKind<'tcx> {
         }
 
         let hir_id = tcx.hir().local_def_id_to_hir_id(def);
-        let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id)
+        let parent_args = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id)
             && let Some(parent_did) = parent_hir_id.as_owner()
         {
-            InternalSubsts::identity_for_item(tcx, parent_did)
+            GenericArgs::identity_for_item(tcx, parent_did)
         } else {
             List::empty()
         };
-        debug!(?parent_substs);
+        debug!(?parent_args);
 
         let did = def.to_def_id();
-        let child_substs = InternalSubsts::identity_for_item(tcx, did);
-        let substs =
-            tcx.mk_substs_from_iter(parent_substs.into_iter().chain(child_substs.into_iter()));
-        debug!(?substs);
+        let child_args = GenericArgs::identity_for_item(tcx, did);
+        let args = tcx.mk_args_from_iter(parent_args.into_iter().chain(child_args.into_iter()));
+        debug!(?args);
 
         let span = tcx.def_span(def);
-        let uneval = UnevaluatedConst::new(did, substs);
+        let uneval = UnevaluatedConst::new(did, args);
         debug!(?span, ?param_env);
 
         match tcx.const_eval_resolve(param_env, uneval, Some(span)) {
@@ -2552,7 +2551,7 @@ impl<'tcx> ConstantKind<'tcx> {
                 Self::Unevaluated(
                     UnevaluatedConst {
                         def: did,
-                        substs: InternalSubsts::identity_for_item(tcx, did),
+                        args: GenericArgs::identity_for_item(tcx, did),
                         promoted: None,
                     },
                     ty,
@@ -2578,7 +2577,7 @@ impl<'tcx> ConstantKind<'tcx> {
 #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
 pub struct UnevaluatedConst<'tcx> {
     pub def: DefId,
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
     pub promoted: Option<Promoted>,
 }
 
@@ -2586,14 +2585,14 @@ impl<'tcx> UnevaluatedConst<'tcx> {
     #[inline]
     pub fn shrink(self) -> ty::UnevaluatedConst<'tcx> {
         assert_eq!(self.promoted, None);
-        ty::UnevaluatedConst { def: self.def, substs: self.substs }
+        ty::UnevaluatedConst { def: self.def, args: self.args }
     }
 }
 
 impl<'tcx> UnevaluatedConst<'tcx> {
     #[inline]
-    pub fn new(def: DefId, substs: SubstsRef<'tcx>) -> UnevaluatedConst<'tcx> {
-        UnevaluatedConst { def, substs, promoted: Default::default() }
+    pub fn new(def: DefId, args: GenericArgsRef<'tcx>) -> UnevaluatedConst<'tcx> {
+        UnevaluatedConst { def, args, promoted: Default::default() }
     }
 }
 
@@ -2906,15 +2905,15 @@ fn pretty_print_const_value<'tcx>(
                         ty::Adt(def, _) if def.variants().is_empty() => {
                             fmt.write_str(&format!("{{unreachable(): {}}}", ty))?;
                         }
-                        ty::Adt(def, substs) => {
+                        ty::Adt(def, args) => {
                             let variant_idx = contents
                                 .variant
                                 .expect("destructed mir constant of adt without variant idx");
                             let variant_def = &def.variant(variant_idx);
-                            let substs = tcx.lift(substs).unwrap();
+                            let args = tcx.lift(args).unwrap();
                             let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
                             cx.print_alloc_ids = true;
-                            let cx = cx.print_value_path(variant_def.def_id, substs)?;
+                            let cx = cx.print_value_path(variant_def.def_id, args)?;
                             fmt.write_str(&cx.into_buffer())?;
 
                             match variant_def.ctor_kind() {
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index ca735d52314..ca3cd943d3d 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -1,5 +1,5 @@
 use crate::dep_graph::{DepNode, WorkProduct, WorkProductId};
-use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt};
+use crate::ty::{GenericArgs, Instance, InstanceDef, SymbolName, TyCtxt};
 use rustc_attr::InlineAttr;
 use rustc_data_structures::base_n;
 use rustc_data_structures::fingerprint::Fingerprint;
@@ -71,7 +71,7 @@ impl<'tcx> MonoItem<'tcx> {
 
     pub fn is_generic_fn(&self) -> bool {
         match *self {
-            MonoItem::Fn(ref instance) => instance.substs.non_erasable_generics().next().is_some(),
+            MonoItem::Fn(ref instance) => instance.args.non_erasable_generics().next().is_some(),
             MonoItem::Static(..) | MonoItem::GlobalAsm(..) => false,
         }
     }
@@ -168,14 +168,14 @@ impl<'tcx> MonoItem<'tcx> {
     /// which will never be accessed) in its place.
     pub fn is_instantiable(&self, tcx: TyCtxt<'tcx>) -> bool {
         debug!("is_instantiable({:?})", self);
-        let (def_id, substs) = match *self {
-            MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs),
-            MonoItem::Static(def_id) => (def_id, InternalSubsts::empty()),
+        let (def_id, args) = match *self {
+            MonoItem::Fn(ref instance) => (instance.def_id(), instance.args),
+            MonoItem::Static(def_id) => (def_id, GenericArgs::empty()),
             // global asm never has predicates
             MonoItem::GlobalAsm(..) => return true,
         };
 
-        !tcx.subst_and_check_impossible_predicates((def_id, &substs))
+        !tcx.subst_and_check_impossible_predicates((def_id, &args))
     }
 
     pub fn local_span(&self, tcx: TyCtxt<'tcx>) -> Option<Span> {
@@ -216,7 +216,7 @@ impl<'tcx> fmt::Display for MonoItem<'tcx> {
         match *self {
             MonoItem::Fn(instance) => write!(f, "fn {}", instance),
             MonoItem::Static(def_id) => {
-                write!(f, "static {}", Instance::new(def_id, InternalSubsts::empty()))
+                write!(f, "static {}", Instance::new(def_id, GenericArgs::empty()))
             }
             MonoItem::GlobalAsm(..) => write!(f, "global_asm"),
         }
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index ffa7a5400d3..8cbab31451b 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -477,7 +477,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
                 ConstantKind::Ty(ct) => match ct.kind() {
                     ty::ConstKind::Param(p) => format!("Param({})", p),
                     ty::ConstKind::Unevaluated(uv) => {
-                        format!("Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.substs,)
+                        format!("Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,)
                     }
                     ty::ConstKind::Value(val) => format!("Value({})", fmt_valtree(&val)),
                     ty::ConstKind::Error(_) => "Error".to_string(),
@@ -491,7 +491,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
                     format!(
                         "Unevaluated({}, {:?}, {:?})",
                         self.tcx.def_path_str(uv.def),
-                        uv.substs,
+                        uv.args,
                         uv.promoted,
                     )
                 }
@@ -512,16 +512,16 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
         self.super_rvalue(rvalue, location);
         if let Rvalue::Aggregate(kind, _) = rvalue {
             match **kind {
-                AggregateKind::Closure(def_id, substs) => {
+                AggregateKind::Closure(def_id, args) => {
                     self.push("closure");
                     self.push(&format!("+ def_id: {:?}", def_id));
-                    self.push(&format!("+ substs: {:#?}", substs));
+                    self.push(&format!("+ args: {:#?}", args));
                 }
 
-                AggregateKind::Generator(def_id, substs, movability) => {
+                AggregateKind::Generator(def_id, args, movability) => {
                     self.push("generator");
                     self.push(&format!("+ def_id: {:?}", def_id));
-                    self.push(&format!("+ substs: {:#?}", substs));
+                    self.push(&format!("+ args: {:#?}", args));
                     self.push(&format!("+ movability: {:?}", movability));
                 }
 
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 613b132ff2d..e8cb9860ee5 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -194,7 +194,7 @@ impl Debug for GeneratorLayout<'_> {
         }
         impl Debug for GenVariantPrinter {
             fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-                let variant_name = ty::GeneratorSubsts::variant_name(self.0);
+                let variant_name = ty::GeneratorArgs::variant_name(self.0);
                 if fmt.alternate() {
                     write!(fmt, "{:9}({:?})", variant_name, self.0)
                 } else {
@@ -265,10 +265,10 @@ pub struct ConstQualifs {
 /// `UniversalRegions::closure_mapping`.) Note the free regions in the
 /// closure's signature and captures are erased.
 ///
-/// Example: If type check produces a closure with the closure substs:
+/// Example: If type check produces a closure with the closure args:
 ///
 /// ```text
-/// ClosureSubsts = [
+/// ClosureArgs = [
 ///     'a,                                         // From the parent.
 ///     'b,
 ///     i8,                                         // the "closure kind"
@@ -280,7 +280,7 @@ pub struct ConstQualifs {
 /// We would "renumber" each free region to a unique vid, as follows:
 ///
 /// ```text
-/// ClosureSubsts = [
+/// ClosureArgs = [
 ///     '1,                                         // From the parent.
 ///     '2,
 ///     i8,                                         // the "closure kind"
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 8c8efc36a2f..be27bf75dbd 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -8,7 +8,7 @@ use super::{BasicBlock, Constant, Local, SwitchTargets, UserTypeProjection};
 use crate::mir::coverage::{CodeRegion, CoverageKind};
 use crate::traits::Reveal;
 use crate::ty::adjustment::PointerCoercion;
-use crate::ty::subst::SubstsRef;
+use crate::ty::GenericArgsRef;
 use crate::ty::{self, List, Ty};
 use crate::ty::{Region, UserTypeAnnotationIndex};
 
@@ -1268,10 +1268,10 @@ pub enum AggregateKind<'tcx> {
     /// active field number and is present only for union expressions
     /// -- e.g., for a union expression `SomeUnion { c: .. }`, the
     /// active field index would identity the field `c`
-    Adt(DefId, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
+    Adt(DefId, VariantIdx, GenericArgsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
 
-    Closure(DefId, SubstsRef<'tcx>),
-    Generator(DefId, SubstsRef<'tcx>, hir::Movability),
+    Closure(DefId, GenericArgsRef<'tcx>),
+    Generator(DefId, GenericArgsRef<'tcx>, hir::Movability),
 }
 
 #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 8618a531527..f79697936d2 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -35,7 +35,7 @@ impl<'tcx> PlaceTy<'tcx> {
     #[instrument(level = "debug", skip(tcx), ret)]
     pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: FieldIdx) -> Ty<'tcx> {
         match self.ty.kind() {
-            ty::Adt(adt_def, substs) => {
+            ty::Adt(adt_def, args) => {
                 let variant_def = match self.variant_index {
                     None => adt_def.non_enum_variant(),
                     Some(variant_index) => {
@@ -44,7 +44,7 @@ impl<'tcx> PlaceTy<'tcx> {
                     }
                 };
                 let field_def = &variant_def.fields[f];
-                field_def.ty(tcx, substs)
+                field_def.ty(tcx, args)
             }
             ty::Tuple(tys) => tys[f.index()],
             _ => bug!("extracting field of non-tuple non-adt: {:?}", self),
@@ -198,10 +198,10 @@ impl<'tcx> Rvalue<'tcx> {
                 AggregateKind::Tuple => {
                     Ty::new_tup_from_iter(tcx, ops.iter().map(|op| op.ty(local_decls, tcx)))
                 }
-                AggregateKind::Adt(did, _, substs, _, _) => tcx.type_of(did).subst(tcx, substs),
-                AggregateKind::Closure(did, substs) => Ty::new_closure(tcx, did, substs),
-                AggregateKind::Generator(did, substs, movability) => {
-                    Ty::new_generator(tcx, did, substs, movability)
+                AggregateKind::Adt(did, _, args, _, _) => tcx.type_of(did).instantiate(tcx, args),
+                AggregateKind::Closure(did, args) => Ty::new_closure(tcx, did, args),
+                AggregateKind::Generator(did, args, movability) => {
+                    Ty::new_generator(tcx, did, args, movability)
                 }
             },
             Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 205dc9ec746..64bc4fa7926 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -63,7 +63,7 @@
 //! `is_cleanup` above.
 
 use crate::mir::*;
-use crate::ty::subst::SubstsRef;
+use crate::ty::GenericArgsRef;
 use crate::ty::{self, CanonicalUserTypeAnnotation, Ty};
 use rustc_span::Span;
 
@@ -245,12 +245,12 @@ macro_rules! make_mir_visitor {
                 self.super_region(region);
             }
 
-            fn visit_substs(
+            fn visit_args(
                 &mut self,
-                substs: & $($mutability)? SubstsRef<'tcx>,
+                args: & $($mutability)? GenericArgsRef<'tcx>,
                 _: Location,
             ) {
-                self.super_substs(substs);
+                self.super_args(args);
             }
 
             fn visit_local_decl(
@@ -335,7 +335,7 @@ macro_rules! make_mir_visitor {
 
                     self.visit_span($(& $mutability)? *callsite_span);
 
-                    let ty::Instance { def: callee_def, substs: callee_substs } = callee;
+                    let ty::Instance { def: callee_def, args: callee_args } = callee;
                     match callee_def {
                         ty::InstanceDef::Item(_def_id) => {}
 
@@ -355,7 +355,7 @@ macro_rules! make_mir_visitor {
                             self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
                         }
                     }
-                    self.visit_substs(callee_substs, location);
+                    self.visit_args(callee_args, location);
                 }
                 if let Some(inlined_parent_scope) = inlined_parent_scope {
                     self.visit_source_scope($(& $mutability)? *inlined_parent_scope);
@@ -721,24 +721,24 @@ macro_rules! make_mir_visitor {
                             AggregateKind::Adt(
                                 _adt_def,
                                 _variant_index,
-                                substs,
-                                _user_substs,
+                                args,
+                                _user_args,
                                 _active_field_index
                             ) => {
-                                self.visit_substs(substs, location);
+                                self.visit_args(args, location);
                             }
                             AggregateKind::Closure(
                                 _,
-                                closure_substs
+                                closure_args
                             ) => {
-                                self.visit_substs(closure_substs, location);
+                                self.visit_args(closure_args, location);
                             }
                             AggregateKind::Generator(
                                 _,
-                                generator_substs,
+                                generator_args,
                                 _movability,
                             ) => {
-                                self.visit_substs(generator_substs, location);
+                                self.visit_args(generator_args, location);
                             }
                         }
 
@@ -933,7 +933,7 @@ macro_rules! make_mir_visitor {
             fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {
             }
 
-            fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {
+            fn super_args(&mut self, _args: & $($mutability)? GenericArgsRef<'tcx>) {
             }
 
             // Convenience methods
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index 28e699cd269..a8aec3096d5 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -6,8 +6,8 @@ use crate::mir::interpret::ConstValue;
 use crate::traits;
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::layout::{TyAndLayout, ValidityRequirement};
-use crate::ty::subst::{GenericArg, SubstsRef};
 use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::{GenericArg, GenericArgsRef};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::hir_id::{HirId, OwnerId};
 use rustc_query_system::query::{DefaultCacheSelector, SingleCacheSelector, VecCacheSelector};
@@ -286,7 +286,7 @@ impl Key for (DefId, SimplifiedType) {
     }
 }
 
-impl<'tcx> Key for SubstsRef<'tcx> {
+impl<'tcx> Key for GenericArgsRef<'tcx> {
     type CacheSelector = DefaultCacheSelector<Self>;
 
     fn default_span(&self, _: TyCtxt<'_>) -> Span {
@@ -294,7 +294,7 @@ impl<'tcx> Key for SubstsRef<'tcx> {
     }
 }
 
-impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
+impl<'tcx> Key for (DefId, GenericArgsRef<'tcx>) {
     type CacheSelector = DefaultCacheSelector<Self>;
 
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
@@ -310,7 +310,7 @@ impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) {
     }
 }
 
-impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) {
+impl<'tcx> Key for (LocalDefId, DefId, GenericArgsRef<'tcx>) {
     type CacheSelector = DefaultCacheSelector<Self>;
 
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
@@ -487,7 +487,7 @@ impl Key for (Symbol, u32, u32) {
     }
 }
 
-impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) {
+impl<'tcx> Key for (DefId, Ty<'tcx>, GenericArgsRef<'tcx>, ty::ParamEnv<'tcx>) {
     type CacheSelector = DefaultCacheSelector<Self>;
 
     fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index a059590e6ad..45fa82ba68a 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -44,7 +44,6 @@ use crate::traits::{
 };
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::layout::ValidityRequirement;
-use crate::ty::subst::{GenericArg, SubstsRef};
 use crate::ty::util::AlwaysRequiresDrop;
 use crate::ty::GeneratorDiagnosticData;
 use crate::ty::TyCtxtFeed;
@@ -52,6 +51,7 @@ use crate::ty::{
     self, print::describe_as_module, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt,
     UnusedGenericParams,
 };
+use crate::ty::{GenericArg, GenericArgsRef};
 use rustc_arena::TypedArena;
 use rustc_ast as ast;
 use rustc_ast::expand::{allocator::AllocatorKind, StrippedCfgItem};
@@ -1032,7 +1032,7 @@ rustc_queries! {
     }
 
     /// Obtain all the calls into other local functions
-    query mir_inliner_callees(key: ty::InstanceDef<'tcx>) -> &'tcx [(DefId, SubstsRef<'tcx>)] {
+    query mir_inliner_callees(key: ty::InstanceDef<'tcx>) -> &'tcx [(DefId, GenericArgsRef<'tcx>)] {
         fatal_cycle
         desc { |tcx|
             "computing all local function calls in `{}`",
@@ -1537,7 +1537,7 @@ rustc_queries! {
     /// added or removed in any upstream crate. Instead use the narrower
     /// `upstream_monomorphizations_for`, `upstream_drop_glue_for`, or, even
     /// better, `Instance::upstream_monomorphization()`.
-    query upstream_monomorphizations(_: ()) -> &'tcx DefIdMap<FxHashMap<SubstsRef<'tcx>, CrateNum>> {
+    query upstream_monomorphizations(_: ()) -> &'tcx DefIdMap<FxHashMap<GenericArgsRef<'tcx>, CrateNum>> {
         arena_cache
         desc { "collecting available upstream monomorphizations" }
     }
@@ -1550,7 +1550,7 @@ rustc_queries! {
     /// You likely want to call `Instance::upstream_monomorphization()`
     /// instead of invoking this query directly.
     query upstream_monomorphizations_for(def_id: DefId)
-        -> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>>
+        -> Option<&'tcx FxHashMap<GenericArgsRef<'tcx>, CrateNum>>
     {
         desc { |tcx|
             "collecting available upstream monomorphizations for `{}`",
@@ -1560,7 +1560,7 @@ rustc_queries! {
     }
 
     /// Returns the upstream crate that exports drop-glue for the given
-    /// type (`substs` is expected to be a single-item list containing the
+    /// type (`args` is expected to be a single-item list containing the
     /// type one wants drop-glue for).
     ///
     /// This is a subset of `upstream_monomorphizations_for` in order to
@@ -1574,8 +1574,8 @@ rustc_queries! {
     /// NOTE: This query could easily be extended to also support other
     ///       common functions that have are large set of monomorphizations
     ///       (like `Clone::clone` for example).
-    query upstream_drop_glue_for(substs: SubstsRef<'tcx>) -> Option<CrateNum> {
-        desc { "available upstream drop-glue for `{:?}`", substs }
+    query upstream_drop_glue_for(args: GenericArgsRef<'tcx>) -> Option<CrateNum> {
+        desc { "available upstream drop-glue for `{:?}`", args }
     }
 
     /// Returns a list of all `extern` blocks of a crate.
@@ -2053,7 +2053,7 @@ rustc_queries! {
         desc { "normalizing `{:?}`", goal.value.value.value }
     }
 
-    query subst_and_check_impossible_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
+    query subst_and_check_impossible_predicates(key: (DefId, GenericArgsRef<'tcx>)) -> bool {
         desc { |tcx|
             "checking impossible substituted predicates: `{}`",
             tcx.def_path_str(key.0)
@@ -2104,16 +2104,16 @@ rustc_queries! {
     }
 
     /// Attempt to resolve the given `DefId` to an `Instance`, for the
-    /// given generics args (`SubstsRef`), returning one of:
+    /// given generics args (`GenericArgsRef`), returning one of:
     ///  * `Ok(Some(instance))` on success
-    ///  * `Ok(None)` when the `SubstsRef` are still too generic,
+    ///  * `Ok(None)` when the `GenericArgsRef` are still too generic,
     ///    and therefore don't allow finding the final `Instance`
     ///  * `Err(ErrorGuaranteed)` when the `Instance` resolution process
     ///    couldn't complete due to errors elsewhere - this is distinct
     ///    from `Ok(None)` to avoid misleading diagnostics when an error
     ///    has already been/will be emitted, for the original cause
     query resolve_instance(
-        key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>
+        key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)>
     ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
         desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
     }
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index e9af5070e5e..e070b054720 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -19,8 +19,8 @@ use rustc_middle::middle::region;
 use rustc_middle::mir::interpret::AllocId;
 use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp};
 use rustc_middle::ty::adjustment::PointerCoercion;
-use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarSubsts};
+use rustc_middle::ty::GenericArgsRef;
+use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarArgs};
 use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{sym, Span, Symbol, DUMMY_SP};
@@ -150,9 +150,9 @@ pub struct AdtExpr<'tcx> {
     pub adt_def: AdtDef<'tcx>,
     /// The variant of the ADT.
     pub variant_index: VariantIdx,
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
 
-    /// Optional user-given substs: for something like `let x =
+    /// Optional user-given args: for something like `let x =
     /// Bar::<T> { ... }`.
     pub user_ty: UserTy<'tcx>,
 
@@ -164,7 +164,7 @@ pub struct AdtExpr<'tcx> {
 #[derive(Clone, Debug, HashStable)]
 pub struct ClosureExpr<'tcx> {
     pub closure_id: LocalDefId,
-    pub substs: UpvarSubsts<'tcx>,
+    pub args: UpvarArgs<'tcx>,
     pub upvars: Box<[ExprId]>,
     pub movability: Option<hir::Movability>,
     pub fake_reads: Vec<(ExprId, FakeReadCause, hir::HirId)>,
@@ -418,7 +418,7 @@ pub enum ExprKind<'tcx> {
     /// An inline `const` block, e.g. `const {}`.
     ConstBlock {
         did: DefId,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     },
     /// An array literal constructed from one repeated element, e.g. `[1; 5]`.
     Repeat {
@@ -466,7 +466,7 @@ pub enum ExprKind<'tcx> {
     /// Associated constants and named constants
     NamedConst {
         def_id: DefId,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
         user_ty: UserTy<'tcx>,
     },
     ConstParam {
@@ -714,7 +714,7 @@ pub enum PatKind<'tcx> {
     /// multiple variants.
     Variant {
         adt_def: AdtDef<'tcx>,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
         variant_index: VariantIdx,
         subpatterns: Vec<FieldPat<'tcx>>,
     },
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 14bc1ac0ce7..55ec17423ec 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -101,7 +101,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
             }
         }
         Become { value } => visitor.visit_expr(&visitor.thir()[value]),
-        ConstBlock { did: _, substs: _ } => {}
+        ConstBlock { did: _, args: _ } => {}
         Repeat { value, count: _ } => {
             visitor.visit_expr(&visitor.thir()[value]);
         }
@@ -115,7 +115,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
             ref base,
             adt_def: _,
             variant_index: _,
-            substs: _,
+            args: _,
             user_ty: _,
         }) => {
             for field in &**fields {
@@ -130,7 +130,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
         }
         Closure(box ClosureExpr {
             closure_id: _,
-            substs: _,
+            args: _,
             upvars: _,
             movability: _,
             fake_reads: _,
@@ -138,7 +138,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
         Literal { lit: _, neg: _ } => {}
         NonHirLiteral { lit: _, user_ty: _ } => {}
         ZstLiteral { user_ty: _ } => {}
-        NamedConst { def_id: _, substs: _, user_ty: _ } => {}
+        NamedConst { def_id: _, args: _, user_ty: _ } => {}
         ConstParam { param: _, def_id: _ } => {}
         StaticRef { alloc_id: _, ty: _, def_id: _ } => {}
         InlineAsm(box InlineAsmExpr { ref operands, template: _, options: _, line_spans: _ }) => {
@@ -227,7 +227,7 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
             name: _,
         } => visitor.visit_pat(&subpattern),
         Binding { .. } | Wild => {}
-        Variant { subpatterns, adt_def: _, substs: _, variant_index: _ } | Leaf { subpatterns } => {
+        Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => {
             for subpattern in subpatterns {
                 visitor.visit_pat(&subpattern.pattern);
             }
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index c7d2e4c22d2..b7ffed57a0b 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -12,7 +12,7 @@ pub mod util;
 use crate::infer::canonical::Canonical;
 use crate::mir::ConstraintCategory;
 use crate::ty::abstract_const::NotConstEvaluatable;
-use crate::ty::subst::SubstsRef;
+use crate::ty::GenericArgsRef;
 use crate::ty::{self, AdtKind, Ty, TyCtxt};
 
 use rustc_data_structures::sync::Lrc;
@@ -199,7 +199,7 @@ impl<'tcx> ObligationCause<'tcx> {
 pub struct UnifyReceiverContext<'tcx> {
     pub assoc_item: ty::AssocItem,
     pub param_env: ty::ParamEnv<'tcx>,
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
 }
 
 #[derive(Clone, PartialEq, Eq, Lift, Default, HashStable)]
@@ -696,7 +696,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
         match self {
             ImplSource::UserDefined(i) => ImplSource::UserDefined(ImplSourceUserDefinedData {
                 impl_def_id: i.impl_def_id,
-                substs: i.substs,
+                args: i.args,
                 nested: i.nested.into_iter().map(f).collect(),
             }),
             ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
@@ -729,7 +729,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
 #[derive(TypeFoldable, TypeVisitable)]
 pub struct ImplSourceUserDefinedData<'tcx, N> {
     pub impl_def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
     pub nested: Vec<N>,
 }
 
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index 60a38747fdf..950a59e9695 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -8,7 +8,7 @@
 use crate::error::DropCheckOverflow;
 use crate::infer::canonical::{Canonical, QueryResponse};
 use crate::ty::error::TypeError;
-use crate::ty::subst::GenericArg;
+use crate::ty::GenericArg;
 use crate::ty::{self, Ty, TyCtxt};
 use rustc_span::source_map::Span;
 
@@ -132,7 +132,7 @@ impl<'tcx> DropckOutlivesResult<'tcx> {
 pub struct DropckConstraint<'tcx> {
     /// Types that are required to be alive in order for this
     /// type to be valid for destruction.
-    pub outlives: Vec<ty::subst::GenericArg<'tcx>>,
+    pub outlives: Vec<ty::GenericArg<'tcx>>,
 
     /// Types that could not be resolved: projections and params.
     pub dtorck_types: Vec<Ty<'tcx>>,
diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs
index dc2cd203560..18a57b6181a 100644
--- a/compiler/rustc_middle/src/traits/specialization_graph.rs
+++ b/compiler/rustc_middle/src/traits/specialization_graph.rs
@@ -259,7 +259,9 @@ pub fn ancestors(
 
     if let Some(reported) = specialization_graph.has_errored {
         Err(reported)
-    } else if let Err(reported) = tcx.type_of(start_from_impl).subst_identity().error_reported() {
+    } else if let Err(reported) =
+        tcx.type_of(start_from_impl).instantiate_identity().error_reported()
+    {
         Err(reported)
     } else {
         Ok(Ancestors {
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index a703e3c9562..e2cd118500b 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -26,8 +26,8 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceUserDefinedData<'tcx,
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(
             f,
-            "ImplSourceUserDefinedData(impl_def_id={:?}, substs={:?}, nested={:?})",
-            self.impl_def_id, self.substs, self.nested
+            "ImplSourceUserDefinedData(impl_def_id={:?}, args={:?}, nested={:?})",
+            self.impl_def_id, self.args, self.nested
         )
     }
 }
diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs
index ffee7ba28c3..0364a620810 100644
--- a/compiler/rustc_middle/src/ty/abstract_const.rs
+++ b/compiler/rustc_middle/src/ty/abstract_const.rs
@@ -55,8 +55,8 @@ impl<'tcx> TyCtxt<'tcx> {
                     ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) {
                         Err(e) => ty::Const::new_error(self.tcx, e, c.ty()),
                         Ok(Some(bac)) => {
-                            let substs = self.tcx.erase_regions(uv.substs);
-                            let bac = bac.subst(self.tcx, substs);
+                            let args = self.tcx.erase_regions(uv.args);
+                            let bac = bac.instantiate(self.tcx, args);
                             return bac.fold_with(self);
                         }
                         Ok(None) => c,
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index cce609c261e..4e746a49d84 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -84,11 +84,15 @@ impl AssocItem {
                 // late-bound regions, and we don't want method signatures to show up
                 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
                 // regions just fine, showing `fn(&MyType)`.
-                tcx.fn_sig(self.def_id).subst_identity().skip_binder().to_string()
+                tcx.fn_sig(self.def_id).instantiate_identity().skip_binder().to_string()
             }
             ty::AssocKind::Type => format!("type {};", self.name),
             ty::AssocKind::Const => {
-                format!("const {}: {:?};", self.name, tcx.type_of(self.def_id).subst_identity())
+                format!(
+                    "const {}: {:?};",
+                    self.name,
+                    tcx.type_of(self.def_id).instantiate_identity()
+                )
             }
         }
     }
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 6adbb44a153..b4f4f9bef8e 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -13,7 +13,7 @@ use crate::mir::{
     interpret::{AllocId, ConstAllocation},
 };
 use crate::traits;
-use crate::ty::subst::SubstsRef;
+use crate::ty::GenericArgsRef;
 use crate::ty::{self, AdtDef, Ty};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::ty::TyCtxt;
@@ -254,12 +254,12 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Clause<'tcx> {
     }
 }
 
-impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for SubstsRef<'tcx> {
+impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for GenericArgsRef<'tcx> {
     fn decode(decoder: &mut D) -> Self {
         let len = decoder.read_usize();
         let tcx = decoder.interner();
-        tcx.mk_substs_from_iter(
-            (0..len).map::<ty::subst::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)),
+        tcx.mk_args_from_iter(
+            (0..len).map::<ty::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)),
         )
     }
 }
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 1cbfe99f87f..bf9f5846ed9 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -1,6 +1,6 @@
 use crate::middle::resolve_bound_vars as rbv;
 use crate::mir::interpret::{AllocId, ConstValue, LitToConstInput, Scalar};
-use crate::ty::{self, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
+use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
 use rustc_data_structures::intern::Interned;
 use rustc_error_messages::MultiSpan;
 use rustc_hir as hir;
@@ -171,7 +171,7 @@ impl<'tcx> Const<'tcx> {
                 tcx,
                 ty::UnevaluatedConst {
                     def: def.to_def_id(),
-                    substs: InternalSubsts::identity_for_item(tcx, def.to_def_id()),
+                    args: GenericArgs::identity_for_item(tcx, def.to_def_id()),
                 },
                 ty,
             ),
@@ -225,7 +225,7 @@ impl<'tcx> Const<'tcx> {
             )) => {
                 // Use the type from the param's definition, since we can resolve it,
                 // not the expected parameter type from WithOptConstParam.
-                let param_ty = tcx.type_of(def_id).subst_identity();
+                let param_ty = tcx.type_of(def_id).instantiate_identity();
                 match tcx.named_bound_var(expr.hir_id) {
                     Some(rbv::ResolvedArg::EarlyBound(_)) => {
                         // Find the name and index of the const parameter by indexing the generics of
@@ -406,14 +406,14 @@ impl<'tcx> Const<'tcx> {
             // any region variables.
 
             // HACK(eddyb) when the query key would contain inference variables,
-            // attempt using identity substs and `ParamEnv` instead, that will succeed
+            // attempt using identity args and `ParamEnv` instead, that will succeed
             // when the expression doesn't depend on any parameters.
             // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
             // we can call `infcx.const_eval_resolve` which handles inference variables.
             let param_env_and = if (param_env, unevaluated).has_non_region_infer() {
                 tcx.param_env(unevaluated.def).and(ty::UnevaluatedConst {
                     def: unevaluated.def,
-                    substs: InternalSubsts::identity_for_item(tcx, unevaluated.def),
+                    args: GenericArgs::identity_for_item(tcx, unevaluated.def),
                 })
             } else {
                 tcx.erase_regions(param_env)
@@ -430,8 +430,8 @@ impl<'tcx> Const<'tcx> {
                 EvalMode::Typeck => {
                     match tcx.const_eval_resolve_for_typeck(param_env, unevaluated, None) {
                         // NOTE(eddyb) `val` contains no lifetimes/types/consts,
-                        // and we use the original type, so nothing from `substs`
-                        // (which may be identity substs, see above),
+                        // and we use the original type, so nothing from `args`
+                        // (which may be identity args, see above),
                         // can leak through `val` into the const we return.
                         Ok(val) => Some(Ok(EvalResult::ValTree(val?))),
                         Err(ErrorHandled::TooGeneric) => None,
@@ -441,8 +441,8 @@ impl<'tcx> Const<'tcx> {
                 EvalMode::Mir => {
                     match tcx.const_eval_resolve(param_env, unevaluated.expand(), None) {
                         // NOTE(eddyb) `val` contains no lifetimes/types/consts,
-                        // and we use the original type, so nothing from `substs`
-                        // (which may be identity substs, see above),
+                        // and we use the original type, so nothing from `args`
+                        // (which may be identity args, see above),
                         // can leak through `val` into the const we return.
                         Ok(val) => Some(Ok(EvalResult::ConstVal(val))),
                         Err(ErrorHandled::TooGeneric) => None,
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 5f2b6d42bf8..6c76075c214 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -1,7 +1,7 @@
 use super::Const;
 use crate::mir;
 use crate::ty::abstract_const::CastKind;
-use crate::ty::subst::SubstsRef;
+use crate::ty::GenericArgsRef;
 use crate::ty::{self, List, Ty};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir::def_id::DefId;
@@ -12,7 +12,7 @@ use rustc_macros::HashStable;
 #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
 pub struct UnevaluatedConst<'tcx> {
     pub def: DefId,
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
 }
 
 impl rustc_errors::IntoDiagnosticArg for UnevaluatedConst<'_> {
@@ -24,14 +24,14 @@ impl rustc_errors::IntoDiagnosticArg for UnevaluatedConst<'_> {
 impl<'tcx> UnevaluatedConst<'tcx> {
     #[inline]
     pub fn expand(self) -> mir::UnevaluatedConst<'tcx> {
-        mir::UnevaluatedConst { def: self.def, substs: self.substs, promoted: None }
+        mir::UnevaluatedConst { def: self.def, args: self.args, promoted: None }
     }
 }
 
 impl<'tcx> UnevaluatedConst<'tcx> {
     #[inline]
-    pub fn new(def: DefId, substs: SubstsRef<'tcx>) -> UnevaluatedConst<'tcx> {
-        UnevaluatedConst { def, substs }
+    pub fn new(def: DefId, args: GenericArgsRef<'tcx>) -> UnevaluatedConst<'tcx> {
+        UnevaluatedConst { def, args }
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 6990fbbb634..8bb13edbe95 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -30,7 +30,7 @@ use crate::ty::{
     Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind,
     TyVid, TypeAndMut, Visibility,
 };
-use crate::ty::{GenericArg, InternalSubsts, SubstsRef};
+use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
 use rustc_ast::{self as ast, attr};
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -84,7 +84,7 @@ use std::ops::{Bound, Deref};
 #[allow(rustc::usage_of_ty_tykind)]
 impl<'tcx> Interner for TyCtxt<'tcx> {
     type AdtDef = ty::AdtDef<'tcx>;
-    type SubstsRef = ty::SubstsRef<'tcx>;
+    type GenericArgsRef = ty::GenericArgsRef<'tcx>;
     type DefId = DefId;
     type Binder<T> = Binder<'tcx, T>;
     type Ty = Ty<'tcx>;
@@ -142,7 +142,7 @@ pub struct CtxtInterners<'tcx> {
     // they're accessed quite often.
     type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
     const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
-    substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
+    args: InternedSet<'tcx, GenericArgs<'tcx>>,
     type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
     canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
     region: InternedSet<'tcx, RegionKind<'tcx>>,
@@ -167,7 +167,7 @@ impl<'tcx> CtxtInterners<'tcx> {
             arena,
             type_: Default::default(),
             const_lists: Default::default(),
-            substs: Default::default(),
+            args: Default::default(),
             type_lists: Default::default(),
             region: Default::default(),
             poly_existential_predicates: Default::default(),
@@ -682,7 +682,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Creates a type context and call the closure with a `TyCtxt` reference
     /// to the context. The closure enforces that the type context and any interned
-    /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
+    /// value (types, args, etc.) can only be used while `ty::tls` has a valid
     /// reference to the context, to allow formatting values that need it.
     pub fn create_global_ctxt(
         s: &'tcx Session,
@@ -1083,7 +1083,7 @@ impl<'tcx> TyCtxt<'tcx> {
             _ => return None,
         }
 
-        let ret_ty = self.type_of(scope_def_id).subst_identity();
+        let ret_ty = self.type_of(scope_def_id).instantiate_identity();
         match ret_ty.kind() {
             ty::FnDef(_, _) => {
                 let sig = ret_ty.fn_sig(self);
@@ -1125,7 +1125,7 @@ impl<'tcx> TyCtxt<'tcx> {
             self,
             self.lifetimes.re_static,
             self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
-                .subst(self, self.mk_substs(&[self.lifetimes.re_static.into()])),
+                .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
         )
     }
 
@@ -1168,7 +1168,7 @@ impl<'tcx> TyCtxt<'tcx> {
 /// A trait implemented for all `X<'a>` types that can be safely and
 /// efficiently converted to `X<'tcx>` as long as they are part of the
 /// provided `TyCtxt<'tcx>`.
-/// This can be done, for example, for `Ty<'tcx>` or `SubstsRef<'tcx>`
+/// This can be done, for example, for `Ty<'tcx>` or `GenericArgsRef<'tcx>`
 /// by looking them up in their respective interners.
 ///
 /// However, this is still not the best implementation as it does
@@ -1234,8 +1234,8 @@ nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'t
 nop_list_lift! {projs; ProjectionKind => ProjectionKind}
 nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind}
 
-// This is the impl for `&'a InternalSubsts<'a>`.
-nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
+// This is the impl for `&'a GenericArgs<'a>`.
+nop_list_lift! {args; GenericArg<'a> => GenericArg<'tcx>}
 
 CloneLiftImpls! {
     Constness,
@@ -1347,7 +1347,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     Foreign
                 )?;
 
-                writeln!(fmt, "InternalSubsts interner: #{}", self.0.interners.substs.len())?;
+                writeln!(fmt, "GenericArgs interner: #{}", self.0.interners.args.len())?;
                 writeln!(fmt, "Region interner: #{}", self.0.interners.region.len())?;
                 writeln!(
                     fmt,
@@ -1503,7 +1503,7 @@ macro_rules! slice_interners {
 // should be used when possible, because it's faster.
 slice_interners!(
     const_lists: pub mk_const_list(Const<'tcx>),
-    substs: pub mk_substs(GenericArg<'tcx>),
+    args: pub mk_args(GenericArg<'tcx>),
     type_lists: pub mk_type_list(Ty<'tcx>),
     canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
     poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
@@ -1617,12 +1617,12 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     #[inline(always)]
-    pub(crate) fn check_and_mk_substs(
+    pub(crate) fn check_and_mk_args(
         self,
         _def_id: DefId,
-        substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
-    ) -> SubstsRef<'tcx> {
-        let substs = substs.into_iter().map(Into::into);
+        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
+    ) -> GenericArgsRef<'tcx> {
+        let args = args.into_iter().map(Into::into);
         #[cfg(debug_assertions)]
         {
             let generics = self.generics_of(_def_id);
@@ -1638,12 +1638,12 @@ impl<'tcx> TyCtxt<'tcx> {
             };
             assert_eq!(
                 (n, Some(n)),
-                substs.size_hint(),
+                args.size_hint(),
                 "wrong number of generic parameters for {_def_id:?}: {:?}",
-                substs.collect::<Vec<_>>(),
+                args.collect::<Vec<_>>(),
             );
         }
-        self.mk_substs_from_iter(substs)
+        self.mk_args_from_iter(args)
     }
 
     #[inline]
@@ -1801,12 +1801,12 @@ impl<'tcx> TyCtxt<'tcx> {
         T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
     }
 
-    pub fn mk_substs_from_iter<I, T>(self, iter: I) -> T::Output
+    pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<GenericArg<'tcx>, &'tcx List<GenericArg<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.mk_substs(xs))
+        T::collect_and_apply(iter, |xs| self.mk_args(xs))
     }
 
     pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
@@ -1833,21 +1833,21 @@ impl<'tcx> TyCtxt<'tcx> {
         T::collect_and_apply(iter, |xs| self.mk_fields(xs))
     }
 
-    pub fn mk_substs_trait(
+    pub fn mk_args_trait(
         self,
         self_ty: Ty<'tcx>,
         rest: impl IntoIterator<Item = GenericArg<'tcx>>,
-    ) -> SubstsRef<'tcx> {
-        self.mk_substs_from_iter(iter::once(self_ty.into()).chain(rest))
+    ) -> GenericArgsRef<'tcx> {
+        self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
     }
 
     pub fn mk_alias_ty(
         self,
         def_id: DefId,
-        substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
+        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> ty::AliasTy<'tcx> {
-        let substs = self.check_and_mk_substs(def_id, substs);
-        ty::AliasTy { def_id, substs, _use_mk_alias_ty_instead: () }
+        let args = self.check_and_mk_args(def_id, args);
+        ty::AliasTy { def_id, args, _use_mk_alias_ty_instead: () }
     }
 
     pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index a0b17c374e4..905e855896e 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -71,7 +71,7 @@ impl<'tcx> Ty<'tcx> {
     /// ADTs with no type arguments.
     pub fn is_simple_text(self) -> bool {
         match self.kind() {
-            Adt(_, substs) => substs.non_erasable_generics().next().is_none(),
+            Adt(_, args) => args.non_erasable_generics().next().is_none(),
             Ref(_, ty, _) => ty.is_simple_text(),
             _ => self.is_simple_ty(),
         }
@@ -491,7 +491,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> {
 
             Alias(Opaque, AliasTy { def_id, .. }) => {
                 let parent = self.tcx.parent(def_id);
-                let parent_ty = self.tcx.type_of(parent).subst_identity();
+                let parent_ty = self.tcx.type_of(parent).instantiate_identity();
                 if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent)
                     && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind()
                     && parent_opaque_def_id == def_id
@@ -558,8 +558,8 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> {
         let t = match *t.kind() {
             Infer(InferTy::TyVar(_)) if self.infer_suggestable => t,
 
-            FnDef(def_id, substs) => {
-                Ty::new_fn_ptr(self.tcx, self.tcx.fn_sig(def_id).subst(self.tcx, substs))
+            FnDef(def_id, args) => {
+                Ty::new_fn_ptr(self.tcx, self.tcx.fn_sig(def_id).instantiate(self.tcx, args))
             }
 
             // FIXME(compiler-errors): We could replace these with infer, I guess.
@@ -575,7 +575,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> {
 
             Alias(Opaque, AliasTy { def_id, .. }) => {
                 let parent = self.tcx.parent(def_id);
-                let parent_ty = self.tcx.type_of(parent).subst_identity();
+                let parent_ty = self.tcx.type_of(parent).instantiate_identity();
                 if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent)
                     && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind()
                     && parent_opaque_def_id == def_id
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 76f61d9ac9c..e86ff4d26aa 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -1,6 +1,6 @@
 use crate::mir::Mutability;
-use crate::ty::subst::GenericArgKind;
-use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeVisitableExt};
+use crate::ty::GenericArgKind;
+use crate::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
 use rustc_hir::def_id::DefId;
 use std::fmt::Debug;
 use std::hash::Hash;
@@ -188,12 +188,12 @@ pub struct DeepRejectCtxt {
 }
 
 impl DeepRejectCtxt {
-    pub fn substs_refs_may_unify<'tcx>(
+    pub fn args_refs_may_unify<'tcx>(
         self,
-        obligation_substs: SubstsRef<'tcx>,
-        impl_substs: SubstsRef<'tcx>,
+        obligation_args: GenericArgsRef<'tcx>,
+        impl_args: GenericArgsRef<'tcx>,
     ) -> bool {
-        iter::zip(obligation_substs, impl_substs).all(|(obl, imp)| {
+        iter::zip(obligation_args, impl_args).all(|(obl, imp)| {
             match (obl.unpack(), imp.unpack()) {
                 // We don't fast reject based on regions for now.
                 (GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) => true,
@@ -258,9 +258,9 @@ impl DeepRejectCtxt {
                 }
                 _ => false,
             },
-            ty::Adt(obl_def, obl_substs) => match k {
-                &ty::Adt(impl_def, impl_substs) => {
-                    obl_def == impl_def && self.substs_refs_may_unify(obl_substs, impl_substs)
+            ty::Adt(obl_def, obl_args) => match k {
+                &ty::Adt(impl_def, impl_args) => {
+                    obl_def == impl_def && self.args_refs_may_unify(obl_args, impl_args)
                 }
                 _ => false,
             },
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index ff391794703..bbd4a623330 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -1,5 +1,5 @@
-use crate::ty::subst::{GenericArg, GenericArgKind};
 use crate::ty::{self, InferConst, Ty, TypeFlags};
+use crate::ty::{GenericArg, GenericArgKind};
 use std::slice;
 
 #[derive(Debug)]
@@ -105,48 +105,48 @@ impl FlagComputation {
                 self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
             }
 
-            ty::Generator(_, substs, _) => {
-                let substs = substs.as_generator();
+            ty::Generator(_, args, _) => {
+                let args = args.as_generator();
                 let should_remove_further_specializable =
                     !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
-                self.add_substs(substs.parent_substs());
+                self.add_args(args.parent_args());
                 if should_remove_further_specializable {
                     self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE;
                 }
 
-                self.add_ty(substs.resume_ty());
-                self.add_ty(substs.return_ty());
-                self.add_ty(substs.witness());
-                self.add_ty(substs.yield_ty());
-                self.add_ty(substs.tupled_upvars_ty());
+                self.add_ty(args.resume_ty());
+                self.add_ty(args.return_ty());
+                self.add_ty(args.witness());
+                self.add_ty(args.yield_ty());
+                self.add_ty(args.tupled_upvars_ty());
             }
 
             &ty::GeneratorWitness(ts) => {
                 self.bound_computation(ts, |flags, ts| flags.add_tys(ts));
             }
 
-            ty::GeneratorWitnessMIR(_, substs) => {
+            ty::GeneratorWitnessMIR(_, args) => {
                 let should_remove_further_specializable =
                     !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
-                self.add_substs(substs);
+                self.add_args(args);
                 if should_remove_further_specializable {
                     self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE;
                 }
                 self.add_flags(TypeFlags::HAS_TY_GENERATOR);
             }
 
-            &ty::Closure(_, substs) => {
-                let substs = substs.as_closure();
+            &ty::Closure(_, args) => {
+                let args = args.as_closure();
                 let should_remove_further_specializable =
                     !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
-                self.add_substs(substs.parent_substs());
+                self.add_args(args.parent_args());
                 if should_remove_further_specializable {
                     self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE;
                 }
 
-                self.add_ty(substs.sig_as_fn_ptr_ty());
-                self.add_ty(substs.kind_ty());
-                self.add_ty(substs.tupled_upvars_ty());
+                self.add_ty(args.sig_as_fn_ptr_ty());
+                self.add_ty(args.kind_ty());
+                self.add_ty(args.tupled_upvars_ty());
             }
 
             &ty::Bound(debruijn, _) => {
@@ -172,8 +172,8 @@ impl FlagComputation {
                 }
             }
 
-            &ty::Adt(_, substs) => {
-                self.add_substs(substs);
+            &ty::Adt(_, args) => {
+                self.add_args(args);
             }
 
             &ty::Alias(kind, data) => {
@@ -189,7 +189,7 @@ impl FlagComputation {
             &ty::Dynamic(obj, r, _) => {
                 for predicate in obj.iter() {
                     self.bound_computation(predicate, |computation, predicate| match predicate {
-                        ty::ExistentialPredicate::Trait(tr) => computation.add_substs(tr.substs),
+                        ty::ExistentialPredicate::Trait(tr) => computation.add_args(tr.args),
                         ty::ExistentialPredicate::Projection(p) => {
                             computation.add_existential_projection(&p);
                         }
@@ -220,8 +220,8 @@ impl FlagComputation {
                 self.add_tys(types);
             }
 
-            &ty::FnDef(_, substs) => {
-                self.add_substs(substs);
+            &ty::FnDef(_, args) => {
+                self.add_args(args);
             }
 
             &ty::FnPtr(fn_sig) => self.bound_computation(fn_sig, |computation, fn_sig| {
@@ -238,7 +238,7 @@ impl FlagComputation {
     fn add_predicate_atom(&mut self, atom: ty::PredicateKind<'_>) {
         match atom {
             ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
-                self.add_substs(trait_pred.trait_ref.substs);
+                self.add_args(trait_pred.trait_ref.args);
             }
             ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
                 a,
@@ -274,11 +274,11 @@ impl FlagComputation {
                 self.add_term(term);
             }
             ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
-                self.add_substs(slice::from_ref(&arg));
+                self.add_args(slice::from_ref(&arg));
             }
             ty::PredicateKind::ObjectSafe(_def_id) => {}
-            ty::PredicateKind::ClosureKind(_def_id, substs, _kind) => {
-                self.add_substs(substs);
+            ty::PredicateKind::ClosureKind(_def_id, args, _kind) => {
+                self.add_args(args);
             }
             ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(uv)) => {
                 self.add_const(uv);
@@ -317,7 +317,7 @@ impl FlagComputation {
         self.add_ty(c.ty());
         match c.kind() {
             ty::ConstKind::Unevaluated(uv) => {
-                self.add_substs(uv.substs);
+                self.add_args(uv.args);
                 self.add_flags(TypeFlags::HAS_CT_PROJECTION);
             }
             ty::ConstKind::Infer(infer) => {
@@ -365,7 +365,7 @@ impl FlagComputation {
     }
 
     fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
-        self.add_substs(projection.substs);
+        self.add_args(projection.args);
         match projection.term.unpack() {
             ty::TermKind::Ty(ty) => self.add_ty(ty),
             ty::TermKind::Const(ct) => self.add_const(ct),
@@ -373,11 +373,11 @@ impl FlagComputation {
     }
 
     fn add_alias_ty(&mut self, alias_ty: ty::AliasTy<'_>) {
-        self.add_substs(alias_ty.substs);
+        self.add_args(alias_ty.args);
     }
 
-    fn add_substs(&mut self, substs: &[GenericArg<'_>]) {
-        for kind in substs {
+    fn add_args(&mut self, args: &[GenericArg<'_>]) {
+        for kind in args {
             match kind.unpack() {
                 GenericArgKind::Type(ty) => self.add_ty(ty),
                 GenericArgKind::Lifetime(lt) => self.add_region(lt),
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index e1a58b97557..12af8456494 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -1,8 +1,8 @@
-// Type substitutions.
+// Generic arguments.
 
 use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
-use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
+use crate::ty::sty::{ClosureArgs, GeneratorArgs, InlineConstArgs};
 use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
 use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
 
@@ -174,7 +174,7 @@ impl<'tcx> GenericArg<'tcx> {
     }
 
     /// Unpack the `GenericArg` as a type when it is known certainly to be a type.
-    /// This is true in cases where `Substs` is used in places where the kinds are known
+    /// This is true in cases where `GenericArgs` is used in places where the kinds are known
     /// to be limited (e.g. in tuples, where the only parameters are type parameters).
     pub fn expect_ty(self) -> Ty<'tcx> {
         self.as_type().unwrap_or_else(|| bug!("expected a type, but found another kind"))
@@ -241,13 +241,13 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for GenericArg<'tcx> {
     }
 }
 
-/// List of generic arguments that are gonna be used to substitute generic parameters.
-pub type InternalSubsts<'tcx> = List<GenericArg<'tcx>>;
+/// List of generic arguments that are gonna be used to replace generic parameters.
+pub type GenericArgs<'tcx> = List<GenericArg<'tcx>>;
 
-pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>;
+pub type GenericArgsRef<'tcx> = &'tcx GenericArgs<'tcx>;
 
-impl<'tcx> InternalSubsts<'tcx> {
-    /// Converts substs to a type list.
+impl<'tcx> GenericArgs<'tcx> {
+    /// Converts generic args to a type list.
     ///
     /// # Panics
     ///
@@ -255,66 +255,71 @@ impl<'tcx> InternalSubsts<'tcx> {
     pub fn into_type_list(&self, tcx: TyCtxt<'tcx>) -> &'tcx List<Ty<'tcx>> {
         tcx.mk_type_list_from_iter(self.iter().map(|arg| match arg.unpack() {
             GenericArgKind::Type(ty) => ty,
-            _ => bug!("`into_type_list` called on substs with non-types"),
+            _ => bug!("`into_type_list` called on generic arg with non-types"),
         }))
     }
 
-    /// Interpret these substitutions as the substitutions of a closure type.
-    /// Closure substitutions have a particular structure controlled by the
+    /// Interpret these generic args as the args of a closure type.
+    /// Closure args have a particular structure controlled by the
     /// compiler that encodes information like the signature and closure kind;
-    /// see `ty::ClosureSubsts` struct for more comments.
-    pub fn as_closure(&'tcx self) -> ClosureSubsts<'tcx> {
-        ClosureSubsts { substs: self }
+    /// see `ty::ClosureArgs` struct for more comments.
+    pub fn as_closure(&'tcx self) -> ClosureArgs<'tcx> {
+        ClosureArgs { args: self }
     }
 
-    /// Interpret these substitutions as the substitutions of a generator type.
-    /// Generator substitutions have a particular structure controlled by the
+    /// Interpret these generic args as the args of a generator type.
+    /// Generator args have a particular structure controlled by the
     /// compiler that encodes information like the signature and generator kind;
-    /// see `ty::GeneratorSubsts` struct for more comments.
-    pub fn as_generator(&'tcx self) -> GeneratorSubsts<'tcx> {
-        GeneratorSubsts { substs: self }
+    /// see `ty::GeneratorArgs` struct for more comments.
+    pub fn as_generator(&'tcx self) -> GeneratorArgs<'tcx> {
+        GeneratorArgs { args: self }
     }
 
-    /// Interpret these substitutions as the substitutions of an inline const.
-    /// Inline const substitutions have a particular structure controlled by the
+    /// Interpret these generic args as the args of an inline const.
+    /// Inline const args have a particular structure controlled by the
     /// compiler that encodes information like the inferred type;
-    /// see `ty::InlineConstSubsts` struct for more comments.
-    pub fn as_inline_const(&'tcx self) -> InlineConstSubsts<'tcx> {
-        InlineConstSubsts { substs: self }
+    /// see `ty::InlineConstArgs` struct for more comments.
+    pub fn as_inline_const(&'tcx self) -> InlineConstArgs<'tcx> {
+        InlineConstArgs { args: self }
     }
 
-    /// Creates an `InternalSubsts` that maps each generic parameter to itself.
-    pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: impl Into<DefId>) -> SubstsRef<'tcx> {
+    /// Creates an `GenericArgs` that maps each generic parameter to itself.
+    pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: impl Into<DefId>) -> GenericArgsRef<'tcx> {
         Self::for_item(tcx, def_id.into(), |param, _| tcx.mk_param_from_def(param))
     }
 
-    /// Creates an `InternalSubsts` for generic parameter definitions,
+    /// Creates an `GenericArgs` for generic parameter definitions,
     /// by calling closures to obtain each kind.
-    /// The closures get to observe the `InternalSubsts` as they're
+    /// The closures get to observe the `GenericArgs` as they're
     /// being built, which can be used to correctly
-    /// substitute defaults of generic parameters.
-    pub fn for_item<F>(tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx>
+    /// replace defaults of generic parameters.
+    pub fn for_item<F>(tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> GenericArgsRef<'tcx>
     where
         F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
     {
         let defs = tcx.generics_of(def_id);
         let count = defs.count();
-        let mut substs = SmallVec::with_capacity(count);
-        Self::fill_item(&mut substs, tcx, defs, &mut mk_kind);
-        tcx.mk_substs(&substs)
+        let mut args = SmallVec::with_capacity(count);
+        Self::fill_item(&mut args, tcx, defs, &mut mk_kind);
+        tcx.mk_args(&args)
     }
 
-    pub fn extend_to<F>(&self, tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx>
+    pub fn extend_to<F>(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        def_id: DefId,
+        mut mk_kind: F,
+    ) -> GenericArgsRef<'tcx>
     where
         F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
     {
-        Self::for_item(tcx, def_id, |param, substs| {
-            self.get(param.index as usize).cloned().unwrap_or_else(|| mk_kind(param, substs))
+        Self::for_item(tcx, def_id, |param, args| {
+            self.get(param.index as usize).cloned().unwrap_or_else(|| mk_kind(param, args))
         })
     }
 
     pub fn fill_item<F>(
-        substs: &mut SmallVec<[GenericArg<'tcx>; 8]>,
+        args: &mut SmallVec<[GenericArg<'tcx>; 8]>,
         tcx: TyCtxt<'tcx>,
         defs: &ty::Generics,
         mk_kind: &mut F,
@@ -323,38 +328,38 @@ impl<'tcx> InternalSubsts<'tcx> {
     {
         if let Some(def_id) = defs.parent {
             let parent_defs = tcx.generics_of(def_id);
-            Self::fill_item(substs, tcx, parent_defs, mk_kind);
+            Self::fill_item(args, tcx, parent_defs, mk_kind);
         }
-        Self::fill_single(substs, defs, mk_kind)
+        Self::fill_single(args, defs, mk_kind)
     }
 
     pub fn fill_single<F>(
-        substs: &mut SmallVec<[GenericArg<'tcx>; 8]>,
+        args: &mut SmallVec<[GenericArg<'tcx>; 8]>,
         defs: &ty::Generics,
         mk_kind: &mut F,
     ) where
         F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
     {
-        substs.reserve(defs.params.len());
+        args.reserve(defs.params.len());
         for param in &defs.params {
-            let kind = mk_kind(param, substs);
-            assert_eq!(param.index as usize, substs.len(), "{substs:#?}, {defs:#?}");
-            substs.push(kind);
+            let kind = mk_kind(param, args);
+            assert_eq!(param.index as usize, args.len(), "{args:#?}, {defs:#?}");
+            args.push(kind);
         }
     }
 
-    // Extend an `original_substs` list to the full number of substs expected by `def_id`,
+    // Extend an `original_args` list to the full number of args expected by `def_id`,
     // filling in the missing parameters with error ty/ct or 'static regions.
     pub fn extend_with_error(
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-        original_substs: &[GenericArg<'tcx>],
-    ) -> SubstsRef<'tcx> {
-        ty::InternalSubsts::for_item(tcx, def_id, |def, substs| {
-            if let Some(subst) = original_substs.get(def.index as usize) {
-                *subst
+        original_args: &[GenericArg<'tcx>],
+    ) -> GenericArgsRef<'tcx> {
+        ty::GenericArgs::for_item(tcx, def_id, |def, args| {
+            if let Some(arg) = original_args.get(def.index as usize) {
+                *arg
             } else {
-                def.to_error(tcx, substs)
+                def.to_error(tcx, args)
             }
         })
     }
@@ -410,9 +415,9 @@ impl<'tcx> InternalSubsts<'tcx> {
         self.type_at(def.index as usize).into()
     }
 
-    /// Transform from substitutions for a child of `source_ancestor`
-    /// (e.g., a trait or impl) to substitutions for the same child
-    /// in a different item, with `target_substs` as the base for
+    /// Transform from generic args for a child of `source_ancestor`
+    /// (e.g., a trait or impl) to args for the same child
+    /// in a different item, with `target_args` as the base for
     /// the target impl/trait, with the source child-specific
     /// parameters (e.g., method parameters) on top of that base.
     ///
@@ -423,23 +428,23 @@ impl<'tcx> InternalSubsts<'tcx> {
     /// impl<U> X<U> for U { fn f<V>() {} }
     /// ```
     ///
-    /// * If `self` is `[Self, S, T]`: the identity substs of `f` in the trait.
+    /// * If `self` is `[Self, S, T]`: the identity args of `f` in the trait.
     /// * If `source_ancestor` is the def_id of the trait.
-    /// * If `target_substs` is `[U]`, the substs for the impl.
-    /// * Then we will return `[U, T]`, the subst for `f` in the impl that
+    /// * If `target_args` is `[U]`, the args for the impl.
+    /// * Then we will return `[U, T]`, the arg for `f` in the impl that
     ///   are needed for it to match the trait.
     pub fn rebase_onto(
         &self,
         tcx: TyCtxt<'tcx>,
         source_ancestor: DefId,
-        target_substs: SubstsRef<'tcx>,
-    ) -> SubstsRef<'tcx> {
+        target_args: GenericArgsRef<'tcx>,
+    ) -> GenericArgsRef<'tcx> {
         let defs = tcx.generics_of(source_ancestor);
-        tcx.mk_substs_from_iter(target_substs.iter().chain(self.iter().skip(defs.params.len())))
+        tcx.mk_args_from_iter(target_args.iter().chain(self.iter().skip(defs.params.len())))
     }
 
-    pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> {
-        tcx.mk_substs_from_iter(self.iter().take(generics.count()))
+    pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> GenericArgsRef<'tcx> {
+        tcx.mk_args_from_iter(self.iter().take(generics.count()))
     }
 
     pub fn host_effect_param(&'tcx self) -> Option<ty::Const<'tcx>> {
@@ -447,7 +452,7 @@ impl<'tcx> InternalSubsts<'tcx> {
     }
 }
 
-impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> {
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArgsRef<'tcx> {
     fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
         self,
         folder: &mut F,
@@ -456,16 +461,12 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> {
         // common length lists, to avoid the overhead of `SmallVec` creation.
         // The match arms are in order of frequency. The 1, 2, and 0 cases are
         // typically hit in 90--99.99% of cases. When folding doesn't change
-        // the substs, it's faster to reuse the existing substs rather than
-        // calling `mk_substs`.
+        // the args, it's faster to reuse the existing args rather than
+        // calling `mk_args`.
         match self.len() {
             1 => {
                 let param0 = self[0].try_fold_with(folder)?;
-                if param0 == self[0] {
-                    Ok(self)
-                } else {
-                    Ok(folder.interner().mk_substs(&[param0]))
-                }
+                if param0 == self[0] { Ok(self) } else { Ok(folder.interner().mk_args(&[param0])) }
             }
             2 => {
                 let param0 = self[0].try_fold_with(folder)?;
@@ -473,11 +474,11 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> {
                 if param0 == self[0] && param1 == self[1] {
                     Ok(self)
                 } else {
-                    Ok(folder.interner().mk_substs(&[param0, param1]))
+                    Ok(folder.interner().mk_args(&[param0, param1]))
                 }
             }
             0 => Ok(self),
-            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_substs(v)),
+            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_args(v)),
         }
     }
 }
@@ -487,7 +488,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
-        // This code is fairly hot, though not as hot as `SubstsRef`.
+        // This code is fairly hot, though not as hot as `GenericArgsRef`.
         //
         // When compiling stage 2, I get the following results:
         //
@@ -525,18 +526,18 @@ impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx
 }
 
 /// Similar to [`super::Binder`] except that it tracks early bound generics, i.e. `struct Foo<T>(T)`
-/// needs `T` substituted immediately. This type primarily exists to avoid forgetting to call
-/// `subst`.
+/// needs `T` instantiated immediately. This type primarily exists to avoid forgetting to call
+/// `instantiate`.
 ///
-/// If you don't have anything to `subst`, you may be looking for
-/// [`subst_identity`](EarlyBinder::subst_identity) or [`skip_binder`](EarlyBinder::skip_binder).
+/// If you don't have anything to `instantiate`, you may be looking for
+/// [`instantiate_identity`](EarlyBinder::instantiate_identity) or [`skip_binder`](EarlyBinder::skip_binder).
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 #[derive(Encodable, Decodable, HashStable)]
 pub struct EarlyBinder<T> {
     value: T,
 }
 
-/// For early binders, you should first call `subst` before using any visitors.
+/// For early binders, you should first call `instantiate` before using any visitors.
 impl<'tcx, T> !TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
 impl<'tcx, T> !TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
 
@@ -580,7 +581,7 @@ impl<T> EarlyBinder<T> {
     /// This can be used to extract data that does not depend on generic parameters
     /// (e.g., getting the `DefId` of the inner value or getting the number of
     /// arguments of an `FnSig`). Otherwise, consider using
-    /// [`subst_identity`](EarlyBinder::subst_identity).
+    /// [`instantiate_identity`](EarlyBinder::instantiate_identity).
     ///
     /// To skip the binder on `x: &EarlyBinder<T>` to obtain `&T`, leverage
     /// [`EarlyBinder::as_ref`](EarlyBinder::as_ref): `x.as_ref().skip_binder()`.
@@ -609,35 +610,31 @@ impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
 where
     I::Item: TypeFoldable<TyCtxt<'tcx>>,
 {
-    pub fn subst_iter(
-        self,
-        tcx: TyCtxt<'tcx>,
-        substs: &'s [GenericArg<'tcx>],
-    ) -> SubstIter<'s, 'tcx, I> {
-        SubstIter { it: self.value.into_iter(), tcx, substs }
+    pub fn arg_iter(self, tcx: TyCtxt<'tcx>, args: &'s [GenericArg<'tcx>]) -> ArgIter<'s, 'tcx, I> {
+        ArgIter { it: self.value.into_iter(), tcx, args }
     }
 
-    /// Similar to [`subst_identity`](EarlyBinder::subst_identity),
+    /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity),
     /// but on an iterator of `TypeFoldable` values.
-    pub fn subst_identity_iter(self) -> I::IntoIter {
+    pub fn instantiate_identity_iter(self) -> I::IntoIter {
         self.value.into_iter()
     }
 }
 
-pub struct SubstIter<'s, 'tcx, I: IntoIterator> {
+pub struct ArgIter<'s, 'tcx, I: IntoIterator> {
     it: I::IntoIter,
     tcx: TyCtxt<'tcx>,
-    substs: &'s [GenericArg<'tcx>],
+    args: &'s [GenericArg<'tcx>],
 }
 
-impl<'tcx, I: IntoIterator> Iterator for SubstIter<'_, 'tcx, I>
+impl<'tcx, I: IntoIterator> Iterator for ArgIter<'_, 'tcx, I>
 where
     I::Item: TypeFoldable<TyCtxt<'tcx>>,
 {
     type Item = I::Item;
 
     fn next(&mut self) -> Option<Self::Item> {
-        Some(EarlyBinder { value: self.it.next()? }.subst(self.tcx, self.substs))
+        Some(EarlyBinder { value: self.it.next()? }.instantiate(self.tcx, self.args))
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
@@ -645,17 +642,17 @@ where
     }
 }
 
-impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIter<'_, 'tcx, I>
+impl<'tcx, I: IntoIterator> DoubleEndedIterator for ArgIter<'_, 'tcx, I>
 where
     I::IntoIter: DoubleEndedIterator,
     I::Item: TypeFoldable<TyCtxt<'tcx>>,
 {
     fn next_back(&mut self) -> Option<Self::Item> {
-        Some(EarlyBinder { value: self.it.next_back()? }.subst(self.tcx, self.substs))
+        Some(EarlyBinder { value: self.it.next_back()? }.instantiate(self.tcx, self.args))
     }
 }
 
-impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIter<'_, 'tcx, I>
+impl<'tcx, I: IntoIterator> ExactSizeIterator for ArgIter<'_, 'tcx, I>
 where
     I::IntoIter: ExactSizeIterator,
     I::Item: TypeFoldable<TyCtxt<'tcx>>,
@@ -667,28 +664,30 @@ where
     I::Item: Deref,
     <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
 {
-    pub fn subst_iter_copied(
+    pub fn arg_iter_copied(
         self,
         tcx: TyCtxt<'tcx>,
-        substs: &'s [GenericArg<'tcx>],
-    ) -> SubstIterCopied<'s, 'tcx, I> {
-        SubstIterCopied { it: self.value.into_iter(), tcx, substs }
+        args: &'s [GenericArg<'tcx>],
+    ) -> ArgIterCopied<'s, 'tcx, I> {
+        ArgIterCopied { it: self.value.into_iter(), tcx, args }
     }
 
-    /// Similar to [`subst_identity`](EarlyBinder::subst_identity),
+    /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity),
     /// but on an iterator of values that deref to a `TypeFoldable`.
-    pub fn subst_identity_iter_copied(self) -> impl Iterator<Item = <I::Item as Deref>::Target> {
+    pub fn instantiate_identity_iter_copied(
+        self,
+    ) -> impl Iterator<Item = <I::Item as Deref>::Target> {
         self.value.into_iter().map(|v| *v)
     }
 }
 
-pub struct SubstIterCopied<'a, 'tcx, I: IntoIterator> {
+pub struct ArgIterCopied<'a, 'tcx, I: IntoIterator> {
     it: I::IntoIter,
     tcx: TyCtxt<'tcx>,
-    substs: &'a [GenericArg<'tcx>],
+    args: &'a [GenericArg<'tcx>],
 }
 
-impl<'tcx, I: IntoIterator> Iterator for SubstIterCopied<'_, 'tcx, I>
+impl<'tcx, I: IntoIterator> Iterator for ArgIterCopied<'_, 'tcx, I>
 where
     I::Item: Deref,
     <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
@@ -696,7 +695,7 @@ where
     type Item = <I::Item as Deref>::Target;
 
     fn next(&mut self) -> Option<Self::Item> {
-        self.it.next().map(|value| EarlyBinder { value: *value }.subst(self.tcx, self.substs))
+        self.it.next().map(|value| EarlyBinder { value: *value }.instantiate(self.tcx, self.args))
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
@@ -704,18 +703,20 @@ where
     }
 }
 
-impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIterCopied<'_, 'tcx, I>
+impl<'tcx, I: IntoIterator> DoubleEndedIterator for ArgIterCopied<'_, 'tcx, I>
 where
     I::IntoIter: DoubleEndedIterator,
     I::Item: Deref,
     <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
 {
     fn next_back(&mut self) -> Option<Self::Item> {
-        self.it.next_back().map(|value| EarlyBinder { value: *value }.subst(self.tcx, self.substs))
+        self.it
+            .next_back()
+            .map(|value| EarlyBinder { value: *value }.instantiate(self.tcx, self.args))
     }
 }
 
-impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIterCopied<'_, 'tcx, I>
+impl<'tcx, I: IntoIterator> ExactSizeIterator for ArgIterCopied<'_, 'tcx, I>
 where
     I::IntoIter: ExactSizeIterator,
     I::Item: Deref,
@@ -746,20 +747,20 @@ impl<T: Iterator> Iterator for EarlyBinderIter<T> {
 }
 
 impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<T> {
-    pub fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T {
-        let mut folder = SubstFolder { tcx, substs, binders_passed: 0 };
+    pub fn instantiate(self, tcx: TyCtxt<'tcx>, args: &[GenericArg<'tcx>]) -> T {
+        let mut folder = ArgFolder { tcx, args, binders_passed: 0 };
         self.value.fold_with(&mut folder)
     }
 
-    /// Makes the identity substitution `T0 => T0, ..., TN => TN`.
+    /// Makes the identity replacement `T0 => T0, ..., TN => TN`.
     /// Conceptually, this converts universally bound variables into placeholders
     /// when inside of a given item.
     ///
     /// For example, consider `for<T> fn foo<T>(){ .. }`:
     /// - Outside of `foo`, `T` is bound (represented by the presence of `EarlyBinder`).
     /// - Inside of the body of `foo`, we treat `T` as a placeholder by calling
-    /// `subst_identity` to discharge the `EarlyBinder`.
-    pub fn subst_identity(self) -> T {
+    /// `instantiate_identity` to discharge the `EarlyBinder`.
+    pub fn instantiate_identity(self) -> T {
         self.value
     }
 
@@ -772,15 +773,15 @@ impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<T> {
 ///////////////////////////////////////////////////////////////////////////
 // The actual substitution engine itself is a type folder.
 
-struct SubstFolder<'a, 'tcx> {
+struct ArgFolder<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
-    substs: &'a [GenericArg<'tcx>],
+    args: &'a [GenericArg<'tcx>],
 
     /// Number of region binders we have passed through while doing the substitution
     binders_passed: u32,
 }
 
-impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for SubstFolder<'a, 'tcx> {
+impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> {
     #[inline]
     fn interner(&self) -> TyCtxt<'tcx> {
         self.tcx
@@ -799,12 +800,12 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for SubstFolder<'a, 'tcx> {
     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
         #[cold]
         #[inline(never)]
-        fn region_param_out_of_range(data: ty::EarlyBoundRegion, substs: &[GenericArg<'_>]) -> ! {
+        fn region_param_out_of_range(data: ty::EarlyBoundRegion, args: &[GenericArg<'_>]) -> ! {
             bug!(
-                "Region parameter out of range when substituting in region {} (index={}, substs = {:?})",
+                "Region parameter out of range when substituting in region {} (index={}, args = {:?})",
                 data.name,
                 data.index,
-                substs,
+                args,
             )
         }
 
@@ -826,11 +827,11 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for SubstFolder<'a, 'tcx> {
         // the specialized routine `ty::replace_late_regions()`.
         match *r {
             ty::ReEarlyBound(data) => {
-                let rk = self.substs.get(data.index as usize).map(|k| k.unpack());
+                let rk = self.args.get(data.index as usize).map(|k| k.unpack());
                 match rk {
                     Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
                     Some(other) => region_param_invalid(data, other),
-                    None => region_param_out_of_range(data, self.substs),
+                    None => region_param_out_of_range(data, self.args),
                 }
             }
             ty::ReLateBound(..)
@@ -863,10 +864,10 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for SubstFolder<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
+impl<'a, 'tcx> ArgFolder<'a, 'tcx> {
     fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
-        // Look up the type in the substitutions. It really should be in there.
-        let opt_ty = self.substs.get(p.index as usize).map(|k| k.unpack());
+        // Look up the type in the args. It really should be in there.
+        let opt_ty = self.args.get(p.index as usize).map(|k| k.unpack());
         let ty = match opt_ty {
             Some(GenericArgKind::Type(ty)) => ty,
             Some(kind) => self.type_param_expected(p, source_ty, kind),
@@ -880,12 +881,12 @@ impl<'a, 'tcx> SubstFolder<'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, substs={:?}",
+            "expected type for `{:?}` ({:?}/{}) but found {:?} when substituting, args={:?}",
             p,
             ty,
             p.index,
             kind,
-            self.substs,
+            self.args,
         )
     }
 
@@ -893,17 +894,17 @@ impl<'a, 'tcx> SubstFolder<'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, substs={:?}",
+            "type parameter `{:?}` ({:?}/{}) out of range when substituting, args={:?}",
             p,
             ty,
             p.index,
-            self.substs,
+            self.args,
         )
     }
 
     fn const_for_param(&self, p: ParamConst, source_ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
-        // Look up the const in the substitutions. It really should be in there.
-        let opt_ct = self.substs.get(p.index as usize).map(|k| k.unpack());
+        // Look up the const in the args. It really should be in there.
+        let opt_ct = self.args.get(p.index as usize).map(|k| k.unpack());
         let ct = match opt_ct {
             Some(GenericArgKind::Const(ct)) => ct,
             Some(kind) => self.const_param_expected(p, source_ct, kind),
@@ -922,12 +923,12 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
         kind: GenericArgKind<'tcx>,
     ) -> ! {
         bug!(
-            "expected const for `{:?}` ({:?}/{}) but found {:?} when substituting substs={:?}",
+            "expected const for `{:?}` ({:?}/{}) but found {:?} when substituting args={:?}",
             p,
             ct,
             p.index,
             kind,
-            self.substs,
+            self.args,
         )
     }
 
@@ -935,11 +936,11 @@ impl<'a, 'tcx> SubstFolder<'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 substs={:?}",
+            "const parameter `{:?}` ({:?}/{}) out of range when substituting args={:?}",
             p,
             ct,
             p.index,
-            self.substs,
+            self.args,
         )
     }
 
@@ -1011,13 +1012,13 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
     }
 }
 
-/// Stores the user-given substs to reach some fully qualified path
+/// Stores the user-given args to reach some fully qualified path
 /// (e.g., `<T>::Item` or `<T as Trait>::Item`).
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
-pub struct UserSubsts<'tcx> {
-    /// The substitutions for the item as given by the user.
-    pub substs: SubstsRef<'tcx>,
+pub struct UserArgs<'tcx> {
+    /// The args for the item as given by the user.
+    pub args: GenericArgsRef<'tcx>,
 
     /// The self type, in the case of a `<T>::Item` path (when applied
     /// to an inherent impl). See `UserSelfTy` below.
@@ -1037,7 +1038,7 @@ pub struct UserSubsts<'tcx> {
 /// when you then have a path like `<Foo<&'static u32>>::method`,
 /// this struct would carry the `DefId` of the impl along with the
 /// self type `Foo<u32>`. Then we can instantiate the parameters of
-/// the impl (with the substs from `UserSubsts`) and apply those to
+/// the impl (with the args from `UserArgs`) and apply those to
 /// the self type, giving `Foo<?A>`. Finally, we unify that with
 /// the self type here, which contains `?A` to be `&'static u32`
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 6c7125c4cb7..338590717d0 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -1,5 +1,5 @@
 use crate::ty;
-use crate::ty::{EarlyBinder, SubstsRef};
+use crate::ty::{EarlyBinder, GenericArgsRef};
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
@@ -97,14 +97,14 @@ impl GenericParamDef {
     pub fn to_error<'tcx>(
         &self,
         tcx: TyCtxt<'tcx>,
-        preceding_substs: &[ty::GenericArg<'tcx>],
+        preceding_args: &[ty::GenericArg<'tcx>],
     ) -> ty::GenericArg<'tcx> {
         match &self.kind {
             ty::GenericParamDefKind::Lifetime => ty::Region::new_error_misc(tcx).into(),
             ty::GenericParamDefKind::Type { .. } => Ty::new_misc_error(tcx).into(),
             ty::GenericParamDefKind::Const { .. } => ty::Const::new_misc_error(
                 tcx,
-                tcx.type_of(self.def_id).subst(tcx, preceding_substs),
+                tcx.type_of(self.def_id).instantiate(tcx, preceding_args),
             )
             .into(),
         }
@@ -136,7 +136,7 @@ pub struct Generics {
     pub has_self: bool,
     pub has_late_bound_regions: Option<Span>,
 
-    // The index of the host effect when substituted. (i.e. might be index to parent substs)
+    // The index of the host effect when substituted. (i.e. might be index to parent args)
     pub host_effect_index: Option<usize>,
 }
 
@@ -278,14 +278,14 @@ impl<'tcx> Generics {
         })
     }
 
-    /// Returns the substs corresponding to the generic parameters
+    /// Returns the args corresponding to the generic parameters
     /// of this item, excluding `Self`.
     ///
     /// **This should only be used for diagnostics purposes.**
-    pub fn own_substs_no_defaults(
+    pub fn own_args_no_defaults(
         &'tcx self,
         tcx: TyCtxt<'tcx>,
-        substs: &'tcx [ty::GenericArg<'tcx>],
+        args: &'tcx [ty::GenericArg<'tcx>],
     ) -> &'tcx [ty::GenericArg<'tcx>] {
         let mut own_params = self.parent_count..self.count();
         if self.has_self && self.parent.is_none() {
@@ -304,22 +304,22 @@ impl<'tcx> Generics {
             .rev()
             .take_while(|param| {
                 param.default_value(tcx).is_some_and(|default| {
-                    default.subst(tcx, substs) == substs[param.index as usize]
+                    default.instantiate(tcx, args) == args[param.index as usize]
                 })
             })
             .count();
 
-        &substs[own_params]
+        &args[own_params]
     }
 
-    /// Returns the substs corresponding to the generic parameters of this item, excluding `Self`.
+    /// Returns the args corresponding to the generic parameters of this item, excluding `Self`.
     ///
     /// **This should only be used for diagnostics purposes.**
-    pub fn own_substs(
+    pub fn own_args(
         &'tcx self,
-        substs: &'tcx [ty::GenericArg<'tcx>],
+        args: &'tcx [ty::GenericArg<'tcx>],
     ) -> &'tcx [ty::GenericArg<'tcx>] {
-        let own = &substs[self.parent_count..][..self.params.len()];
+        let own = &args[self.parent_count..][..self.params.len()];
         if self.has_self && self.parent.is_none() { &own[1..] } else { &own }
     }
 }
@@ -335,19 +335,19 @@ impl<'tcx> GenericPredicates<'tcx> {
     pub fn instantiate(
         &self,
         tcx: TyCtxt<'tcx>,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) -> InstantiatedPredicates<'tcx> {
         let mut instantiated = InstantiatedPredicates::empty();
-        self.instantiate_into(tcx, &mut instantiated, substs);
+        self.instantiate_into(tcx, &mut instantiated, args);
         instantiated
     }
 
     pub fn instantiate_own(
         &self,
         tcx: TyCtxt<'tcx>,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) -> impl Iterator<Item = (Clause<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator {
-        EarlyBinder::bind(self.predicates).subst_iter_copied(tcx, substs)
+        EarlyBinder::bind(self.predicates).arg_iter_copied(tcx, args)
     }
 
     #[instrument(level = "debug", skip(self, tcx))]
@@ -355,14 +355,14 @@ impl<'tcx> GenericPredicates<'tcx> {
         &self,
         tcx: TyCtxt<'tcx>,
         instantiated: &mut InstantiatedPredicates<'tcx>,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) {
         if let Some(def_id) = self.parent {
-            tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs);
+            tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, args);
         }
-        instantiated
-            .predicates
-            .extend(self.predicates.iter().map(|(p, _)| EarlyBinder::bind(*p).subst(tcx, substs)));
+        instantiated.predicates.extend(
+            self.predicates.iter().map(|(p, _)| EarlyBinder::bind(*p).instantiate(tcx, args)),
+        );
         instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp));
     }
 
diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs
index 02baa395c3c..b03874a90e8 100644
--- a/compiler/rustc_middle/src/ty/impls_ty.rs
+++ b/compiler/rustc_middle/src/ty/impls_ty.rs
@@ -67,7 +67,7 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for SimplifiedType {
     }
 }
 
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'tcx> {
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::GenericArg<'tcx> {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         self.unpack().hash_stable(hcx, hasher);
     }
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
index 295cb146461..f278cace99d 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
@@ -19,7 +19,7 @@ pub enum InhabitedPredicate<'tcx> {
     /// type has restricted visibility.
     NotInModule(DefId),
     /// Inhabited if some generic type is inhabited.
-    /// These are replaced by calling [`Self::subst`].
+    /// These are replaced by calling [`Self::instantiate`].
     GenericType(Ty<'tcx>),
     /// A AND B
     And(&'tcx [InhabitedPredicate<'tcx>; 2]),
@@ -162,14 +162,14 @@ impl<'tcx> InhabitedPredicate<'tcx> {
     }
 
     /// Replaces generic types with its corresponding predicate
-    pub fn subst(self, tcx: TyCtxt<'tcx>, substs: ty::SubstsRef<'tcx>) -> Self {
-        self.subst_opt(tcx, substs).unwrap_or(self)
+    pub fn instantiate(self, tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> Self {
+        self.instantiate_opt(tcx, args).unwrap_or(self)
     }
 
-    fn subst_opt(self, tcx: TyCtxt<'tcx>, substs: ty::SubstsRef<'tcx>) -> Option<Self> {
+    fn instantiate_opt(self, tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> Option<Self> {
         match self {
             Self::ConstIsZero(c) => {
-                let c = ty::EarlyBinder::bind(c).subst(tcx, substs);
+                let c = ty::EarlyBinder::bind(c).instantiate(tcx, args);
                 let pred = match c.try_to_target_usize(tcx) {
                     Some(0) => Self::True,
                     Some(1..) => Self::False,
@@ -178,17 +178,17 @@ impl<'tcx> InhabitedPredicate<'tcx> {
                 Some(pred)
             }
             Self::GenericType(t) => {
-                Some(ty::EarlyBinder::bind(t).subst(tcx, substs).inhabited_predicate(tcx))
+                Some(ty::EarlyBinder::bind(t).instantiate(tcx, args).inhabited_predicate(tcx))
             }
-            Self::And(&[a, b]) => match a.subst_opt(tcx, substs) {
-                None => b.subst_opt(tcx, substs).map(|b| a.and(tcx, b)),
+            Self::And(&[a, b]) => match a.instantiate_opt(tcx, args) {
+                None => b.instantiate_opt(tcx, args).map(|b| a.and(tcx, b)),
                 Some(InhabitedPredicate::False) => Some(InhabitedPredicate::False),
-                Some(a) => Some(a.and(tcx, b.subst_opt(tcx, substs).unwrap_or(b))),
+                Some(a) => Some(a.and(tcx, b.instantiate_opt(tcx, args).unwrap_or(b))),
             },
-            Self::Or(&[a, b]) => match a.subst_opt(tcx, substs) {
-                None => b.subst_opt(tcx, substs).map(|b| a.or(tcx, b)),
+            Self::Or(&[a, b]) => match a.instantiate_opt(tcx, args) {
+                None => b.instantiate_opt(tcx, args).map(|b| a.or(tcx, b)),
                 Some(InhabitedPredicate::True) => Some(InhabitedPredicate::True),
-                Some(a) => Some(a.or(tcx, b.subst_opt(tcx, substs).unwrap_or(b))),
+                Some(a) => Some(a.or(tcx, b.instantiate_opt(tcx, args).unwrap_or(b))),
             },
             _ => None,
         }
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index b92d84152b4..4dac6891b30 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -58,7 +58,7 @@ pub(crate) fn provide(providers: &mut Providers) {
 }
 
 /// Returns an `InhabitedPredicate` that is generic over type parameters and
-/// requires calling [`InhabitedPredicate::subst`]
+/// requires calling [`InhabitedPredicate::instantiate`]
 fn inhabited_predicate_adt(tcx: TyCtxt<'_>, def_id: DefId) -> InhabitedPredicate<'_> {
     if let Some(def_id) = def_id.as_local() {
         if matches!(tcx.representability(def_id), ty::Representability::Infinite) {
@@ -87,7 +87,7 @@ impl<'tcx> VariantDef {
         InhabitedPredicate::all(
             tcx,
             self.fields.iter().map(|field| {
-                let pred = tcx.type_of(field.did).subst_identity().inhabited_predicate(tcx);
+                let pred = tcx.type_of(field.did).instantiate_identity().inhabited_predicate(tcx);
                 if adt.is_enum() {
                     return pred;
                 }
@@ -114,8 +114,8 @@ impl<'tcx> Ty<'tcx> {
             Never => InhabitedPredicate::False,
             Param(_) | Alias(ty::Projection, _) => InhabitedPredicate::GenericType(self),
             // FIXME(inherent_associated_types): Most likely we can just map to `GenericType` like above.
-            // However it's unclear if the substs passed to `InhabitedPredicate::subst` are of the correct
-            // format, i.e. don't contain parent substs. If you hit this case, please verify this beforehand.
+            // However it's unclear if the args passed to `InhabitedPredicate::instantiate` are of the correct
+            // format, i.e. don't contain parent args. If you hit this case, please verify this beforehand.
             Alias(ty::Inherent, _) => {
                 bug!("unimplemented: inhabitedness checking for inherent projections")
             }
@@ -189,7 +189,7 @@ impl<'tcx> Ty<'tcx> {
 /// N.B. this query should only be called through `Ty::inhabited_predicate`
 fn inhabited_predicate_type<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> InhabitedPredicate<'tcx> {
     match *ty.kind() {
-        Adt(adt, substs) => tcx.inhabited_predicate_adt(adt.did()).subst(tcx, substs),
+        Adt(adt, args) => tcx.inhabited_predicate_adt(adt.did()).instantiate(tcx, args),
 
         Tuple(tys) => {
             InhabitedPredicate::all(tcx, tys.iter().map(|ty| ty.inhabited_predicate(tcx)))
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index ae57e954ff4..48e88daa890 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -1,7 +1,7 @@
 use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::ty::print::{FmtPrinter, Printer};
 use crate::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
-use crate::ty::{EarlyBinder, InternalSubsts, SubstsRef, TypeVisitableExt};
+use crate::ty::{EarlyBinder, GenericArgs, GenericArgsRef, TypeVisitableExt};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::{CrateNum, DefId};
@@ -16,13 +16,13 @@ use std::fmt;
 /// A monomorphized `InstanceDef`.
 ///
 /// Monomorphization happens on-the-fly and no monomorphized MIR is ever created. Instead, this type
-/// simply couples a potentially generic `InstanceDef` with some substs, and codegen and const eval
+/// simply couples a potentially generic `InstanceDef` with some args, and codegen and const eval
 /// will do all required substitution as they run.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable, Lift, TypeFoldable, TypeVisitable)]
 pub struct Instance<'tcx> {
     pub def: InstanceDef<'tcx>,
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
@@ -115,7 +115,7 @@ impl<'tcx> Instance<'tcx> {
     /// 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());
-        tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty)
+        tcx.subst_and_normalize_erasing_regions(self.args, param_env, ty)
     }
 
     /// Finds a crate that contains a monomorphization of this instance that
@@ -139,13 +139,13 @@ impl<'tcx> Instance<'tcx> {
         }
 
         // If this a non-generic instance, it cannot be a shared monomorphization.
-        self.substs.non_erasable_generics().next()?;
+        self.args.non_erasable_generics().next()?;
 
         match self.def {
             InstanceDef::Item(def) => tcx
                 .upstream_monomorphizations_for(def)
-                .and_then(|monos| monos.get(&self.substs).cloned()),
-            InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs),
+                .and_then(|monos| monos.get(&self.args).cloned()),
+            InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.args),
             _ => None,
         }
     }
@@ -265,8 +265,8 @@ 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 `substs` from `Instance` (see
-    /// `Instance::substs_for_mir_body`).
+    /// by its users (e.g. codegen or miri) by substituting 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.
@@ -294,10 +294,10 @@ fn fmt_instance(
     type_length: rustc_session::Limit,
 ) -> fmt::Result {
     ty::tls::with(|tcx| {
-        let substs = tcx.lift(instance.substs).expect("could not lift for printing");
+        let args = tcx.lift(instance.args).expect("could not lift for printing");
 
         let s = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length)
-            .print_def_path(instance.def_id(), substs)?
+            .print_def_path(instance.def_id(), args)?
             .into_buffer();
         f.write_str(&s)
     })?;
@@ -333,18 +333,18 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
 }
 
 impl<'tcx> Instance<'tcx> {
-    pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> Instance<'tcx> {
+    pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> {
         assert!(
-            !substs.has_escaping_bound_vars(),
-            "substs of instance {:?} not normalized for codegen: {:?}",
+            !args.has_escaping_bound_vars(),
+            "args of instance {:?} not normalized for codegen: {:?}",
             def_id,
-            substs
+            args
         );
-        Instance { def: InstanceDef::Item(def_id), substs }
+        Instance { def: InstanceDef::Item(def_id), args }
     }
 
     pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
-        let substs = InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind {
+        let args = GenericArgs::for_item(tcx, def_id, |param, _| match param.kind {
             ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
             ty::GenericParamDefKind::Type { .. } => {
                 bug!("Instance::mono: {:?} has type parameters", def_id)
@@ -354,7 +354,7 @@ impl<'tcx> Instance<'tcx> {
             }
         });
 
-        Instance::new(def_id, substs)
+        Instance::new(def_id, args)
     }
 
     #[inline]
@@ -362,7 +362,7 @@ impl<'tcx> Instance<'tcx> {
         self.def.def_id()
     }
 
-    /// Resolves a `(def_id, substs)` pair to an (optional) instance -- most commonly,
+    /// Resolves a `(def_id, args)` pair to an (optional) instance -- most commonly,
     /// this is used to find the precise code that will run for a trait method invocation,
     /// if known.
     ///
@@ -390,29 +390,29 @@ impl<'tcx> Instance<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         def_id: DefId,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
         // All regions in the result of this query are erased, so it's
         // fine to erase all of the input regions.
 
-        // HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)`
+        // HACK(eddyb) erase regions in `args` first, so that `param_env.and(...)`
         // below is more likely to ignore the bounds in scope (e.g. if the only
-        // generic parameters mentioned by `substs` were lifetime ones).
-        let substs = tcx.erase_regions(substs);
-        tcx.resolve_instance(tcx.erase_regions(param_env.and((def_id, substs))))
+        // generic parameters mentioned by `args` were lifetime ones).
+        let args = tcx.erase_regions(args);
+        tcx.resolve_instance(tcx.erase_regions(param_env.and((def_id, args))))
     }
 
     pub fn expect_resolve(
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         def_id: DefId,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) -> Instance<'tcx> {
-        match ty::Instance::resolve(tcx, param_env, def_id, substs) {
+        match ty::Instance::resolve(tcx, param_env, def_id, args) {
             Ok(Some(instance)) => instance,
             instance => bug!(
                 "failed to resolve instance for {}: {instance:#?}",
-                tcx.def_path_str_with_substs(def_id, substs)
+                tcx.def_path_str_with_args(def_id, args)
             ),
         }
     }
@@ -421,12 +421,12 @@ impl<'tcx> Instance<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         def_id: DefId,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) -> Option<Instance<'tcx>> {
-        debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
+        debug!("resolve(def_id={:?}, args={:?})", def_id, args);
         // Use either `resolve_closure` or `resolve_for_vtable`
         assert!(!tcx.is_closure(def_id), "Called `resolve_for_fn_ptr` on closure: {:?}", def_id);
-        Instance::resolve(tcx, param_env, def_id, substs).ok().flatten().map(|mut resolved| {
+        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) => {
                     debug!(" => fn pointer created for function with #[track_caller]");
@@ -447,18 +447,18 @@ impl<'tcx> Instance<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         def_id: DefId,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) -> Option<Instance<'tcx>> {
-        debug!("resolve_for_vtable(def_id={:?}, substs={:?})", def_id, substs);
-        let fn_sig = tcx.fn_sig(def_id).subst_identity();
+        debug!("resolve_for_vtable(def_id={:?}, args={:?})", def_id, args);
+        let fn_sig = tcx.fn_sig(def_id).instantiate_identity();
         let is_vtable_shim = !fn_sig.inputs().skip_binder().is_empty()
             && fn_sig.input(0).skip_binder().is_param(0)
             && tcx.generics_of(def_id).has_self;
         if is_vtable_shim {
             debug!(" => associated item with unsizeable self: Self");
-            Some(Instance { def: InstanceDef::VTableShim(def_id), substs })
+            Some(Instance { def: InstanceDef::VTableShim(def_id), args })
         } else {
-            Instance::resolve(tcx, param_env, def_id, substs).ok().flatten().map(|mut resolved| {
+            Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
                 match resolved.def {
                     InstanceDef::Item(def) => {
                         // We need to generate a shim when we cannot guarantee that
@@ -489,12 +489,12 @@ impl<'tcx> Instance<'tcx> {
                         {
                             if tcx.is_closure(def) {
                                 debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}",
-                                       def, def_id, substs);
+                                       def, def_id, args);
 
                                 // Create a shim for the `FnOnce/FnMut/Fn` method we are calling
                                 // - unlike functions, invoking a closure always goes through a
                                 // trait.
-                                resolved = Instance { def: InstanceDef::ReifyShim(def_id), substs };
+                                resolved = Instance { def: InstanceDef::ReifyShim(def_id), args };
                             } else {
                                 debug!(
                                     " => vtable fn pointer created for function with #[track_caller]: {:?}", def
@@ -518,28 +518,28 @@ impl<'tcx> Instance<'tcx> {
     pub fn resolve_closure(
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-        substs: ty::SubstsRef<'tcx>,
+        args: ty::GenericArgsRef<'tcx>,
         requested_kind: ty::ClosureKind,
     ) -> Option<Instance<'tcx>> {
-        let actual_kind = substs.as_closure().kind();
+        let actual_kind = args.as_closure().kind();
 
         match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
-            Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs),
-            _ => Some(Instance::new(def_id, substs)),
+            Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, args),
+            _ => Some(Instance::new(def_id, args)),
         }
     }
 
     pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
         let def_id = tcx.require_lang_item(LangItem::DropInPlace, None);
-        let substs = tcx.mk_substs(&[ty.into()]);
-        Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs)
+        let args = tcx.mk_args(&[ty.into()]);
+        Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args)
     }
 
     #[instrument(level = "debug", skip(tcx), ret)]
     pub fn fn_once_adapter_instance(
         tcx: TyCtxt<'tcx>,
         closure_did: DefId,
-        substs: ty::SubstsRef<'tcx>,
+        args: ty::GenericArgsRef<'tcx>,
     ) -> Option<Instance<'tcx>> {
         let fn_once = tcx.require_lang_item(LangItem::FnOnce, None);
         let call_once = tcx
@@ -552,30 +552,30 @@ impl<'tcx> Instance<'tcx> {
             tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER);
         let def = ty::InstanceDef::ClosureOnceShim { call_once, track_caller };
 
-        let self_ty = Ty::new_closure(tcx, closure_did, substs);
+        let self_ty = Ty::new_closure(tcx, closure_did, args);
 
-        let sig = substs.as_closure().sig();
+        let sig = args.as_closure().sig();
         let sig =
             tcx.try_normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig).ok()?;
         assert_eq!(sig.inputs().len(), 1);
-        let substs = tcx.mk_substs_trait(self_ty, [sig.inputs()[0].into()]);
+        let args = tcx.mk_args_trait(self_ty, [sig.inputs()[0].into()]);
 
         debug!(?self_ty, ?sig);
-        Some(Instance { def, substs })
+        Some(Instance { def, args })
     }
 
     /// 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
-    /// values from the substs when monomorphizing the function body. But in the latter case, we
+    /// 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.
     ///
-    /// This function returns `Some(substs)` in the former case and `None` otherwise -- i.e., if
+    /// 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
     /// codegen.
-    fn substs_for_mir_body(&self) -> Option<SubstsRef<'tcx>> {
-        self.def.has_polymorphic_mir_body().then_some(self.substs)
+    fn args_for_mir_body(&self) -> Option<GenericArgsRef<'tcx>> {
+        self.def.has_polymorphic_mir_body().then_some(self.args)
     }
 
     pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
@@ -583,10 +583,10 @@ impl<'tcx> Instance<'tcx> {
         T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
         let v = v.map_bound(|v| *v);
-        if let Some(substs) = self.substs_for_mir_body() {
-            v.subst(tcx, substs)
+        if let Some(args) = self.args_for_mir_body() {
+            v.instantiate(tcx, args)
         } else {
-            v.subst_identity()
+            v.instantiate_identity()
         }
     }
 
@@ -600,8 +600,8 @@ impl<'tcx> Instance<'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>> + Clone,
     {
-        if let Some(substs) = self.substs_for_mir_body() {
-            tcx.subst_and_normalize_erasing_regions(substs, param_env, v)
+        if let Some(args) = self.args_for_mir_body() {
+            tcx.subst_and_normalize_erasing_regions(args, param_env, v)
         } else {
             tcx.normalize_erasing_regions(param_env, v.skip_binder())
         }
@@ -617,14 +617,14 @@ impl<'tcx> Instance<'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>> + Clone,
     {
-        if let Some(substs) = self.substs_for_mir_body() {
-            tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v)
+        if let Some(args) = self.args_for_mir_body() {
+            tcx.try_subst_and_normalize_erasing_regions(args, param_env, v)
         } else {
             tcx.try_normalize_erasing_regions(param_env, v.skip_binder())
         }
     }
 
-    /// Returns a new `Instance` where generic parameters in `instance.substs` are replaced by
+    /// Returns a new `Instance` where generic parameters in `instance.args` are replaced by
     /// identity parameters if they are determined to be unused in `instance.def`.
     pub fn polymorphize(self, tcx: TyCtxt<'tcx>) -> Self {
         debug!("polymorphize: running polymorphization analysis");
@@ -632,18 +632,18 @@ impl<'tcx> Instance<'tcx> {
             return self;
         }
 
-        let polymorphized_substs = polymorphize(tcx, self.def, self.substs);
-        debug!("polymorphize: self={:?} polymorphized_substs={:?}", self, polymorphized_substs);
-        Self { def: self.def, substs: polymorphized_substs }
+        let polymorphized_args = polymorphize(tcx, self.def, self.args);
+        debug!("polymorphize: self={:?} polymorphized_args={:?}", self, polymorphized_args);
+        Self { def: self.def, args: polymorphized_args }
     }
 }
 
 fn polymorphize<'tcx>(
     tcx: TyCtxt<'tcx>,
     instance: ty::InstanceDef<'tcx>,
-    substs: SubstsRef<'tcx>,
-) -> SubstsRef<'tcx> {
-    debug!("polymorphize({:?}, {:?})", instance, substs);
+    args: GenericArgsRef<'tcx>,
+) -> GenericArgsRef<'tcx> {
+    debug!("polymorphize({:?}, {:?})", instance, args);
     let unused = tcx.unused_generic_params(instance);
     debug!("polymorphize: unused={:?}", unused);
 
@@ -653,9 +653,9 @@ fn polymorphize<'tcx>(
     // multiple mono items (and eventually symbol clashes).
     let def_id = instance.def_id();
     let upvars_ty = if tcx.is_closure(def_id) {
-        Some(substs.as_closure().tupled_upvars_ty())
+        Some(args.as_closure().tupled_upvars_ty())
     } else if tcx.type_of(def_id).skip_binder().is_generator() {
-        Some(substs.as_generator().tupled_upvars_ty())
+        Some(args.as_generator().tupled_upvars_ty())
     } else {
         None
     };
@@ -674,22 +674,22 @@ fn polymorphize<'tcx>(
         fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
             debug!("fold_ty: ty={:?}", ty);
             match *ty.kind() {
-                ty::Closure(def_id, substs) => {
-                    let polymorphized_substs =
-                        polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs);
-                    if substs == polymorphized_substs {
+                ty::Closure(def_id, args) => {
+                    let polymorphized_args =
+                        polymorphize(self.tcx, ty::InstanceDef::Item(def_id), args);
+                    if args == polymorphized_args {
                         ty
                     } else {
-                        Ty::new_closure(self.tcx, def_id, polymorphized_substs)
+                        Ty::new_closure(self.tcx, def_id, polymorphized_args)
                     }
                 }
-                ty::Generator(def_id, substs, movability) => {
-                    let polymorphized_substs =
-                        polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs);
-                    if substs == polymorphized_substs {
+                ty::Generator(def_id, args, movability) => {
+                    let polymorphized_args =
+                        polymorphize(self.tcx, ty::InstanceDef::Item(def_id), args);
+                    if args == polymorphized_args {
                         ty
                     } else {
-                        Ty::new_generator(self.tcx, def_id, polymorphized_substs, movability)
+                        Ty::new_generator(self.tcx, def_id, polymorphized_args, movability)
                     }
                 }
                 _ => ty.super_fold_with(self),
@@ -697,7 +697,7 @@ fn polymorphize<'tcx>(
         }
     }
 
-    InternalSubsts::for_item(tcx, def_id, |param, _| {
+    GenericArgs::for_item(tcx, def_id, |param, _| {
         let is_unused = unused.is_unused(param.index);
         debug!("polymorphize: param={:?} is_unused={:?}", param, is_unused);
         match param.kind {
@@ -706,7 +706,7 @@ fn polymorphize<'tcx>(
                 // ..and has upvars..
                 has_upvars &&
                 // ..and this param has the same type as the tupled upvars..
-                upvars_ty == Some(substs[param.index as usize].expect_ty()) => {
+                upvars_ty == Some(args[param.index as usize].expect_ty()) => {
                     // ..then double-check that polymorphization marked it used..
                     debug_assert!(!is_unused);
                     // ..and polymorphize any closures/generators captured as upvars.
@@ -725,7 +725,7 @@ fn polymorphize<'tcx>(
                     tcx.mk_param_from_def(param),
 
             // Otherwise, use the parameter as before.
-            _ => substs[param.index as usize],
+            _ => args[param.index as usize],
         }
     })
 }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index d95b05ef754..61d95e64c9c 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -374,7 +374,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
                 }
             }
 
-            ty::Adt(def, substs) => {
+            ty::Adt(def, args) => {
                 // Only newtypes and enums w/ nullable pointer optimization.
                 if def.is_union() || def.variants().is_empty() || def.variants().len() > 2 {
                     return Err(err);
@@ -385,7 +385,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
                     let i = VariantIdx::from_usize(i);
                     let fields =
                         def.variant(i).fields.iter().map(|field| {
-                            SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env)
+                            SizeSkeleton::compute(field.ty(tcx, args), tcx, param_env)
                         });
                     let mut ptr = None;
                     for field in fields {
@@ -861,9 +861,9 @@ where
                         // offers better information than `std::ptr::metadata::VTable`,
                         // and we rely on this layout information to trigger a panic in
                         // `std::mem::uninitialized::<&dyn Trait>()`, for example.
-                        if let ty::Adt(def, substs) = metadata.kind()
+                        if let ty::Adt(def, args) = metadata.kind()
                             && Some(def.did()) == tcx.lang_items().dyn_metadata()
-                            && substs.type_at(0).is_trait()
+                            && args.type_at(0).is_trait()
                         {
                             mk_dyn_vtable()
                         } else {
@@ -885,16 +885,15 @@ where
                 ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8),
 
                 // Tuples, generators and closures.
-                ty::Closure(_, ref substs) => field_ty_or_layout(
-                    TyAndLayout { ty: substs.as_closure().tupled_upvars_ty(), ..this },
+                ty::Closure(_, ref args) => field_ty_or_layout(
+                    TyAndLayout { ty: args.as_closure().tupled_upvars_ty(), ..this },
                     cx,
                     i,
                 ),
 
-                ty::Generator(def_id, ref substs, _) => match this.variants {
+                ty::Generator(def_id, ref args, _) => match this.variants {
                     Variants::Single { index } => TyMaybeWithLayout::Ty(
-                        substs
-                            .as_generator()
+                        args.as_generator()
                             .state_tys(def_id, tcx)
                             .nth(index.as_usize())
                             .unwrap()
@@ -905,18 +904,18 @@ where
                         if i == tag_field {
                             return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
                         }
-                        TyMaybeWithLayout::Ty(substs.as_generator().prefix_tys().nth(i).unwrap())
+                        TyMaybeWithLayout::Ty(args.as_generator().prefix_tys().nth(i).unwrap())
                     }
                 },
 
                 ty::Tuple(tys) => TyMaybeWithLayout::Ty(tys[i]),
 
                 // ADTs.
-                ty::Adt(def, substs) => {
+                ty::Adt(def, args) => {
                     match this.variants {
                         Variants::Single { index } => {
                             let field = &def.variant(index).fields[FieldIdx::from_usize(i)];
-                            TyMaybeWithLayout::Ty(field.ty(tcx, substs))
+                            TyMaybeWithLayout::Ty(field.ty(tcx, args))
                         }
 
                         // Discriminant field for enums (where applicable).
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index f23ea986d55..0411890ab51 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -28,6 +28,7 @@ use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::util::Discr;
 pub use adt::*;
 pub use assoc::*;
+pub use generic_args::*;
 pub use generics::*;
 use rustc_ast as ast;
 use rustc_ast::node_id::NodeMap;
@@ -54,7 +55,6 @@ use rustc_span::{ExpnId, ExpnKind, Span};
 use rustc_target::abi::{Align, FieldIdx, Integer, IntegerType, VariantIdx};
 pub use rustc_target::abi::{ReprFlags, ReprOptions};
 pub use rustc_type_ir::{DebugWithInfcx, InferCtxtLike, OptWithInfcx};
-pub use subst::*;
 pub use vtable::*;
 
 use std::fmt::Debug;
@@ -97,12 +97,12 @@ pub use self::rvalue_scopes::RvalueScopes;
 pub use self::sty::BoundRegionKind::*;
 pub use self::sty::{
     AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar,
-    BoundVariableKind, CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstKind, ConstVid,
+    BoundVariableKind, CanonicalPolyFnSig, ClosureArgs, ClosureArgsParts, ConstKind, ConstVid,
     EarlyBoundRegion, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig,
-    FreeRegion, GenSig, GeneratorSubsts, GeneratorSubstsParts, InlineConstSubsts,
-    InlineConstSubstsParts, ParamConst, ParamTy, PolyExistentialPredicate,
-    PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef,
-    Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts, VarianceDiagInfo,
+    FreeRegion, GenSig, GeneratorArgs, GeneratorArgsParts, InlineConstArgs, InlineConstArgsParts,
+    ParamConst, ParamTy, PolyExistentialPredicate, PolyExistentialProjection,
+    PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, Region, RegionKind, RegionVid,
+    TraitRef, TyKind, TypeAndMut, UpvarArgs, VarianceDiagInfo,
 };
 pub use self::trait_def::TraitDef;
 pub use self::typeck_results::{
@@ -126,7 +126,6 @@ pub mod layout;
 pub mod normalize_erasing_regions;
 pub mod print;
 pub mod relate;
-pub mod subst;
 pub mod trait_def;
 pub mod util;
 pub mod visit;
@@ -140,6 +139,7 @@ mod consts;
 mod context;
 mod diagnostics;
 mod erase_regions;
+mod generic_args;
 mod generics;
 mod impls_ty;
 mod instance;
@@ -676,9 +676,9 @@ pub enum PredicateKind<'tcx> {
     ObjectSafe(DefId),
 
     /// No direct syntax. May be thought of as `where T: FnFoo<...>`
-    /// for some substitutions `...` and `T` being a closure type.
+    /// for some generic args `...` and `T` being a closure type.
     /// Satisfied (or refuted) once we know the closure's kind.
-    ClosureKind(DefId, SubstsRef<'tcx>, ClosureKind),
+    ClosureKind(DefId, GenericArgsRef<'tcx>, ClosureKind),
 
     /// `T1 <: T2`
     ///
@@ -813,15 +813,15 @@ impl<'tcx> Clause<'tcx> {
         // this trick achieves that).
 
         // Working through the second example:
-        // trait_ref: for<'x> T: Foo1<'^0.0>; substs: [T, '^0.0]
-        // predicate: for<'b> Self: Bar1<'a, '^0.0>; substs: [Self, 'a, '^0.0]
+        // trait_ref: for<'x> T: Foo1<'^0.0>; args: [T, '^0.0]
+        // predicate: for<'b> Self: Bar1<'a, '^0.0>; args: [Self, 'a, '^0.0]
         // We want to end up with:
         //     for<'x, 'b> T: Bar1<'^0.0, '^0.1>
         // To do this:
         // 1) We must shift all bound vars in predicate by the length
         //    of trait ref's bound vars. So, we would end up with predicate like
         //    Self: Bar1<'a, '^0.1>
-        // 2) We can then apply the trait substs to this, ending up with
+        // 2) We can then apply the trait args to this, ending up with
         //    T: Bar1<'^0.0, '^0.1>
         // 3) Finally, to create the final bound vars, we concatenate the bound
         //    vars of the trait ref with those of the predicate:
@@ -833,7 +833,7 @@ impl<'tcx> Clause<'tcx> {
         let shifted_pred =
             tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
         // 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1>
-        let new = EarlyBinder::bind(shifted_pred).subst(tcx, trait_ref.skip_binder().substs);
+        let new = EarlyBinder::bind(shifted_pred).instantiate(tcx, trait_ref.skip_binder().args);
         // 3) ['x] + ['b] -> ['x, 'b]
         let bound_vars =
             tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
@@ -1079,7 +1079,7 @@ impl<'tcx> Term<'tcx> {
                 _ => None,
             },
             TermKind::Const(ct) => match ct.kind() {
-                ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def, uv.substs)),
+                ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def, uv.args)),
                 _ => None,
             },
         }
@@ -1558,7 +1558,7 @@ impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
 #[derive(TypeFoldable, TypeVisitable)]
 pub struct OpaqueTypeKey<'tcx> {
     pub def_id: LocalDefId,
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
 }
 
 #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
@@ -1629,21 +1629,21 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
         // typeck errors have subpar spans for opaque types, so delay error reporting until borrowck.
         ignore_errors: bool,
     ) -> Self {
-        let OpaqueTypeKey { def_id, substs } = opaque_type_key;
+        let OpaqueTypeKey { def_id, args } = opaque_type_key;
 
-        // Use substs to build up a reverse map from regions to their
+        // Use args to build up a reverse map from regions to their
         // identity mappings. This is necessary because of `impl
         // Trait` lifetimes are computed by replacing existing
         // lifetimes with 'static and remapping only those used in the
         // `impl Trait` return type, resulting in the parameters
         // shifting.
-        let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
-        debug!(?id_substs);
+        let id_args = GenericArgs::identity_for_item(tcx, def_id);
+        debug!(?id_args);
 
-        // This zip may have several times the same lifetime in `substs` paired with a different
-        // lifetime from `id_substs`. Simply `collect`ing the iterator is the correct behaviour:
+        // This zip may have several times the same lifetime in `args` paired with a different
+        // lifetime from `id_args`. Simply `collect`ing the iterator is the correct behaviour:
         // it will pick the last one, which is the one we introduced in the impl-trait desugaring.
-        let map = substs.iter().zip(id_substs).collect();
+        let map = args.iter().zip(id_args).collect();
         debug!("map = {:#?}", map);
 
         // Convert the type from the function into a type valid outside
@@ -2164,10 +2164,10 @@ impl Hash for FieldDef {
 }
 
 impl<'tcx> FieldDef {
-    /// Returns the type of this field. The resulting type is not normalized. The `subst` is
+    /// Returns the type of this field. The resulting type is not normalized. The `arg` is
     /// typically obtained via the second field of [`TyKind::Adt`].
-    pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
-        tcx.type_of(self.did).subst(tcx, subst)
+    pub fn ty(&self, tcx: TyCtxt<'tcx>, arg: GenericArgsRef<'tcx>) -> Ty<'tcx> {
+        tcx.type_of(self.did).instantiate(tcx, arg)
     }
 
     /// Computes the `Ident` of this variant by looking up the `Span`
@@ -2391,8 +2391,8 @@ impl<'tcx> TyCtxt<'tcx> {
         let impl_trait_ref2 = self.impl_trait_ref(def_id2);
         // If either trait impl references an error, they're allowed to overlap,
         // as one of them essentially doesn't exist.
-        if impl_trait_ref1.is_some_and(|tr| tr.subst_identity().references_error())
-            || impl_trait_ref2.is_some_and(|tr| tr.subst_identity().references_error())
+        if impl_trait_ref1.is_some_and(|tr| tr.instantiate_identity().references_error())
+            || impl_trait_ref2.is_some_and(|tr| tr.instantiate_identity().references_error())
         {
             return Some(ImplOverlapKind::Permitted { marker: false });
         }
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index a0c8d299f48..3c2c4483c73 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -9,7 +9,7 @@
 
 use crate::traits::query::NoSolution;
 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder};
-use crate::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt, TypeVisitableExt};
+use crate::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
 
 #[derive(Debug, Copy, Clone, HashStable, TyEncodable, TyDecodable)]
 pub enum NormalizationError<'tcx> {
@@ -137,7 +137,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// use `try_subst_and_normalize_erasing_regions` instead.
     pub fn subst_and_normalize_erasing_regions<T>(
         self,
-        param_substs: SubstsRef<'tcx>,
+        param_args: GenericArgsRef<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         value: EarlyBinder<T>,
     ) -> T
@@ -146,12 +146,12 @@ impl<'tcx> TyCtxt<'tcx> {
     {
         debug!(
             "subst_and_normalize_erasing_regions(\
-             param_substs={:?}, \
+             param_args={:?}, \
              value={:?}, \
              param_env={:?})",
-            param_substs, value, param_env,
+            param_args, value, param_env,
         );
-        let substituted = value.subst(self, param_substs);
+        let substituted = value.instantiate(self, param_args);
         self.normalize_erasing_regions(param_env, substituted)
     }
 
@@ -161,7 +161,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// not assume that normalization succeeds.
     pub fn try_subst_and_normalize_erasing_regions<T>(
         self,
-        param_substs: SubstsRef<'tcx>,
+        param_args: GenericArgsRef<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         value: EarlyBinder<T>,
     ) -> Result<T, NormalizationError<'tcx>>
@@ -170,12 +170,12 @@ impl<'tcx> TyCtxt<'tcx> {
     {
         debug!(
             "subst_and_normalize_erasing_regions(\
-             param_substs={:?}, \
+             param_args={:?}, \
              value={:?}, \
              param_env={:?})",
-            param_substs, value, param_env,
+            param_args, value, param_env,
         );
-        let substituted = value.subst(self, param_substs);
+        let substituted = value.instantiate(self, param_args);
         self.try_normalize_erasing_regions(param_env, substituted)
     }
 }
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index b10921eff08..7ae8be2dab3 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -1,7 +1,7 @@
 use crate::error::ConstNotUsedTraitAlias;
 use crate::ty::fold::{TypeFolder, TypeSuperFoldable};
-use crate::ty::subst::{GenericArg, GenericArgKind};
 use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{GenericArg, GenericArgKind};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_span::def_id::DefId;
 use rustc_span::Span;
@@ -49,11 +49,11 @@ impl<'tcx> ReverseMapper<'tcx> {
         kind.fold_with(self)
     }
 
-    fn fold_closure_substs(
+    fn fold_closure_args(
         &mut self,
         def_id: DefId,
-        substs: ty::SubstsRef<'tcx>,
-    ) -> ty::SubstsRef<'tcx> {
+        args: ty::GenericArgsRef<'tcx>,
+    ) -> ty::GenericArgsRef<'tcx> {
         // I am a horrible monster and I pray for death. When
         // we encounter a closure here, it is always a closure
         // from within the function that we are currently
@@ -79,7 +79,7 @@ impl<'tcx> ReverseMapper<'tcx> {
         // during codegen.
 
         let generics = self.tcx.generics_of(def_id);
-        self.tcx.mk_substs_from_iter(substs.iter().enumerate().map(|(index, kind)| {
+        self.tcx.mk_args_from_iter(args.iter().enumerate().map(|(index, kind)| {
             if index < generics.parent_count {
                 // Accommodate missing regions in the parent kinds...
                 self.fold_kind_no_missing_regions_error(kind)
@@ -148,19 +148,19 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
         match *ty.kind() {
-            ty::Closure(def_id, substs) => {
-                let substs = self.fold_closure_substs(def_id, substs);
-                Ty::new_closure(self.tcx, def_id, substs)
+            ty::Closure(def_id, args) => {
+                let args = self.fold_closure_args(def_id, args);
+                Ty::new_closure(self.tcx, def_id, args)
             }
 
-            ty::Generator(def_id, substs, movability) => {
-                let substs = self.fold_closure_substs(def_id, substs);
-                Ty::new_generator(self.tcx, def_id, substs, movability)
+            ty::Generator(def_id, args, movability) => {
+                let args = self.fold_closure_args(def_id, args);
+                Ty::new_generator(self.tcx, def_id, args, movability)
             }
 
-            ty::GeneratorWitnessMIR(def_id, substs) => {
-                let substs = self.fold_closure_substs(def_id, substs);
-                Ty::new_generator_witness_mir(self.tcx, def_id, substs)
+            ty::GeneratorWitnessMIR(def_id, args) => {
+                let args = self.fold_closure_args(def_id, args);
+                Ty::new_generator_witness_mir(self.tcx, def_id, args)
             }
 
             ty::Param(param) => {
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 2de0a3f75dc..83a75d0c6b9 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -42,19 +42,19 @@ pub trait Printer<'tcx>: Sized {
     fn print_def_path(
         self,
         def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
+        args: &'tcx [GenericArg<'tcx>],
     ) -> Result<Self::Path, Self::Error> {
-        self.default_print_def_path(def_id, substs)
+        self.default_print_def_path(def_id, args)
     }
 
     fn print_impl_path(
         self,
         impl_def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
+        args: &'tcx [GenericArg<'tcx>],
         self_ty: Ty<'tcx>,
         trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<Self::Path, Self::Error> {
-        self.default_print_impl_path(impl_def_id, substs, self_ty, trait_ref)
+        self.default_print_impl_path(impl_def_id, args, self_ty, trait_ref)
     }
 
     fn print_region(self, region: ty::Region<'tcx>) -> Result<Self::Region, Self::Error>;
@@ -102,7 +102,7 @@ pub trait Printer<'tcx>: Sized {
     fn default_print_def_path(
         self,
         def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
+        args: &'tcx [GenericArg<'tcx>],
     ) -> Result<Self::Path, Self::Error> {
         let key = self.tcx().def_key(def_id);
         debug!(?key);
@@ -117,25 +117,28 @@ pub trait Printer<'tcx>: Sized {
                 let generics = self.tcx().generics_of(def_id);
                 let self_ty = self.tcx().type_of(def_id);
                 let impl_trait_ref = self.tcx().impl_trait_ref(def_id);
-                let (self_ty, impl_trait_ref) = if substs.len() >= generics.count() {
+                let (self_ty, impl_trait_ref) = if args.len() >= generics.count() {
                     (
-                        self_ty.subst(self.tcx(), substs),
-                        impl_trait_ref.map(|i| i.subst(self.tcx(), substs)),
+                        self_ty.instantiate(self.tcx(), args),
+                        impl_trait_ref.map(|i| i.instantiate(self.tcx(), args)),
                     )
                 } else {
-                    (self_ty.subst_identity(), impl_trait_ref.map(|i| i.subst_identity()))
+                    (
+                        self_ty.instantiate_identity(),
+                        impl_trait_ref.map(|i| i.instantiate_identity()),
+                    )
                 };
-                self.print_impl_path(def_id, substs, self_ty, impl_trait_ref)
+                self.print_impl_path(def_id, args, self_ty, impl_trait_ref)
             }
 
             _ => {
                 let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
 
-                let mut parent_substs = substs;
+                let mut parent_args = args;
                 let mut trait_qualify_parent = false;
-                if !substs.is_empty() {
+                if !args.is_empty() {
                     let generics = self.tcx().generics_of(def_id);
-                    parent_substs = &substs[..generics.parent_count.min(substs.len())];
+                    parent_args = &args[..generics.parent_count.min(args.len())];
 
                     match key.disambiguated_data.data {
                         // Closures' own generics are only captures, don't print them.
@@ -148,10 +151,10 @@ pub trait Printer<'tcx>: Sized {
                         // If we have any generic arguments to print, we do that
                         // on top of the same path, but without its own generics.
                         _ => {
-                            if !generics.params.is_empty() && substs.len() >= generics.count() {
-                                let args = generics.own_substs_no_defaults(self.tcx(), substs);
+                            if !generics.params.is_empty() && args.len() >= generics.count() {
+                                let args = generics.own_args_no_defaults(self.tcx(), args);
                                 return self.path_generic_args(
-                                    |cx| cx.print_def_path(def_id, parent_substs),
+                                    |cx| cx.print_def_path(def_id, parent_args),
                                     args,
                                 );
                             }
@@ -162,7 +165,7 @@ pub trait Printer<'tcx>: Sized {
                     // logic, instead of doing it when printing the child.
                     trait_qualify_parent = generics.has_self
                         && generics.parent == Some(parent_def_id)
-                        && parent_substs.len() == generics.parent_count
+                        && parent_args.len() == generics.parent_count
                         && self.tcx().generics_of(parent_def_id).parent_count == 0;
                 }
 
@@ -172,11 +175,11 @@ pub trait Printer<'tcx>: Sized {
                             let trait_ref = ty::TraitRef::new(
                                 cx.tcx(),
                                 parent_def_id,
-                                parent_substs.iter().copied(),
+                                parent_args.iter().copied(),
                             );
                             cx.path_qualified(trait_ref.self_ty(), Some(trait_ref))
                         } else {
-                            cx.print_def_path(parent_def_id, parent_substs)
+                            cx.print_def_path(parent_def_id, parent_args)
                         }
                     },
                     &key.disambiguated_data,
@@ -188,7 +191,7 @@ pub trait Printer<'tcx>: Sized {
     fn default_print_impl_path(
         self,
         impl_def_id: DefId,
-        _substs: &'tcx [GenericArg<'tcx>],
+        _args: &'tcx [GenericArg<'tcx>],
         self_ty: Ty<'tcx>,
         impl_trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<Self::Path, Self::Error> {
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 96cf36eb996..3591acdea56 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -224,9 +224,9 @@ pub trait PrettyPrinter<'tcx>:
     fn print_value_path(
         self,
         def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
+        args: &'tcx [GenericArg<'tcx>],
     ) -> Result<Self::Path, Self::Error> {
-        self.print_def_path(def_id, substs)
+        self.print_def_path(def_id, args)
     }
 
     fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error>
@@ -679,12 +679,12 @@ pub trait PrettyPrinter<'tcx>:
                 }
                 p!(")")
             }
-            ty::FnDef(def_id, substs) => {
+            ty::FnDef(def_id, args) => {
                 if with_no_queries() {
-                    p!(print_def_path(def_id, substs));
+                    p!(print_def_path(def_id, args));
                 } else {
-                    let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs);
-                    p!(print(sig), " {{", print_value_path(def_id, substs), "}}");
+                    let sig = self.tcx().fn_sig(def_id).instantiate(self.tcx(), args);
+                    p!(print(sig), " {{", print_value_path(def_id, args), "}}");
                 }
             }
             ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
@@ -715,8 +715,8 @@ pub trait PrettyPrinter<'tcx>:
                     false => p!(write("{s}")),
                 },
             },
-            ty::Adt(def, substs) => {
-                p!(print_def_path(def.did(), substs));
+            ty::Adt(def, args) => {
+                p!(print_def_path(def.did(), args));
             }
             ty::Dynamic(data, r, repr) => {
                 let print_r = self.should_print_region(r);
@@ -739,7 +739,7 @@ pub trait PrettyPrinter<'tcx>:
                 if !(self.should_print_verbose() || with_no_queries())
                     && self.tcx().is_impl_trait_in_trait(data.def_id)
                 {
-                    return self.pretty_print_opaque_impl_type(data.def_id, data.substs);
+                    return self.pretty_print_opaque_impl_type(data.def_id, data.args);
                 } else {
                     p!(print(data))
                 }
@@ -751,7 +751,7 @@ pub trait PrettyPrinter<'tcx>:
                     false => p!(write("{name}")),
                 },
             },
-            ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
+            ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
                 // We use verbose printing in 'NO_QUERIES' mode, to
                 // avoid needing to call `predicates_of`. This should
                 // only affect certain debug messages (e.g. messages printed
@@ -759,7 +759,7 @@ pub trait PrettyPrinter<'tcx>:
                 // and should have no effect on any compiler output.
                 if self.should_print_verbose() {
                     // FIXME(eddyb) print this with `print_def_path`.
-                    p!(write("Opaque({:?}, {:?})", def_id, substs));
+                    p!(write("Opaque({:?}, {:?})", def_id, args));
                     return Ok(self);
                 }
 
@@ -769,17 +769,17 @@ pub trait PrettyPrinter<'tcx>:
                         // NOTE: I know we should check for NO_QUERIES here, but it's alright.
                         // `type_of` on a type alias or assoc type should never cause a cycle.
                         if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, .. }) =
-                            *self.tcx().type_of(parent).subst_identity().kind()
+                            *self.tcx().type_of(parent).instantiate_identity().kind()
                         {
                             if d == def_id {
                                 // If the type alias directly starts with the `impl` of the
                                 // opaque type we're printing, then skip the `::{opaque#1}`.
-                                p!(print_def_path(parent, substs));
+                                p!(print_def_path(parent, args));
                                 return Ok(self);
                             }
                         }
                         // Complex opaque type, e.g. `type Foo = (i32, impl Debug);`
-                        p!(print_def_path(def_id, substs));
+                        p!(print_def_path(def_id, args));
                         return Ok(self);
                     }
                     _ => {
@@ -787,13 +787,13 @@ pub trait PrettyPrinter<'tcx>:
                             p!(print_def_path(def_id, &[]));
                             return Ok(self);
                         } else {
-                            return self.pretty_print_opaque_impl_type(def_id, substs);
+                            return self.pretty_print_opaque_impl_type(def_id, args);
                         }
                     }
                 }
             }
             ty::Str => p!("str"),
-            ty::Generator(did, substs, movability) => {
+            ty::Generator(did, args, movability) => {
                 p!(write("["));
                 let generator_kind = self.tcx().generator_kind(did).unwrap();
                 let should_print_movability =
@@ -818,20 +818,20 @@ pub trait PrettyPrinter<'tcx>:
                             self.tcx().sess.source_map().span_to_embeddable_string(span)
                         ));
                     } else {
-                        p!(write("@"), print_def_path(did, substs));
+                        p!(write("@"), print_def_path(did, args));
                     }
                 } else {
-                    p!(print_def_path(did, substs));
+                    p!(print_def_path(did, args));
                     p!(" upvar_tys=(");
-                    if !substs.as_generator().is_valid() {
+                    if !args.as_generator().is_valid() {
                         p!("unavailable");
                     } else {
-                        self = self.comma_sep(substs.as_generator().upvar_tys())?;
+                        self = self.comma_sep(args.as_generator().upvar_tys())?;
                     }
                     p!(")");
 
-                    if substs.as_generator().is_valid() {
-                        p!(" ", print(substs.as_generator().witness()));
+                    if args.as_generator().is_valid() {
+                        p!(" ", print(args.as_generator().witness()));
                     }
                 }
 
@@ -840,7 +840,7 @@ pub trait PrettyPrinter<'tcx>:
             ty::GeneratorWitness(types) => {
                 p!(in_binder(&types));
             }
-            ty::GeneratorWitnessMIR(did, substs) => {
+            ty::GeneratorWitnessMIR(did, args) => {
                 p!(write("["));
                 if !self.tcx().sess.verbose() {
                     p!("generator witness");
@@ -854,22 +854,22 @@ pub trait PrettyPrinter<'tcx>:
                             self.tcx().sess.source_map().span_to_embeddable_string(span)
                         ));
                     } else {
-                        p!(write("@"), print_def_path(did, substs));
+                        p!(write("@"), print_def_path(did, args));
                     }
                 } else {
-                    p!(print_def_path(did, substs));
+                    p!(print_def_path(did, args));
                 }
 
                 p!("]")
             }
-            ty::Closure(did, substs) => {
+            ty::Closure(did, args) => {
                 p!(write("["));
                 if !self.should_print_verbose() {
                     p!(write("closure"));
                     // FIXME(eddyb) should use `def_span`.
                     if let Some(did) = did.as_local() {
                         if self.tcx().sess.opts.unstable_opts.span_free_formats {
-                            p!("@", print_def_path(did.to_def_id(), substs));
+                            p!("@", print_def_path(did.to_def_id(), args));
                         } else {
                             let span = self.tcx().def_span(did);
                             let preference = if FORCE_TRIMMED_PATH.with(|flag| flag.get()) {
@@ -885,21 +885,21 @@ pub trait PrettyPrinter<'tcx>:
                             ));
                         }
                     } else {
-                        p!(write("@"), print_def_path(did, substs));
+                        p!(write("@"), print_def_path(did, args));
                     }
                 } else {
-                    p!(print_def_path(did, substs));
-                    if !substs.as_closure().is_valid() {
-                        p!(" closure_substs=(unavailable)");
-                        p!(write(" substs={:?}", substs));
+                    p!(print_def_path(did, args));
+                    if !args.as_closure().is_valid() {
+                        p!(" closure_args=(unavailable)");
+                        p!(write(" args={:?}", args));
                     } else {
-                        p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
+                        p!(" closure_kind_ty=", print(args.as_closure().kind_ty()));
                         p!(
                             " closure_sig_as_fn_ptr_ty=",
-                            print(substs.as_closure().sig_as_fn_ptr_ty())
+                            print(args.as_closure().sig_as_fn_ptr_ty())
                         );
                         p!(" upvar_tys=(");
-                        self = self.comma_sep(substs.as_closure().upvar_tys())?;
+                        self = self.comma_sep(args.as_closure().upvar_tys())?;
                         p!(")");
                     }
                 }
@@ -915,7 +915,7 @@ pub trait PrettyPrinter<'tcx>:
     fn pretty_print_opaque_impl_type(
         mut self,
         def_id: DefId,
-        substs: &'tcx ty::List<ty::GenericArg<'tcx>>,
+        args: &'tcx ty::List<ty::GenericArg<'tcx>>,
     ) -> Result<Self::Type, Self::Error> {
         let tcx = self.tcx();
 
@@ -928,7 +928,7 @@ pub trait PrettyPrinter<'tcx>:
         let mut is_sized = false;
         let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new();
 
-        for (predicate, _) in bounds.subst_iter_copied(tcx, substs) {
+        for (predicate, _) in bounds.arg_iter_copied(tcx, args) {
             let bound_predicate = predicate.kind();
 
             match bound_predicate.skip_binder() {
@@ -978,9 +978,9 @@ pub trait PrettyPrinter<'tcx>:
                 define_scoped_cx!(cx);
                 // Get the (single) generic ty (the args) of this FnOnce trait ref.
                 let generics = tcx.generics_of(trait_ref.def_id);
-                let args = generics.own_substs_no_defaults(tcx, trait_ref.substs);
+                let own_args = generics.own_args_no_defaults(tcx, trait_ref.args);
 
-                match (entry.return_ty, args[0].expect_ty()) {
+                match (entry.return_ty, own_args[0].expect_ty()) {
                     // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
                     // a return type.
                     (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
@@ -1044,12 +1044,12 @@ pub trait PrettyPrinter<'tcx>:
                 p!(print(trait_ref.print_only_trait_name()));
 
                 let generics = tcx.generics_of(trait_ref.def_id);
-                let args = generics.own_substs_no_defaults(tcx, trait_ref.substs);
+                let own_args = generics.own_args_no_defaults(tcx, trait_ref.args);
 
-                if !args.is_empty() || !assoc_items.is_empty() {
+                if !own_args.is_empty() || !assoc_items.is_empty() {
                     let mut first = true;
 
-                    for ty in args {
+                    for ty in own_args {
                         if first {
                             p!("<");
                             first = false;
@@ -1068,8 +1068,8 @@ pub trait PrettyPrinter<'tcx>:
                             && assoc.trait_container(tcx) == tcx.lang_items().gen_trait()
                             && assoc.name == rustc_span::sym::Return
                         {
-                            if let ty::Generator(_, substs, _) = substs.type_at(0).kind() {
-                                let return_ty = substs.as_generator().return_ty();
+                            if let ty::Generator(_, args, _) = args.type_at(0).kind() {
+                                let return_ty = args.as_generator().return_ty();
                                 if !return_ty.is_ty_var() {
                                     return_ty.into()
                                 } else {
@@ -1182,7 +1182,7 @@ pub trait PrettyPrinter<'tcx>:
                     &def_key.disambiguated_data,
                 )
             },
-            &alias_ty.substs[1..],
+            &alias_ty.args[1..],
         )
     }
 
@@ -1211,7 +1211,7 @@ pub trait PrettyPrinter<'tcx>:
                 // Special-case `Fn(...) -> ...` and re-sugar it.
                 let fn_trait_kind = cx.tcx().fn_trait_kind_from_def_id(principal.def_id);
                 if !cx.should_print_verbose() && fn_trait_kind.is_some() {
-                    if let ty::Tuple(tys) = principal.substs.type_at(0).kind() {
+                    if let ty::Tuple(tys) = principal.args.type_at(0).kind() {
                         let mut projections = predicates.projection_bounds();
                         if let (Some(proj), None) = (projections.next(), projections.next()) {
                             p!(pretty_fn_sig(
@@ -1234,7 +1234,7 @@ pub trait PrettyPrinter<'tcx>:
                     let args = cx
                         .tcx()
                         .generics_of(principal.def_id)
-                        .own_substs_no_defaults(cx.tcx(), principal.substs);
+                        .own_args_no_defaults(cx.tcx(), principal.args);
 
                     let mut projections = predicates.projection_bounds();
 
@@ -1341,10 +1341,10 @@ pub trait PrettyPrinter<'tcx>:
         }
 
         match ct.kind() {
-            ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => {
+            ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
                 match self.tcx().def_kind(def) {
                     DefKind::Const | DefKind::AssocConst => {
-                        p!(print_value_path(def, substs))
+                        p!(print_value_path(def, args))
                     }
                     DefKind::AnonConst => {
                         if def.is_local()
@@ -1449,7 +1449,7 @@ pub trait PrettyPrinter<'tcx>:
                     self.tcx().try_get_global_alloc(alloc_id)
                 {
                     self = self.typed_value(
-                        |this| this.print_value_path(instance.def_id(), instance.substs),
+                        |this| this.print_value_path(instance.def_id(), instance.args),
                         |this| this.print_type(ty),
                         " as ",
                     )?;
@@ -1619,11 +1619,11 @@ pub trait PrettyPrinter<'tcx>:
                             ": ",
                         )?;
                     }
-                    ty::Adt(def, substs) => {
+                    ty::Adt(def, args) => {
                         let variant_idx =
                             contents.variant.expect("destructed const of adt without variant idx");
                         let variant_def = &def.variant(variant_idx);
-                        p!(print_value_path(variant_def.def_id, substs));
+                        p!(print_value_path(variant_def.def_id, args));
                         match variant_def.ctor_kind() {
                             Some(CtorKind::Const) => {}
                             Some(CtorKind::Fn) => {
@@ -1673,7 +1673,7 @@ pub trait PrettyPrinter<'tcx>:
 
     fn pretty_closure_as_impl(
         mut self,
-        closure: ty::ClosureSubsts<'tcx>,
+        closure: ty::ClosureArgs<'tcx>,
     ) -> Result<Self::Const, Self::Error> {
         let sig = closure.sig();
         let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn);
@@ -1798,29 +1798,29 @@ impl<'t> TyCtxt<'t> {
     /// Returns a string identifying this `DefId`. This string is
     /// suitable for user output.
     pub fn def_path_str(self, def_id: impl IntoQueryParam<DefId>) -> String {
-        self.def_path_str_with_substs(def_id, &[])
+        self.def_path_str_with_args(def_id, &[])
     }
 
-    pub fn def_path_str_with_substs(
+    pub fn def_path_str_with_args(
         self,
         def_id: impl IntoQueryParam<DefId>,
-        substs: &'t [GenericArg<'t>],
+        args: &'t [GenericArg<'t>],
     ) -> String {
         let def_id = def_id.into_query_param();
         let ns = guess_def_namespace(self, def_id);
         debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns);
-        FmtPrinter::new(self, ns).print_def_path(def_id, substs).unwrap().into_buffer()
+        FmtPrinter::new(self, ns).print_def_path(def_id, args).unwrap().into_buffer()
     }
 
-    pub fn value_path_str_with_substs(
+    pub fn value_path_str_with_args(
         self,
         def_id: impl IntoQueryParam<DefId>,
-        substs: &'t [GenericArg<'t>],
+        args: &'t [GenericArg<'t>],
     ) -> String {
         let def_id = def_id.into_query_param();
         let ns = guess_def_namespace(self, def_id);
         debug!("value_path_str: def_id={:?}, ns={:?}", def_id, ns);
-        FmtPrinter::new(self, ns).print_value_path(def_id, substs).unwrap().into_buffer()
+        FmtPrinter::new(self, ns).print_value_path(def_id, args).unwrap().into_buffer()
     }
 }
 
@@ -1847,11 +1847,11 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
     fn print_def_path(
         mut self,
         def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
+        args: &'tcx [GenericArg<'tcx>],
     ) -> Result<Self::Path, Self::Error> {
         define_scoped_cx!(self);
 
-        if substs.is_empty() {
+        if args.is_empty() {
             match self.try_print_trimmed_def_path(def_id)? {
                 (cx, true) => return Ok(cx),
                 (cx, false) => self = cx,
@@ -1900,7 +1900,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
             }
         }
 
-        self.default_print_def_path(def_id, substs)
+        self.default_print_def_path(def_id, args)
     }
 
     fn print_region(self, region: ty::Region<'tcx>) -> Result<Self::Region, Self::Error> {
@@ -2044,10 +2044,10 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
     fn print_value_path(
         mut self,
         def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
+        args: &'tcx [GenericArg<'tcx>],
     ) -> Result<Self::Path, Self::Error> {
         let was_in_value = std::mem::replace(&mut self.in_value, true);
-        self = self.print_def_path(def_id, substs)?;
+        self = self.print_def_path(def_id, args)?;
         self.in_value = was_in_value;
 
         Ok(self)
@@ -2695,7 +2695,7 @@ impl<'tcx> ty::PolyTraitPredicate<'tcx> {
 
 #[derive(Debug, Copy, Clone, Lift)]
 pub struct PrintClosureAsImpl<'tcx> {
-    pub closure: ty::ClosureSubsts<'tcx>,
+    pub closure: ty::ClosureArgs<'tcx>,
 }
 
 forward_display_to_print! {
@@ -2771,7 +2771,7 @@ define_print_and_forward_display! {
     }
 
     TraitRefPrintOnlyTraitPath<'tcx> {
-        p!(print_def_path(self.0.def_id, self.0.substs));
+        p!(print_def_path(self.0.def_id, self.0.args));
     }
 
     TraitRefPrintOnlyTraitName<'tcx> {
@@ -2842,7 +2842,7 @@ define_print_and_forward_display! {
         if let DefKind::Impl { of_trait: false } = cx.tcx().def_kind(cx.tcx().parent(self.def_id)) {
             p!(pretty_print_inherent_projection(self))
         } else {
-            p!(print_def_path(self.def_id, self.substs));
+            p!(print_def_path(self.def_id, self.args));
         }
     }
 
@@ -2891,7 +2891,7 @@ define_print_and_forward_display! {
             ty::PredicateKind::ObjectSafe(trait_def_id) => {
                 p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
             }
-            ty::PredicateKind::ClosureKind(closure_def_id, _closure_substs, kind) => p!(
+            ty::PredicateKind::ClosureKind(closure_def_id, _closure_args, kind) => p!(
                 "the closure `",
                 print_value_path(closure_def_id, &[]),
                 write("` implements the trait `{}`", kind)
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 54dedf31d9f..bf9adabdab1 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -6,7 +6,7 @@
 
 use crate::ty::error::{ExpectedFound, TypeError};
 use crate::ty::{self, Expr, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable};
-use crate::ty::{GenericArg, GenericArgKind, SubstsRef};
+use crate::ty::{GenericArg, GenericArgKind, GenericArgsRef};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_target::spec::abi;
@@ -43,23 +43,23 @@ pub trait TypeRelation<'tcx>: Sized {
         Relate::relate(self, a, b)
     }
 
-    /// Relate the two substitutions for the given item. The default
+    /// Relate the two args for the given item. The default
     /// is to look up the variance for the item and proceed
     /// accordingly.
-    fn relate_item_substs(
+    fn relate_item_args(
         &mut self,
         item_def_id: DefId,
-        a_subst: SubstsRef<'tcx>,
-        b_subst: SubstsRef<'tcx>,
-    ) -> RelateResult<'tcx, SubstsRef<'tcx>> {
+        a_arg: GenericArgsRef<'tcx>,
+        b_arg: GenericArgsRef<'tcx>,
+    ) -> RelateResult<'tcx, GenericArgsRef<'tcx>> {
         debug!(
-            "relate_item_substs(item_def_id={:?}, a_subst={:?}, b_subst={:?})",
-            item_def_id, a_subst, b_subst
+            "relate_item_args(item_def_id={:?}, a_arg={:?}, b_arg={:?})",
+            item_def_id, a_arg, b_arg
         );
 
         let tcx = self.tcx();
         let opt_variances = tcx.variances_of(item_def_id);
-        relate_substs_with_variances(self, item_def_id, opt_variances, a_subst, b_subst, true)
+        relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true)
     }
 
     /// Switch variance for the purpose of relating `a` and `b`.
@@ -134,31 +134,32 @@ pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>(
 }
 
 #[inline]
-pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>(
+pub fn relate_args<'tcx, R: TypeRelation<'tcx>>(
     relation: &mut R,
-    a_subst: SubstsRef<'tcx>,
-    b_subst: SubstsRef<'tcx>,
-) -> RelateResult<'tcx, SubstsRef<'tcx>> {
-    relation.tcx().mk_substs_from_iter(iter::zip(a_subst, b_subst).map(|(a, b)| {
+    a_arg: GenericArgsRef<'tcx>,
+    b_arg: GenericArgsRef<'tcx>,
+) -> RelateResult<'tcx, GenericArgsRef<'tcx>> {
+    relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| {
         relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)
     }))
 }
 
-pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>(
+pub fn relate_args_with_variances<'tcx, R: TypeRelation<'tcx>>(
     relation: &mut R,
     ty_def_id: DefId,
     variances: &[ty::Variance],
-    a_subst: SubstsRef<'tcx>,
-    b_subst: SubstsRef<'tcx>,
+    a_arg: GenericArgsRef<'tcx>,
+    b_arg: GenericArgsRef<'tcx>,
     fetch_ty_for_diag: bool,
-) -> RelateResult<'tcx, SubstsRef<'tcx>> {
+) -> RelateResult<'tcx, GenericArgsRef<'tcx>> {
     let tcx = relation.tcx();
 
     let mut cached_ty = None;
-    let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| {
+    let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| {
         let variance = variances[i];
         let variance_info = if variance == ty::Invariant && fetch_ty_for_diag {
-            let ty = *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).subst(tcx, a_subst));
+            let ty =
+                *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, a_arg));
             ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
         } else {
             ty::VarianceDiagInfo::default()
@@ -166,7 +167,7 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>(
         relation.relate_with_variance(variance, variance_info, a, b)
     });
 
-    tcx.mk_substs_from_iter(params)
+    tcx.mk_args_from_iter(params)
 }
 
 impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
@@ -272,8 +273,8 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> {
         if a.def_id != b.def_id {
             Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id)))
         } else {
-            let substs = relation.relate(a.substs, b.substs)?;
-            Ok(relation.tcx().mk_alias_ty(a.def_id, substs))
+            let args = relation.relate(a.args, b.args)?;
+            Ok(relation.tcx().mk_alias_ty(a.def_id, args))
         }
     }
 }
@@ -293,13 +294,13 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
                 a.term,
                 b.term,
             )?;
-            let substs = relation.relate_with_variance(
+            let args = relation.relate_with_variance(
                 ty::Invariant,
                 ty::VarianceDiagInfo::default(),
-                a.substs,
-                b.substs,
+                a.args,
+                b.args,
             )?;
-            Ok(ty::ExistentialProjection { def_id: a.def_id, substs, term })
+            Ok(ty::ExistentialProjection { def_id: a.def_id, args, term })
         }
     }
 }
@@ -314,8 +315,8 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
         if a.def_id != b.def_id {
             Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
         } else {
-            let substs = relate_substs(relation, a.substs, b.substs)?;
-            Ok(ty::TraitRef::new(relation.tcx(), a.def_id, substs))
+            let args = relate_args(relation, a.args, b.args)?;
+            Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args))
         }
     }
 }
@@ -330,8 +331,8 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
         if a.def_id != b.def_id {
             Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
         } else {
-            let substs = relate_substs(relation, a.substs, b.substs)?;
-            Ok(ty::ExistentialTraitRef { def_id: a.def_id, substs })
+            let args = relate_args(relation, a.args, b.args)?;
+            Ok(ty::ExistentialTraitRef { def_id: a.def_id, args })
         }
     }
 }
@@ -426,9 +427,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
 
         (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a),
 
-        (&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs)) if a_def == b_def => {
-            let substs = relation.relate_item_substs(a_def.did(), a_substs, b_substs)?;
-            Ok(Ty::new_adt(tcx, a_def, substs))
+        (&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args)) if a_def == b_def => {
+            let args = relation.relate_item_args(a_def.did(), a_args, b_args)?;
+            Ok(Ty::new_adt(tcx, a_def, args))
         }
 
         (&ty::Foreign(a_id), &ty::Foreign(b_id)) if a_id == b_id => Ok(Ty::new_foreign(tcx, a_id)),
@@ -442,14 +443,14 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
             Ok(Ty::new_dynamic(tcx, relation.relate(a_obj, b_obj)?, region_bound, a_repr))
         }
 
-        (&ty::Generator(a_id, a_substs, movability), &ty::Generator(b_id, b_substs, _))
+        (&ty::Generator(a_id, a_args, movability), &ty::Generator(b_id, b_args, _))
             if a_id == b_id =>
         {
             // All Generator types with the same id represent
             // the (anonymous) type of the same generator expression. So
             // all of their regions should be equated.
-            let substs = relation.relate(a_substs, b_substs)?;
-            Ok(Ty::new_generator(tcx, a_id, substs, movability))
+            let args = relation.relate(a_args, b_args)?;
+            Ok(Ty::new_generator(tcx, a_id, args, movability))
         }
 
         (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
@@ -462,22 +463,22 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
             Ok(Ty::new_generator_witness(tcx, types))
         }
 
-        (&ty::GeneratorWitnessMIR(a_id, a_substs), &ty::GeneratorWitnessMIR(b_id, b_substs))
+        (&ty::GeneratorWitnessMIR(a_id, a_args), &ty::GeneratorWitnessMIR(b_id, b_args))
             if a_id == b_id =>
         {
             // All GeneratorWitness types with the same id represent
             // the (anonymous) type of the same generator expression. So
             // all of their regions should be equated.
-            let substs = relation.relate(a_substs, b_substs)?;
-            Ok(Ty::new_generator_witness_mir(tcx, a_id, substs))
+            let args = relation.relate(a_args, b_args)?;
+            Ok(Ty::new_generator_witness_mir(tcx, a_id, args))
         }
 
-        (&ty::Closure(a_id, a_substs), &ty::Closure(b_id, b_substs)) if a_id == b_id => {
+        (&ty::Closure(a_id, a_args), &ty::Closure(b_id, b_args)) if a_id == b_id => {
             // All Closure types with the same id represent
             // the (anonymous) type of the same closure expression. So
             // all of their regions should be equated.
-            let substs = relation.relate(a_substs, b_substs)?;
-            Ok(Ty::new_closure(tcx, a_id, &substs))
+            let args = relation.relate(a_args, b_args)?;
+            Ok(Ty::new_closure(tcx, a_id, &args))
         }
 
         (&ty::RawPtr(a_mt), &ty::RawPtr(b_mt)) => {
@@ -535,11 +536,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
             }
         }
 
-        (&ty::FnDef(a_def_id, a_substs), &ty::FnDef(b_def_id, b_substs))
-            if a_def_id == b_def_id =>
-        {
-            let substs = relation.relate_item_substs(a_def_id, a_substs, b_substs)?;
-            Ok(Ty::new_fn_def(tcx, a_def_id, substs))
+        (&ty::FnDef(a_def_id, a_args), &ty::FnDef(b_def_id, b_args)) if a_def_id == b_def_id => {
+            let args = relation.relate_item_args(a_def_id, a_args, b_args)?;
+            Ok(Ty::new_fn_def(tcx, a_def_id, args))
         }
 
         (&ty::FnPtr(a_fty), &ty::FnPtr(b_fty)) => {
@@ -547,22 +546,22 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
             Ok(Ty::new_fn_ptr(tcx, fty))
         }
 
-        // The substs of opaque types may not all be invariant, so we have
+        // The args of opaque types may not all be invariant, so we have
         // to treat them separately from other aliases.
         (
-            &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, substs: a_substs, .. }),
-            &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, substs: b_substs, .. }),
+            &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, args: a_args, .. }),
+            &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, args: b_args, .. }),
         ) if a_def_id == b_def_id => {
             let opt_variances = tcx.variances_of(a_def_id);
-            let substs = relate_substs_with_variances(
+            let args = relate_args_with_variances(
                 relation,
                 a_def_id,
                 opt_variances,
-                a_substs,
-                b_substs,
+                a_args,
+                b_args,
                 false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
             )?;
-            Ok(Ty::new_opaque(tcx, a_def_id, substs))
+            Ok(Ty::new_opaque(tcx, a_def_id, args))
         }
 
         // Alias tend to mostly already be handled downstream due to normalization.
@@ -618,15 +617,15 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
         // be stabilized.
         (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => {
             assert_eq!(a.ty(), b.ty());
-            let substs = relation.relate_with_variance(
+            let args = relation.relate_with_variance(
                 ty::Variance::Invariant,
                 ty::VarianceDiagInfo::default(),
-                au.substs,
-                bu.substs,
+                au.args,
+                bu.args,
             )?;
             return Ok(ty::Const::new_unevaluated(
                 tcx,
-                ty::UnevaluatedConst { def: au.def, substs },
+                ty::UnevaluatedConst { def: au.def, args },
                 a.ty(),
             ));
         }
@@ -640,7 +639,7 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
             // FIXME(generic_const_exprs): relating the `ty()`s is a little weird since it is supposed to
             // ICE If they mismatch. Unfortunately `ConstKind::Expr` is a little special and can be thought
             // of as being generic over the argument types, however this is implicit so these types don't get
-            // related when we relate the substs of the item this const arg is for.
+            // related when we relate the args of the item this const arg is for.
             let expr = match (ae, be) {
                 (Expr::Binop(a_op, al, ar), Expr::Binop(b_op, bl, br)) if a_op == b_op => {
                     r.relate(al.ty(), bl.ty())?;
@@ -714,35 +713,35 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
     }
 }
 
-impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
+impl<'tcx> Relate<'tcx> for ty::ClosureArgs<'tcx> {
     fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
-        a: ty::ClosureSubsts<'tcx>,
-        b: ty::ClosureSubsts<'tcx>,
-    ) -> RelateResult<'tcx, ty::ClosureSubsts<'tcx>> {
-        let substs = relate_substs(relation, a.substs, b.substs)?;
-        Ok(ty::ClosureSubsts { substs })
+        a: ty::ClosureArgs<'tcx>,
+        b: ty::ClosureArgs<'tcx>,
+    ) -> RelateResult<'tcx, ty::ClosureArgs<'tcx>> {
+        let args = relate_args(relation, a.args, b.args)?;
+        Ok(ty::ClosureArgs { args })
     }
 }
 
-impl<'tcx> Relate<'tcx> for ty::GeneratorSubsts<'tcx> {
+impl<'tcx> Relate<'tcx> for ty::GeneratorArgs<'tcx> {
     fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
-        a: ty::GeneratorSubsts<'tcx>,
-        b: ty::GeneratorSubsts<'tcx>,
-    ) -> RelateResult<'tcx, ty::GeneratorSubsts<'tcx>> {
-        let substs = relate_substs(relation, a.substs, b.substs)?;
-        Ok(ty::GeneratorSubsts { substs })
+        a: ty::GeneratorArgs<'tcx>,
+        b: ty::GeneratorArgs<'tcx>,
+    ) -> RelateResult<'tcx, ty::GeneratorArgs<'tcx>> {
+        let args = relate_args(relation, a.args, b.args)?;
+        Ok(ty::GeneratorArgs { args })
     }
 }
 
-impl<'tcx> Relate<'tcx> for SubstsRef<'tcx> {
+impl<'tcx> Relate<'tcx> for GenericArgsRef<'tcx> {
     fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
-        a: SubstsRef<'tcx>,
-        b: SubstsRef<'tcx>,
-    ) -> RelateResult<'tcx, SubstsRef<'tcx>> {
-        relate_substs(relation, a, b)
+        a: GenericArgsRef<'tcx>,
+        b: GenericArgsRef<'tcx>,
+    ) -> RelateResult<'tcx, GenericArgsRef<'tcx>> {
+        relate_args(relation, a, b)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index c82ce9112fc..9d380a58d9f 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -222,8 +222,8 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
             ty::PredicateKind::ObjectSafe(trait_def_id) => {
                 write!(f, "ObjectSafe({:?})", trait_def_id)
             }
-            ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
-                write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
+            ty::PredicateKind::ClosureKind(closure_def_id, closure_args, kind) => {
+                write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_args, kind)
             }
             ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
             ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"),
@@ -245,7 +245,7 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for AliasTy<'tcx> {
         f: &mut core::fmt::Formatter<'_>,
     ) -> core::fmt::Result {
         f.debug_struct("AliasTy")
-            .field("substs", &this.map(|data| data.substs))
+            .field("args", &this.map(|data| data.args))
             .field("def_id", &this.data.def_id)
             .finish()
     }
@@ -322,7 +322,7 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> {
     ) -> core::fmt::Result {
         f.debug_struct("UnevaluatedConst")
             .field("def", &this.data.def)
-            .field("substs", &this.wrap(this.data.substs))
+            .field("args", &this.wrap(this.data.args))
             .finish()
     }
 }
@@ -695,26 +695,26 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
             ty::RawPtr(tm) => ty::RawPtr(tm.try_fold_with(folder)?),
             ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?),
             ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?),
-            ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?),
+            ty::Adt(tid, args) => ty::Adt(tid, args.try_fold_with(folder)?),
             ty::Dynamic(trait_ty, region, representation) => ty::Dynamic(
                 trait_ty.try_fold_with(folder)?,
                 region.try_fold_with(folder)?,
                 representation,
             ),
             ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
-            ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?),
+            ty::FnDef(def_id, args) => ty::FnDef(def_id, args.try_fold_with(folder)?),
             ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?),
             ty::Ref(r, ty, mutbl) => {
                 ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
             }
-            ty::Generator(did, substs, movability) => {
-                ty::Generator(did, substs.try_fold_with(folder)?, movability)
+            ty::Generator(did, args, movability) => {
+                ty::Generator(did, args.try_fold_with(folder)?, movability)
             }
             ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
-            ty::GeneratorWitnessMIR(did, substs) => {
-                ty::GeneratorWitnessMIR(did, substs.try_fold_with(folder)?)
+            ty::GeneratorWitnessMIR(did, args) => {
+                ty::GeneratorWitnessMIR(did, args.try_fold_with(folder)?)
             }
-            ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?),
+            ty::Closure(did, args) => ty::Closure(did, args.try_fold_with(folder)?),
             ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
 
             ty::Bool
@@ -748,22 +748,22 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
                 sz.visit_with(visitor)
             }
             ty::Slice(typ) => typ.visit_with(visitor),
-            ty::Adt(_, substs) => substs.visit_with(visitor),
+            ty::Adt(_, args) => args.visit_with(visitor),
             ty::Dynamic(ref trait_ty, ref reg, _) => {
                 trait_ty.visit_with(visitor)?;
                 reg.visit_with(visitor)
             }
             ty::Tuple(ts) => ts.visit_with(visitor),
-            ty::FnDef(_, substs) => substs.visit_with(visitor),
+            ty::FnDef(_, args) => args.visit_with(visitor),
             ty::FnPtr(ref f) => f.visit_with(visitor),
             ty::Ref(r, ty, _) => {
                 r.visit_with(visitor)?;
                 ty.visit_with(visitor)
             }
-            ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
+            ty::Generator(_did, ref args, _) => args.visit_with(visitor),
             ty::GeneratorWitness(ref types) => types.visit_with(visitor),
-            ty::GeneratorWitnessMIR(_did, ref substs) => substs.visit_with(visitor),
-            ty::Closure(_did, ref substs) => substs.visit_with(visitor),
+            ty::GeneratorWitnessMIR(_did, ref args) => args.visit_with(visitor),
+            ty::Closure(_did, ref args) => args.visit_with(visitor),
             ty::Alias(_, ref data) => data.visit_with(visitor),
 
             ty::Bool
@@ -943,7 +943,7 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> {
         &self,
         visitor: &mut V,
     ) -> ControlFlow<V::BreakTy> {
-        self.substs.visit_with(visitor)
+        self.args.visit_with(visitor)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 9f4515b95e7..66d8a79de42 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -3,13 +3,13 @@
 #![allow(rustc::usage_of_ty_tykind)]
 
 use crate::infer::canonical::Canonical;
-use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
 use crate::ty::visit::ValidateBoundVars;
 use crate::ty::InferTy::*;
 use crate::ty::{
     self, AdtDef, Discr, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable,
     TypeVisitableExt, TypeVisitor,
 };
+use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
 use crate::ty::{List, ParamEnv};
 use hir::def::DefKind;
 use polonius_engine::Atom;
@@ -218,7 +218,7 @@ impl<'tcx> Article for TyKind<'tcx> {
 ///
 /// ## Generators
 ///
-/// Generators are handled similarly in `GeneratorSubsts`. The set of
+/// Generators are handled similarly in `GeneratorArgs`. The set of
 /// type parameters is similar, but `CK` and `CS` are replaced by the
 /// following type parameters:
 ///
@@ -231,33 +231,30 @@ impl<'tcx> Article for TyKind<'tcx> {
 ///   completion of the generator.
 /// * `GW`: The "generator witness".
 #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
-pub struct ClosureSubsts<'tcx> {
+pub struct ClosureArgs<'tcx> {
     /// Lifetime and type parameters from the enclosing function,
     /// concatenated with a tuple containing the types of the upvars.
     ///
     /// These are separated out because codegen wants to pass them around
     /// when monomorphizing.
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
 }
 
 /// Struct returned by `split()`.
-pub struct ClosureSubstsParts<'tcx, T> {
-    pub parent_substs: &'tcx [GenericArg<'tcx>],
+pub struct ClosureArgsParts<'tcx, T> {
+    pub parent_args: &'tcx [GenericArg<'tcx>],
     pub closure_kind_ty: T,
     pub closure_sig_as_fn_ptr_ty: T,
     pub tupled_upvars_ty: T,
 }
 
-impl<'tcx> ClosureSubsts<'tcx> {
-    /// Construct `ClosureSubsts` from `ClosureSubstsParts`, containing `Substs`
+impl<'tcx> ClosureArgs<'tcx> {
+    /// Construct `ClosureArgs` from `ClosureArgsParts`, containing `Args`
     /// for the closure parent, alongside additional closure-specific components.
-    pub fn new(
-        tcx: TyCtxt<'tcx>,
-        parts: ClosureSubstsParts<'tcx, Ty<'tcx>>,
-    ) -> ClosureSubsts<'tcx> {
-        ClosureSubsts {
-            substs: tcx.mk_substs_from_iter(
-                parts.parent_substs.iter().copied().chain(
+    pub fn new(tcx: TyCtxt<'tcx>, parts: ClosureArgsParts<'tcx, Ty<'tcx>>) -> ClosureArgs<'tcx> {
+        ClosureArgs {
+            args: tcx.mk_args_from_iter(
+                parts.parent_args.iter().copied().chain(
                     [parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty]
                         .iter()
                         .map(|&ty| ty.into()),
@@ -266,38 +263,34 @@ impl<'tcx> ClosureSubsts<'tcx> {
         }
     }
 
-    /// Divides the closure substs into their respective components.
-    /// The ordering assumed here must match that used by `ClosureSubsts::new` above.
-    fn split(self) -> ClosureSubstsParts<'tcx, GenericArg<'tcx>> {
-        match self.substs[..] {
-            [
-                ref parent_substs @ ..,
-                closure_kind_ty,
-                closure_sig_as_fn_ptr_ty,
-                tupled_upvars_ty,
-            ] => ClosureSubstsParts {
-                parent_substs,
-                closure_kind_ty,
-                closure_sig_as_fn_ptr_ty,
-                tupled_upvars_ty,
-            },
-            _ => bug!("closure substs missing synthetics"),
+    /// Divides the closure args into their respective components.
+    /// The ordering assumed here must match that used by `ClosureArgs::new` above.
+    fn split(self) -> ClosureArgsParts<'tcx, GenericArg<'tcx>> {
+        match self.args[..] {
+            [ref parent_args @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
+                ClosureArgsParts {
+                    parent_args,
+                    closure_kind_ty,
+                    closure_sig_as_fn_ptr_ty,
+                    tupled_upvars_ty,
+                }
+            }
+            _ => bug!("closure args missing synthetics"),
         }
     }
 
     /// Returns `true` only if enough of the synthetic types are known to
-    /// allow using all of the methods on `ClosureSubsts` without panicking.
+    /// allow using all of the methods on `ClosureArgs` without panicking.
     ///
     /// Used primarily by `ty::print::pretty` to be able to handle closure
     /// types that haven't had their synthetic types substituted in.
     pub fn is_valid(self) -> bool {
-        self.substs.len() >= 3
-            && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_))
+        self.args.len() >= 3 && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_))
     }
 
     /// Returns the substitutions of the closure's parent.
-    pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
-        self.split().parent_substs
+    pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
+        self.split().parent_args
     }
 
     /// Returns an iterator over the list of types of captured paths by the closure.
@@ -323,7 +316,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
 
     /// Returns the closure kind for this closure; may return a type
     /// variable during inference. To get the closure kind during
-    /// inference, use `infcx.closure_kind(substs)`.
+    /// inference, use `infcx.closure_kind(args)`.
     pub fn kind_ty(self) -> Ty<'tcx> {
         self.split().closure_kind_ty.expect_ty()
     }
@@ -331,7 +324,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
     /// Returns the `fn` pointer type representing the closure signature for this
     /// closure.
     // FIXME(eddyb) this should be unnecessary, as the shallowly resolved
-    // type is known at the time of the creation of `ClosureSubsts`,
+    // type is known at the time of the creation of `ClosureArgs`,
     // see `rustc_hir_analysis::check::closure`.
     pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> {
         self.split().closure_sig_as_fn_ptr_ty.expect_ty()
@@ -360,14 +353,14 @@ impl<'tcx> ClosureSubsts<'tcx> {
     }
 }
 
-/// Similar to `ClosureSubsts`; see the above documentation for more.
+/// Similar to `ClosureArgs`; see the above documentation for more.
 #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
-pub struct GeneratorSubsts<'tcx> {
-    pub substs: SubstsRef<'tcx>,
+pub struct GeneratorArgs<'tcx> {
+    pub args: GenericArgsRef<'tcx>,
 }
 
-pub struct GeneratorSubstsParts<'tcx, T> {
-    pub parent_substs: &'tcx [GenericArg<'tcx>],
+pub struct GeneratorArgsParts<'tcx, T> {
+    pub parent_args: &'tcx [GenericArg<'tcx>],
     pub resume_ty: T,
     pub yield_ty: T,
     pub return_ty: T,
@@ -375,16 +368,16 @@ pub struct GeneratorSubstsParts<'tcx, T> {
     pub tupled_upvars_ty: T,
 }
 
-impl<'tcx> GeneratorSubsts<'tcx> {
-    /// Construct `GeneratorSubsts` from `GeneratorSubstsParts`, containing `Substs`
+impl<'tcx> GeneratorArgs<'tcx> {
+    /// Construct `GeneratorArgs` from `GeneratorArgsParts`, containing `Args`
     /// for the generator parent, alongside additional generator-specific components.
     pub fn new(
         tcx: TyCtxt<'tcx>,
-        parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>,
-    ) -> GeneratorSubsts<'tcx> {
-        GeneratorSubsts {
-            substs: tcx.mk_substs_from_iter(
-                parts.parent_substs.iter().copied().chain(
+        parts: GeneratorArgsParts<'tcx, Ty<'tcx>>,
+    ) -> GeneratorArgs<'tcx> {
+        GeneratorArgs {
+            args: tcx.mk_args_from_iter(
+                parts.parent_args.iter().copied().chain(
                     [
                         parts.resume_ty,
                         parts.yield_ty,
@@ -399,13 +392,13 @@ impl<'tcx> GeneratorSubsts<'tcx> {
         }
     }
 
-    /// Divides the generator substs into their respective components.
-    /// The ordering assumed here must match that used by `GeneratorSubsts::new` above.
-    fn split(self) -> GeneratorSubstsParts<'tcx, GenericArg<'tcx>> {
-        match self.substs[..] {
-            [ref parent_substs @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
-                GeneratorSubstsParts {
-                    parent_substs,
+    /// Divides the generator args into their respective components.
+    /// The ordering assumed here must match that used by `GeneratorArgs::new` above.
+    fn split(self) -> GeneratorArgsParts<'tcx, GenericArg<'tcx>> {
+        match self.args[..] {
+            [ref parent_args @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
+                GeneratorArgsParts {
+                    parent_args,
                     resume_ty,
                     yield_ty,
                     return_ty,
@@ -413,23 +406,22 @@ impl<'tcx> GeneratorSubsts<'tcx> {
                     tupled_upvars_ty,
                 }
             }
-            _ => bug!("generator substs missing synthetics"),
+            _ => bug!("generator args missing synthetics"),
         }
     }
 
     /// Returns `true` only if enough of the synthetic types are known to
-    /// allow using all of the methods on `GeneratorSubsts` without panicking.
+    /// allow using all of the methods on `GeneratorArgs` without panicking.
     ///
     /// Used primarily by `ty::print::pretty` to be able to handle generator
     /// types that haven't had their synthetic types substituted in.
     pub fn is_valid(self) -> bool {
-        self.substs.len() >= 5
-            && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_))
+        self.args.len() >= 5 && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_))
     }
 
     /// Returns the substitutions of the generator's parent.
-    pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
-        self.split().parent_substs
+    pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
+        self.split().parent_args
     }
 
     /// This describes the types that can be contained in a generator.
@@ -498,7 +490,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
     }
 }
 
-impl<'tcx> GeneratorSubsts<'tcx> {
+impl<'tcx> GeneratorArgs<'tcx> {
     /// Generator has not been resumed yet.
     pub const UNRESUMED: usize = 0;
     /// Generator has returned or is completed.
@@ -577,7 +569,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
         let layout = tcx.generator_layout(def_id).unwrap();
         layout.variant_fields.iter().map(move |variant| {
             variant.iter().map(move |field| {
-                ty::EarlyBinder::bind(layout.field_tys[*field].ty).subst(tcx, self.substs)
+                ty::EarlyBinder::bind(layout.field_tys[*field].ty).instantiate(tcx, self.args)
             })
         })
     }
@@ -591,20 +583,20 @@ impl<'tcx> GeneratorSubsts<'tcx> {
 }
 
 #[derive(Debug, Copy, Clone, HashStable)]
-pub enum UpvarSubsts<'tcx> {
-    Closure(SubstsRef<'tcx>),
-    Generator(SubstsRef<'tcx>),
+pub enum UpvarArgs<'tcx> {
+    Closure(GenericArgsRef<'tcx>),
+    Generator(GenericArgsRef<'tcx>),
 }
 
-impl<'tcx> UpvarSubsts<'tcx> {
+impl<'tcx> UpvarArgs<'tcx> {
     /// Returns an iterator over the list of types of captured paths by the closure/generator.
     /// In case there was a type error in figuring out the types of the captured path, an
     /// empty iterator is returned.
     #[inline]
     pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
         let tupled_tys = match self {
-            UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(),
-            UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(),
+            UpvarArgs::Closure(args) => args.as_closure().tupled_upvars_ty(),
+            UpvarArgs::Generator(args) => args.as_generator().tupled_upvars_ty(),
         };
 
         match tupled_tys.kind() {
@@ -620,8 +612,8 @@ impl<'tcx> UpvarSubsts<'tcx> {
     #[inline]
     pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
         match self {
-            UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(),
-            UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(),
+            UpvarArgs::Closure(args) => args.as_closure().tupled_upvars_ty(),
+            UpvarArgs::Generator(args) => args.as_generator().tupled_upvars_ty(),
         }
     }
 }
@@ -638,46 +630,46 @@ impl<'tcx> UpvarSubsts<'tcx> {
 ///
 /// When the inline const is instantiated, `R` is substituted as the actual inferred
 /// type of the constant. The reason that `R` is represented as an extra type parameter
-/// is the same reason that [`ClosureSubsts`] have `CS` and `U` as type parameters:
+/// 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.
 #[derive(Copy, Clone, Debug)]
-pub struct InlineConstSubsts<'tcx> {
+pub struct InlineConstArgs<'tcx> {
     /// Generic parameters from the enclosing item,
     /// concatenated with the inferred type of the constant.
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
 }
 
 /// Struct returned by `split()`.
-pub struct InlineConstSubstsParts<'tcx, T> {
-    pub parent_substs: &'tcx [GenericArg<'tcx>],
+pub struct InlineConstArgsParts<'tcx, T> {
+    pub parent_args: &'tcx [GenericArg<'tcx>],
     pub ty: T,
 }
 
-impl<'tcx> InlineConstSubsts<'tcx> {
-    /// Construct `InlineConstSubsts` from `InlineConstSubstsParts`.
+impl<'tcx> InlineConstArgs<'tcx> {
+    /// Construct `InlineConstArgs` from `InlineConstArgsParts`.
     pub fn new(
         tcx: TyCtxt<'tcx>,
-        parts: InlineConstSubstsParts<'tcx, Ty<'tcx>>,
-    ) -> InlineConstSubsts<'tcx> {
-        InlineConstSubsts {
-            substs: tcx.mk_substs_from_iter(
-                parts.parent_substs.iter().copied().chain(std::iter::once(parts.ty.into())),
+        parts: InlineConstArgsParts<'tcx, Ty<'tcx>>,
+    ) -> InlineConstArgs<'tcx> {
+        InlineConstArgs {
+            args: tcx.mk_args_from_iter(
+                parts.parent_args.iter().copied().chain(std::iter::once(parts.ty.into())),
             ),
         }
     }
 
-    /// Divides the inline const substs into their respective components.
-    /// The ordering assumed here must match that used by `InlineConstSubsts::new` above.
-    fn split(self) -> InlineConstSubstsParts<'tcx, GenericArg<'tcx>> {
-        match self.substs[..] {
-            [ref parent_substs @ .., ty] => InlineConstSubstsParts { parent_substs, ty },
-            _ => bug!("inline const substs missing synthetics"),
+    /// Divides the inline const args into their respective components.
+    /// The ordering assumed here must match that used by `InlineConstArgs::new` above.
+    fn split(self) -> InlineConstArgsParts<'tcx, GenericArg<'tcx>> {
+        match self.args[..] {
+            [ref parent_args @ .., ty] => InlineConstArgsParts { parent_args, ty },
+            _ => bug!("inline const args missing synthetics"),
         }
     }
 
     /// Returns the substitutions of the inline const's parent.
-    pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
-        self.split().parent_substs
+    pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
+        self.split().parent_args
     }
 
     /// Returns the type of this inline const.
@@ -748,10 +740,9 @@ impl<'tcx> PolyExistentialPredicate<'tcx> {
                     ty::TraitRef::new(tcx, did, [self_ty])
                 } else {
                     // If this is an ill-formed auto trait, then synthesize
-                    // new error substs for the missing generics.
-                    let err_substs =
-                        ty::InternalSubsts::extend_with_error(tcx, did, &[self_ty.into()]);
-                    ty::TraitRef::new(tcx, did, err_substs)
+                    // new error args for the missing generics.
+                    let err_args = ty::GenericArgs::extend_with_error(tcx, did, &[self_ty.into()]);
+                    ty::TraitRef::new(tcx, did, err_args)
                 };
                 self.rebind(trait_ref).without_const().to_predicate(tcx)
             }
@@ -827,7 +818,7 @@ impl<'tcx> List<ty::PolyExistentialPredicate<'tcx>> {
 /// T: Foo<U>
 /// ```
 /// This would be represented by a trait-reference where the `DefId` is the
-/// `DefId` for the trait `Foo` and the substs define `T` as parameter 0,
+/// `DefId` for the trait `Foo` and the args define `T` as parameter 0,
 /// and `U` as parameter 1.
 ///
 /// Trait references also appear in object types like `Foo<U>`, but in
@@ -836,7 +827,7 @@ impl<'tcx> List<ty::PolyExistentialPredicate<'tcx>> {
 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
 pub struct TraitRef<'tcx> {
     pub def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
     /// This field exists to prevent the creation of `TraitRef` without
     /// calling [`TraitRef::new`].
     pub(super) _use_trait_ref_new_instead: (),
@@ -846,42 +837,42 @@ impl<'tcx> TraitRef<'tcx> {
     pub fn new(
         tcx: TyCtxt<'tcx>,
         trait_def_id: DefId,
-        substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
+        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> Self {
-        let substs = tcx.check_and_mk_substs(trait_def_id, substs);
-        Self { def_id: trait_def_id, substs, _use_trait_ref_new_instead: () }
+        let args = tcx.check_and_mk_args(trait_def_id, args);
+        Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
     }
 
     pub fn from_lang_item(
         tcx: TyCtxt<'tcx>,
         trait_lang_item: LangItem,
         span: Span,
-        substs: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
+        args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
     ) -> Self {
         let trait_def_id = tcx.require_lang_item(trait_lang_item, Some(span));
-        Self::new(tcx, trait_def_id, substs)
+        Self::new(tcx, trait_def_id, args)
     }
 
     pub fn from_method(
         tcx: TyCtxt<'tcx>,
         trait_id: DefId,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) -> ty::TraitRef<'tcx> {
         let defs = tcx.generics_of(trait_id);
-        ty::TraitRef::new(tcx, trait_id, tcx.mk_substs(&substs[..defs.params.len()]))
+        ty::TraitRef::new(tcx, trait_id, tcx.mk_args(&args[..defs.params.len()]))
     }
 
     /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
     /// are the parameters defined on trait.
     pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> {
-        ty::TraitRef::new(tcx, def_id, InternalSubsts::identity_for_item(tcx, def_id))
+        ty::TraitRef::new(tcx, def_id, GenericArgs::identity_for_item(tcx, def_id))
     }
 
     pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
         ty::TraitRef::new(
             tcx,
             self.def_id,
-            [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)),
+            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
         )
     }
 
@@ -899,7 +890,7 @@ impl<'tcx> TraitRef<'tcx> {
 
     #[inline]
     pub fn self_ty(&self) -> Ty<'tcx> {
-        self.substs.type_at(0)
+        self.args.type_at(0)
     }
 }
 
@@ -932,7 +923,7 @@ impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> {
 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
 pub struct ExistentialTraitRef<'tcx> {
     pub def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
 }
 
 impl<'tcx> ExistentialTraitRef<'tcx> {
@@ -941,11 +932,11 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
         trait_ref: ty::TraitRef<'tcx>,
     ) -> ty::ExistentialTraitRef<'tcx> {
         // Assert there is a Self.
-        trait_ref.substs.type_at(0);
+        trait_ref.args.type_at(0);
 
         ty::ExistentialTraitRef {
             def_id: trait_ref.def_id,
-            substs: tcx.mk_substs(&trait_ref.substs[1..]),
+            args: tcx.mk_args(&trait_ref.args[1..]),
         }
     }
 
@@ -957,7 +948,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
         // otherwise the escaping vars would be captured by the binder
         // debug_assert!(!self_ty.has_escaping_bound_vars());
 
-        ty::TraitRef::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter()))
+        ty::TraitRef::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
     }
 }
 
@@ -1226,7 +1217,7 @@ pub struct AliasTy<'tcx> {
     ///
     /// For RPIT the substitutions are for the generics of the function,
     /// while for TAIT it is used for the generic parameters of the alias.
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
 
     /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether
     /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if
@@ -1264,11 +1255,11 @@ impl<'tcx> AliasTy<'tcx> {
 /// The following methods work only with associated type projections.
 impl<'tcx> AliasTy<'tcx> {
     pub fn self_ty(self) -> Ty<'tcx> {
-        self.substs.type_at(0)
+        self.args.type_at(0)
     }
 
     pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
-        tcx.mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)))
+        tcx.mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.args.iter().skip(1)))
     }
 }
 
@@ -1281,10 +1272,10 @@ impl<'tcx> AliasTy<'tcx> {
         }
     }
 
-    /// Extracts the underlying trait reference and own substs from this projection.
+    /// Extracts the underlying trait reference and own args from this projection.
     /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
-    /// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own substs
-    pub fn trait_ref_and_own_substs(
+    /// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own args
+    pub fn trait_ref_and_own_args(
         self,
         tcx: TyCtxt<'tcx>,
     ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
@@ -1292,8 +1283,8 @@ impl<'tcx> AliasTy<'tcx> {
         let trait_def_id = self.trait_def_id(tcx);
         let trait_generics = tcx.generics_of(trait_def_id);
         (
-            ty::TraitRef::new(tcx, trait_def_id, self.substs.truncate_to(tcx, trait_generics)),
-            &self.substs[trait_generics.count()..],
+            ty::TraitRef::new(tcx, trait_def_id, self.args.truncate_to(tcx, trait_generics)),
+            &self.args[trait_generics.count()..],
         )
     }
 
@@ -1301,18 +1292,18 @@ impl<'tcx> AliasTy<'tcx> {
     /// For example, if this is a projection of `<T as Iterator>::Item`,
     /// then this function would return a `T: Iterator` trait reference.
     ///
-    /// WARNING: This will drop the substs for generic associated types
-    /// consider calling [Self::trait_ref_and_own_substs] to get those
+    /// WARNING: This will drop the args for generic associated types
+    /// consider calling [Self::trait_ref_and_own_args] to get those
     /// as well.
     pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
         let def_id = self.trait_def_id(tcx);
-        ty::TraitRef::new(tcx, def_id, self.substs.truncate_to(tcx, tcx.generics_of(def_id)))
+        ty::TraitRef::new(tcx, def_id, self.args.truncate_to(tcx, tcx.generics_of(def_id)))
     }
 }
 
 /// The following methods work only with inherent associated type projections.
 impl<'tcx> AliasTy<'tcx> {
-    /// Transform the substitutions to have the given `impl` substs as the base and the GAT substs on top of that.
+    /// Transform the substitutions to have the given `impl` args as the base and the GAT args on top of that.
     ///
     /// Does the following transformation:
     ///
@@ -1322,14 +1313,14 @@ impl<'tcx> AliasTy<'tcx> {
     ///     I_i impl subst
     ///     P_j GAT subst
     /// ```
-    pub fn rebase_substs_onto_impl(
+    pub fn rebase_args_onto_impl(
         self,
-        impl_substs: ty::SubstsRef<'tcx>,
+        impl_args: ty::GenericArgsRef<'tcx>,
         tcx: TyCtxt<'tcx>,
-    ) -> ty::SubstsRef<'tcx> {
+    ) -> ty::GenericArgsRef<'tcx> {
         debug_assert_eq!(self.kind(tcx), ty::Inherent);
 
-        tcx.mk_substs_from_iter(impl_substs.into_iter().chain(self.substs.into_iter().skip(1)))
+        tcx.mk_args_from_iter(impl_args.into_iter().chain(self.args.into_iter().skip(1)))
     }
 }
 
@@ -1649,7 +1640,7 @@ impl From<BoundVar> for BoundTy {
 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
 pub struct ExistentialProjection<'tcx> {
     pub def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
+    pub args: GenericArgsRef<'tcx>,
     pub term: Term<'tcx>,
 }
 
@@ -1663,8 +1654,8 @@ impl<'tcx> ExistentialProjection<'tcx> {
     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 substs = tcx.mk_substs(&self.substs[..subst_count]);
-        ty::ExistentialTraitRef { def_id, substs }
+        let args = tcx.mk_args(&self.args[..subst_count]);
+        ty::ExistentialTraitRef { def_id, args }
     }
 
     pub fn with_self_ty(
@@ -1677,7 +1668,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
 
         ty::ProjectionPredicate {
             projection_ty: tcx
-                .mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs)),
+                .mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.args)),
             term: self.term,
         }
     }
@@ -1687,11 +1678,11 @@ impl<'tcx> ExistentialProjection<'tcx> {
         projection_predicate: ty::ProjectionPredicate<'tcx>,
     ) -> Self {
         // Assert there is a Self.
-        projection_predicate.projection_ty.substs.type_at(0);
+        projection_predicate.projection_ty.args.type_at(0);
 
         Self {
             def_id: projection_predicate.projection_ty.def_id,
-            substs: tcx.mk_substs(&projection_predicate.projection_ty.substs[1..]),
+            args: tcx.mk_args(&projection_predicate.projection_ty.args[1..]),
             term: projection_predicate.term,
         }
     }
@@ -1979,8 +1970,8 @@ impl<'tcx> Ty<'tcx> {
     }
 
     #[inline]
-    pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        Ty::new_alias(tcx, ty::Opaque, tcx.mk_alias_ty(def_id, substs))
+    pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
+        Ty::new_alias(tcx, ty::Opaque, tcx.mk_alias_ty(def_id, args))
     }
 
     /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed`
@@ -2072,8 +2063,8 @@ impl<'tcx> Ty<'tcx> {
     }
 
     #[inline]
-    pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        Ty::new(tcx, Adt(def, substs))
+    pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
+        Ty::new(tcx, Adt(def, args))
     }
 
     #[inline]
@@ -2117,10 +2108,10 @@ impl<'tcx> Ty<'tcx> {
     pub fn new_fn_def(
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-        substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
+        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> Ty<'tcx> {
-        let substs = tcx.check_and_mk_substs(def_id, substs);
-        Ty::new(tcx, FnDef(def_id, substs))
+        let args = tcx.check_and_mk_args(def_id, args);
+        Ty::new(tcx, FnDef(def_id, args))
     }
 
     #[inline]
@@ -2142,38 +2133,38 @@ impl<'tcx> Ty<'tcx> {
     pub fn new_projection(
         tcx: TyCtxt<'tcx>,
         item_def_id: DefId,
-        substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
+        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> Ty<'tcx> {
-        Ty::new_alias(tcx, ty::Projection, tcx.mk_alias_ty(item_def_id, substs))
+        Ty::new_alias(tcx, ty::Projection, tcx.mk_alias_ty(item_def_id, args))
     }
 
     #[inline]
     pub fn new_closure(
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-        closure_substs: SubstsRef<'tcx>,
+        closure_args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
         debug_assert_eq!(
-            closure_substs.len(),
+            closure_args.len(),
             tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 3,
             "closure constructed with incorrect substitutions"
         );
-        Ty::new(tcx, Closure(def_id, closure_substs))
+        Ty::new(tcx, Closure(def_id, closure_args))
     }
 
     #[inline]
     pub fn new_generator(
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-        generator_substs: SubstsRef<'tcx>,
+        generator_args: GenericArgsRef<'tcx>,
         movability: hir::Movability,
     ) -> Ty<'tcx> {
         debug_assert_eq!(
-            generator_substs.len(),
+            generator_args.len(),
             tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 5,
             "generator constructed with incorrect number of substitutions"
         );
-        Ty::new(tcx, Generator(def_id, generator_substs, movability))
+        Ty::new(tcx, Generator(def_id, generator_args, movability))
     }
 
     #[inline]
@@ -2188,9 +2179,9 @@ impl<'tcx> Ty<'tcx> {
     pub fn new_generator_witness_mir(
         tcx: TyCtxt<'tcx>,
         id: DefId,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
-        Ty::new(tcx, GeneratorWitnessMIR(id, substs))
+        Ty::new(tcx, GeneratorWitnessMIR(id, args))
     }
 
     // misc
@@ -2214,19 +2205,18 @@ impl<'tcx> Ty<'tcx> {
 
     fn new_generic_adt(tcx: TyCtxt<'tcx>, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
         let adt_def = tcx.adt_def(wrapper_def_id);
-        let substs =
-            InternalSubsts::for_item(tcx, wrapper_def_id, |param, substs| match param.kind {
-                GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(),
-                GenericParamDefKind::Type { has_default, .. } => {
-                    if param.index == 0 {
-                        ty_param.into()
-                    } else {
-                        assert!(has_default);
-                        tcx.type_of(param.def_id).subst(tcx, substs).into()
-                    }
+        let args = GenericArgs::for_item(tcx, wrapper_def_id, |param, args| match param.kind {
+            GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(),
+            GenericParamDefKind::Type { has_default, .. } => {
+                if param.index == 0 {
+                    ty_param.into()
+                } else {
+                    assert!(has_default);
+                    tcx.type_of(param.def_id).instantiate(tcx, args).into()
                 }
-            });
-        Ty::new(tcx, Adt(adt_def, substs))
+            }
+        });
+        Ty::new(tcx, Adt(adt_def, args))
     }
 
     #[inline]
@@ -2257,8 +2247,8 @@ impl<'tcx> Ty<'tcx> {
     pub fn new_task_context(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         let context_did = tcx.require_lang_item(LangItem::Context, None);
         let context_adt_ref = tcx.adt_def(context_did);
-        let context_substs = tcx.mk_substs(&[tcx.lifetimes.re_erased.into()]);
-        let context_ty = Ty::new_adt(tcx, context_adt_ref, context_substs);
+        let context_args = tcx.mk_args(&[tcx.lifetimes.re_erased.into()]);
+        let context_ty = Ty::new_adt(tcx, context_adt_ref, context_args);
         Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, context_ty)
     }
 }
@@ -2382,10 +2372,10 @@ impl<'tcx> Ty<'tcx> {
 
     pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
         match self.kind() {
-            Adt(def, substs) => {
+            Adt(def, args) => {
                 assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type");
                 let variant = def.non_enum_variant();
-                let f0_ty = variant.fields[FieldIdx::from_u32(0)].ty(tcx, substs);
+                let f0_ty = variant.fields[FieldIdx::from_u32(0)].ty(tcx, args);
 
                 match f0_ty.kind() {
                     // If the first field is an array, we assume it is the only field and its
@@ -2446,7 +2436,7 @@ impl<'tcx> Ty<'tcx> {
     /// Panics if called on any type other than `Box<T>`.
     pub fn boxed_ty(self) -> Ty<'tcx> {
         match self.kind() {
-            Adt(def, substs) if def.is_box() => substs.type_at(0),
+            Adt(def, args) if def.is_box() => args.type_at(0),
             _ => bug!("`boxed_ty` is called on non-box type {:?}", self),
         }
     }
@@ -2610,14 +2600,14 @@ impl<'tcx> Ty<'tcx> {
 
     pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
         match self.kind() {
-            FnDef(def_id, substs) => tcx.fn_sig(*def_id).subst(tcx, substs),
+            FnDef(def_id, args) => tcx.fn_sig(*def_id).instantiate(tcx, args),
             FnPtr(f) => *f,
             Error(_) => {
                 // ignore errors (#54954)
                 ty::Binder::dummy(FnSig::fake())
             }
             Closure(..) => bug!(
-                "to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
+                "to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
             ),
             _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self),
         }
@@ -2651,7 +2641,7 @@ impl<'tcx> Ty<'tcx> {
     #[inline]
     pub fn tuple_fields(self) -> &'tcx List<Ty<'tcx>> {
         match self.kind() {
-            Tuple(substs) => substs,
+            Tuple(args) => args,
             _ => bug!("tuple_fields called on non-tuple"),
         }
     }
@@ -2663,8 +2653,8 @@ impl<'tcx> Ty<'tcx> {
     pub fn variant_range(self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> {
         match self.kind() {
             TyKind::Adt(adt, _) => Some(adt.variant_range()),
-            TyKind::Generator(def_id, substs, _) => {
-                Some(substs.as_generator().variant_range(*def_id, tcx))
+            TyKind::Generator(def_id, args, _) => {
+                Some(args.as_generator().variant_range(*def_id, tcx))
             }
             _ => None,
         }
@@ -2689,8 +2679,8 @@ impl<'tcx> Ty<'tcx> {
             TyKind::Adt(adt, _) if adt.is_enum() => {
                 Some(adt.discriminant_for_variant(tcx, variant_index))
             }
-            TyKind::Generator(def_id, substs, _) => {
-                Some(substs.as_generator().discriminant_for_variant(*def_id, tcx, variant_index))
+            TyKind::Generator(def_id, args, _) => {
+                Some(args.as_generator().discriminant_for_variant(*def_id, tcx, variant_index))
             }
             _ => None,
         }
@@ -2700,13 +2690,13 @@ impl<'tcx> Ty<'tcx> {
     pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match self.kind() {
             ty::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(tcx),
-            ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
+            ty::Generator(_, args, _) => args.as_generator().discr_ty(tcx),
 
             ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => {
                 let assoc_items = tcx.associated_item_def_ids(
                     tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
                 );
-                Ty::new_projection(tcx, assoc_items[0], tcx.mk_substs(&[self.into()]))
+                Ty::new_projection(tcx, assoc_items[0], tcx.mk_args(&[self.into()]))
             }
 
             ty::Bool
@@ -2779,7 +2769,7 @@ impl<'tcx> Ty<'tcx> {
             ty::Str | ty::Slice(_) => (tcx.types.usize, false),
             ty::Dynamic(..) => {
                 let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None);
-                (tcx.type_of(dyn_metadata).subst(tcx, &[tail.into()]), false)
+                (tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]), false)
             },
 
             // type parameters only have unit metadata if they're sized, so return true
@@ -2796,7 +2786,7 @@ impl<'tcx> Ty<'tcx> {
     }
 
     /// When we create a closure, we record its kind (i.e., what trait
-    /// it implements) into its `ClosureSubsts` using a type
+    /// it implements) into its `ClosureArgs` using a type
     /// parameter. This is kind of a phantom type, except that the
     /// most convenient thing for us to are the integral types. This
     /// function converts such a special type into the closure
@@ -2859,7 +2849,7 @@ impl<'tcx> Ty<'tcx> {
 
             ty::Tuple(tys) => tys.iter().all(|ty| ty.is_trivially_sized(tcx)),
 
-            ty::Adt(def, _substs) => def.sized_constraint(tcx).skip_binder().is_empty(),
+            ty::Adt(def, _args) => def.sized_constraint(tcx).skip_binder().is_empty(),
 
             ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false,
 
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 98c70e330f1..6e55e7915c9 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -236,7 +236,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
     for &impl_def_id in tcx.hir().trait_impls(trait_id) {
         let impl_def_id = impl_def_id.to_def_id();
 
-        let impl_self_ty = tcx.type_of(impl_def_id).subst_identity();
+        let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
         if impl_self_ty.references_error() {
             continue;
         }
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 9c25c01b056..327cd0a5d7b 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -4,7 +4,7 @@ use crate::{
     traits::ObligationCause,
     ty::{
         self, tls, BindingMode, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData,
-        GenericArgKind, InternalSubsts, SubstsRef, Ty, UserSubsts,
+        GenericArgKind, GenericArgs, GenericArgsRef, Ty, UserArgs,
     },
 };
 use rustc_data_structures::{
@@ -53,7 +53,7 @@ pub struct TypeckResults<'tcx> {
     /// 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_substs: ItemLocalMap<SubstsRef<'tcx>>,
+    node_args: ItemLocalMap<GenericArgsRef<'tcx>>,
 
     /// This will either store the canonicalized types provided by the user
     /// or the substitutions that the user explicitly gave (if any) attached
@@ -264,7 +264,7 @@ impl<'tcx> TypeckResults<'tcx> {
             user_provided_types: Default::default(),
             user_provided_sigs: Default::default(),
             node_types: Default::default(),
-            node_substs: Default::default(),
+            node_args: Default::default(),
             adjustments: Default::default(),
             pat_binding_modes: Default::default(),
             pat_adjustments: Default::default(),
@@ -384,18 +384,18 @@ impl<'tcx> TypeckResults<'tcx> {
         self.node_types.get(&id.local_id).cloned()
     }
 
-    pub fn node_substs_mut(&mut self) -> LocalTableInContextMut<'_, SubstsRef<'tcx>> {
-        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_substs }
+    pub fn node_args_mut(&mut self) -> LocalTableInContextMut<'_, GenericArgsRef<'tcx>> {
+        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_args }
     }
 
-    pub fn node_substs(&self, id: hir::HirId) -> SubstsRef<'tcx> {
+    pub fn node_args(&self, id: hir::HirId) -> GenericArgsRef<'tcx> {
         validate_hir_id_for_typeck_results(self.hir_owner, id);
-        self.node_substs.get(&id.local_id).cloned().unwrap_or_else(|| InternalSubsts::empty())
+        self.node_args.get(&id.local_id).cloned().unwrap_or_else(|| GenericArgs::empty())
     }
 
-    pub fn node_substs_opt(&self, id: hir::HirId) -> Option<SubstsRef<'tcx>> {
+    pub fn node_args_opt(&self, id: hir::HirId) -> Option<GenericArgsRef<'tcx>> {
         validate_hir_id_for_typeck_results(self.hir_owner, id);
-        self.node_substs.get(&id.local_id).cloned()
+        self.node_args.get(&id.local_id).cloned()
     }
 
     /// Returns the type of a pattern as a monotype. Like [`expr_ty`], this function
@@ -670,12 +670,12 @@ impl<'tcx> CanonicalUserType<'tcx> {
     pub fn is_identity(&self) -> bool {
         match self.value {
             UserType::Ty(_) => false,
-            UserType::TypeOf(_, user_substs) => {
-                if user_substs.user_self_ty.is_some() {
+            UserType::TypeOf(_, user_args) => {
+                if user_args.user_self_ty.is_some() {
                     return false;
                 }
 
-                iter::zip(user_substs.substs, BoundVar::new(0)..).all(|(kind, cvar)| {
+                iter::zip(user_args.args, BoundVar::new(0)..).all(|(kind, cvar)| {
                     match kind.unpack() {
                         GenericArgKind::Type(ty) => match ty.kind() {
                             ty::Bound(debruijn, b) => {
@@ -720,5 +720,5 @@ pub enum UserType<'tcx> {
 
     /// The canonical type is the result of `type_of(def_id)` with the
     /// given substitutions applied.
-    TypeOf(DefId, UserSubsts<'tcx>),
+    TypeOf(DefId, UserArgs<'tcx>),
 }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 8a83214edc7..b4852ab8881 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -7,7 +7,7 @@ use crate::ty::{
     self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
     TypeVisitableExt,
 };
-use crate::ty::{GenericArgKind, SubstsRef};
+use crate::ty::{GenericArgKind, GenericArgsRef};
 use rustc_apfloat::Float as _;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
@@ -226,14 +226,14 @@ impl<'tcx> TyCtxt<'tcx> {
                 return Ty::new_error(self, reported);
             }
             match *ty.kind() {
-                ty::Adt(def, substs) => {
+                ty::Adt(def, args) => {
                     if !def.is_struct() {
                         break;
                     }
                     match def.non_enum_variant().tail_opt() {
                         Some(field) => {
                             f();
-                            ty = field.ty(self, substs);
+                            ty = field.ty(self, args);
                         }
                         None => break,
                     }
@@ -301,12 +301,12 @@ impl<'tcx> TyCtxt<'tcx> {
         let (mut a, mut b) = (source, target);
         loop {
             match (&a.kind(), &b.kind()) {
-                (&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs))
+                (&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args))
                     if a_def == b_def && a_def.is_struct() =>
                 {
                     if let Some(f) = a_def.non_enum_variant().tail_opt() {
-                        a = f.ty(self, a_substs);
-                        b = f.ty(self, b_substs);
+                        a = f.ty(self, a_args);
+                        b = f.ty(self, b_args);
                     } else {
                         break;
                     }
@@ -349,7 +349,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let drop_trait = self.lang_items().drop_trait()?;
         self.ensure().coherent_trait(drop_trait);
 
-        let ty = self.type_of(adt_did).subst_identity();
+        let ty = self.type_of(adt_did).instantiate_identity();
         let mut dtor_candidate = None;
         self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
             if validate(self, impl_did).is_err() {
@@ -384,7 +384,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Note that this returns only the constraints for the
     /// destructor of `def` itself. For the destructors of the
     /// contents, you need `adt_dtorck_constraint`.
-    pub fn destructor_constraints(self, def: ty::AdtDef<'tcx>) -> Vec<ty::subst::GenericArg<'tcx>> {
+    pub fn destructor_constraints(self, def: ty::AdtDef<'tcx>) -> Vec<ty::GenericArg<'tcx>> {
         let dtor = match def.destructor(self) {
             None => {
                 debug!("destructor_constraints({:?}) - no dtor", def.did());
@@ -401,7 +401,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // must be live.
 
         // We need to return the list of parameters from the ADTs
-        // generics/substs that correspond to impure parameters on the
+        // generics/args that correspond to impure parameters on the
         // impl's generics. This is a bit ugly, but conceptually simple:
         //
         // Suppose our ADT looks like the following
@@ -413,21 +413,21 @@ impl<'tcx> TyCtxt<'tcx> {
         //     impl<#[may_dangle] P0, P1, P2> Drop for S<P1, P2, P0>
         //
         // We want to return the parameters (X, Y). For that, we match
-        // up the item-substs <X, Y, Z> with the substs on the impl ADT,
-        // <P1, P2, P0>, and then look up which of the impl substs refer to
+        // up the item-args <X, Y, Z> with the args on the impl ADT,
+        // <P1, P2, P0>, and then look up which of the impl args refer to
         // parameters marked as pure.
 
-        let impl_substs = match *self.type_of(impl_def_id).subst_identity().kind() {
-            ty::Adt(def_, substs) if def_ == def => substs,
+        let impl_args = match *self.type_of(impl_def_id).instantiate_identity().kind() {
+            ty::Adt(def_, args) if def_ == def => args,
             _ => bug!(),
         };
 
-        let item_substs = match *self.type_of(def.did()).subst_identity().kind() {
-            ty::Adt(def_, substs) if def_ == def => substs,
+        let item_args = match *self.type_of(def.did()).instantiate_identity().kind() {
+            ty::Adt(def_, args) if def_ == def => args,
             _ => bug!(),
         };
 
-        let result = iter::zip(item_substs, impl_substs)
+        let result = iter::zip(item_args, impl_args)
             .filter(|&(_, k)| {
                 match k.unpack() {
                     GenericArgKind::Lifetime(region) => match region.kind() {
@@ -460,12 +460,12 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Checks whether each generic argument is simply a unique generic parameter.
     pub fn uses_unique_generic_params(
         self,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
         ignore_regions: CheckRegions,
     ) -> Result<(), NotUniqueParam<'tcx>> {
         let mut seen = GrowableBitSet::default();
         let mut seen_late = FxHashSet::default();
-        for arg in substs {
+        for arg in args {
             match arg.unpack() {
                 GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) {
                     (CheckRegions::Bound, ty::ReLateBound(di, reg)) => {
@@ -511,10 +511,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// for better caching.
     pub fn uses_unique_placeholders_ignoring_regions(
         self,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) -> Result<(), NotUniqueParam<'tcx>> {
         let mut seen = GrowableBitSet::default();
-        for arg in substs {
+        for arg in args {
             match arg.unpack() {
                 // Ignore regions, since we can't resolve those in a canonicalized
                 // query in the trait solver.
@@ -595,7 +595,7 @@ impl<'tcx> TyCtxt<'tcx> {
         def_id
     }
 
-    /// Given the `DefId` and substs a closure, creates the type of
+    /// Given the `DefId` and args a closure, creates the type of
     /// `self` argument that the closure expects. For example, for a
     /// `Fn` closure, this would return a reference type `&T` where
     /// `T = closure_ty`.
@@ -608,11 +608,11 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn closure_env_ty(
         self,
         closure_def_id: DefId,
-        closure_substs: SubstsRef<'tcx>,
+        closure_args: GenericArgsRef<'tcx>,
         env_region: ty::Region<'tcx>,
     ) -> Option<Ty<'tcx>> {
-        let closure_ty = Ty::new_closure(self, closure_def_id, closure_substs);
-        let closure_kind_ty = closure_substs.as_closure().kind_ty();
+        let closure_ty = Ty::new_closure(self, closure_def_id, closure_args);
+        let closure_kind_ty = closure_args.as_closure().kind_ty();
         let closure_kind = closure_kind_ty.to_opt_closure_kind()?;
         let env_ty = match closure_kind {
             ty::ClosureKind::Fn => Ty::new_imm_ref(self, env_region, closure_ty),
@@ -655,7 +655,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Returns the type a reference to the thread local takes in MIR.
     pub fn thread_local_ptr_ty(self, def_id: DefId) -> Ty<'tcx> {
-        let static_ty = self.type_of(def_id).subst_identity();
+        let static_ty = self.type_of(def_id).instantiate_identity();
         if self.is_mutable_static(def_id) {
             Ty::new_mut_ptr(self, static_ty)
         } else if self.is_foreign_item(def_id) {
@@ -671,7 +671,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // Make sure that any constants in the static's type are evaluated.
         let static_ty = self.normalize_erasing_regions(
             ty::ParamEnv::empty(),
-            self.type_of(def_id).subst_identity(),
+            self.type_of(def_id).instantiate_identity(),
         );
 
         // Make sure that accesses to unsafe statics end up using raw pointers.
@@ -720,7 +720,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn try_expand_impl_trait_type(
         self,
         def_id: DefId,
-        substs: SubstsRef<'tcx>,
+        args: GenericArgsRef<'tcx>,
     ) -> Result<Ty<'tcx>, Ty<'tcx>> {
         let mut visitor = OpaqueTypeExpander {
             seen_opaque_tys: FxHashSet::default(),
@@ -733,7 +733,7 @@ impl<'tcx> TyCtxt<'tcx> {
             tcx: self,
         };
 
-        let expanded_type = visitor.expand_opaque_ty(def_id, substs).unwrap();
+        let expanded_type = visitor.expand_opaque_ty(def_id, args).unwrap();
         if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) }
     }
 
@@ -800,7 +800,7 @@ struct OpaqueTypeExpander<'tcx> {
     seen_opaque_tys: FxHashSet<DefId>,
     // Cache of all expansions we've seen so far. This is a critical
     // optimization for some large types produced by async fn trees.
-    expanded_cache: FxHashMap<(DefId, SubstsRef<'tcx>), Ty<'tcx>>,
+    expanded_cache: FxHashMap<(DefId, GenericArgsRef<'tcx>), Ty<'tcx>>,
     primary_def_id: Option<DefId>,
     found_recursion: bool,
     found_any_recursion: bool,
@@ -813,19 +813,19 @@ struct OpaqueTypeExpander<'tcx> {
 }
 
 impl<'tcx> OpaqueTypeExpander<'tcx> {
-    fn expand_opaque_ty(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) -> Option<Ty<'tcx>> {
+    fn expand_opaque_ty(&mut self, def_id: DefId, args: GenericArgsRef<'tcx>) -> Option<Ty<'tcx>> {
         if self.found_any_recursion {
             return None;
         }
-        let substs = substs.fold_with(self);
+        let args = args.fold_with(self);
         if !self.check_recursion || self.seen_opaque_tys.insert(def_id) {
-            let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) {
+            let expanded_ty = match self.expanded_cache.get(&(def_id, args)) {
                 Some(expanded_ty) => *expanded_ty,
                 None => {
                     let generic_ty = self.tcx.type_of(def_id);
-                    let concrete_ty = generic_ty.subst(self.tcx, substs);
+                    let concrete_ty = generic_ty.instantiate(self.tcx, args);
                     let expanded_ty = self.fold_ty(concrete_ty);
-                    self.expanded_cache.insert((def_id, substs), expanded_ty);
+                    self.expanded_cache.insert((def_id, args), expanded_ty);
                     expanded_ty
                 }
             };
@@ -842,21 +842,21 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
         }
     }
 
-    fn expand_generator(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) -> Option<Ty<'tcx>> {
+    fn expand_generator(&mut self, def_id: DefId, args: GenericArgsRef<'tcx>) -> Option<Ty<'tcx>> {
         if self.found_any_recursion {
             return None;
         }
-        let substs = substs.fold_with(self);
+        let args = args.fold_with(self);
         if !self.check_recursion || self.seen_opaque_tys.insert(def_id) {
-            let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) {
+            let expanded_ty = match self.expanded_cache.get(&(def_id, args)) {
                 Some(expanded_ty) => *expanded_ty,
                 None => {
                     for bty in self.tcx.generator_hidden_types(def_id) {
-                        let hidden_ty = bty.subst(self.tcx, substs);
+                        let hidden_ty = bty.instantiate(self.tcx, args);
                         self.fold_ty(hidden_ty);
                     }
-                    let expanded_ty = Ty::new_generator_witness_mir(self.tcx, def_id, substs);
-                    self.expanded_cache.insert((def_id, substs), expanded_ty);
+                    let expanded_ty = Ty::new_generator_witness_mir(self.tcx, def_id, args);
+                    self.expanded_cache.insert((def_id, args), expanded_ty);
                     expanded_ty
                 }
             };
@@ -880,16 +880,16 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
     }
 
     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-        let mut t = if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) = *t.kind() {
-            self.expand_opaque_ty(def_id, substs).unwrap_or(t)
+        let mut t = if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) = *t.kind() {
+            self.expand_opaque_ty(def_id, args).unwrap_or(t)
         } else if t.has_opaque_types() || t.has_generators() {
             t.super_fold_with(self)
         } else {
             t
         };
         if self.expand_generators {
-            if let ty::GeneratorWitnessMIR(def_id, substs) = *t.kind() {
-                t = self.expand_generator(def_id, substs).unwrap_or(t);
+            if let ty::GeneratorWitnessMIR(def_id, args) = *t.kind() {
+                t = self.expand_generator(def_id, args).unwrap_or(t);
             }
         }
         t
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index 04a635a6803..7c3d9ed390a 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -1,8 +1,8 @@
 //! An iterator over the type substructure.
 //! WARNING: this does not keep track of the region depth.
 
-use crate::ty::subst::{GenericArg, GenericArgKind};
 use crate::ty::{self, Ty};
+use crate::ty::{GenericArg, GenericArgKind};
 use rustc_data_structures::sso::SsoHashSet;
 use smallvec::SmallVec;
 
@@ -166,33 +166,33 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
                 stack.push(lt.into());
             }
             ty::Alias(_, data) => {
-                stack.extend(data.substs.iter().rev());
+                stack.extend(data.args.iter().rev());
             }
             ty::Dynamic(obj, lt, _) => {
                 stack.push(lt.into());
                 stack.extend(obj.iter().rev().flat_map(|predicate| {
-                    let (substs, opt_ty) = match predicate.skip_binder() {
-                        ty::ExistentialPredicate::Trait(tr) => (tr.substs, None),
-                        ty::ExistentialPredicate::Projection(p) => (p.substs, Some(p.term)),
+                    let (args, opt_ty) = match predicate.skip_binder() {
+                        ty::ExistentialPredicate::Trait(tr) => (tr.args, None),
+                        ty::ExistentialPredicate::Projection(p) => (p.args, Some(p.term)),
                         ty::ExistentialPredicate::AutoTrait(_) =>
                         // Empty iterator
                         {
-                            (ty::InternalSubsts::empty(), None)
+                            (ty::GenericArgs::empty(), None)
                         }
                     };
 
-                    substs.iter().rev().chain(opt_ty.map(|term| match term.unpack() {
+                    args.iter().rev().chain(opt_ty.map(|term| match term.unpack() {
                         ty::TermKind::Ty(ty) => ty.into(),
                         ty::TermKind::Const(ct) => ct.into(),
                     }))
                 }));
             }
-            ty::Adt(_, substs)
-            | ty::Closure(_, substs)
-            | ty::Generator(_, substs, _)
-            | ty::GeneratorWitnessMIR(_, substs)
-            | ty::FnDef(_, substs) => {
-                stack.extend(substs.iter().rev());
+            ty::Adt(_, args)
+            | ty::Closure(_, args)
+            | ty::Generator(_, args, _)
+            | ty::GeneratorWitnessMIR(_, args)
+            | ty::FnDef(_, args) => {
+                stack.extend(args.iter().rev());
             }
             ty::Tuple(ts) => stack.extend(ts.iter().rev().map(GenericArg::from)),
             ty::GeneratorWitness(ts) => {
@@ -233,7 +233,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
                 },
 
                 ty::ConstKind::Unevaluated(ct) => {
-                    stack.extend(ct.substs.iter().rev());
+                    stack.extend(ct.args.iter().rev());
                 }
             }
         }
diff --git a/compiler/rustc_middle/src/util/call_kind.rs b/compiler/rustc_middle/src/util/call_kind.rs
index 98d55ea6d40..4e2a2c6ae0a 100644
--- a/compiler/rustc_middle/src/util/call_kind.rs
+++ b/compiler/rustc_middle/src/util/call_kind.rs
@@ -2,7 +2,7 @@
 //! as well as errors when attempting to call a non-const function in a const
 //! context.
 
-use crate::ty::subst::SubstsRef;
+use crate::ty::GenericArgsRef;
 use crate::ty::{AssocItemContainer, Instance, ParamEnv, Ty, TyCtxt};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{lang_items, LangItem};
@@ -43,7 +43,7 @@ pub enum CallKind<'tcx> {
         self_arg: Option<Ident>,
         desugaring: Option<(CallDesugaringKind, Ty<'tcx>)>,
         method_did: DefId,
-        method_substs: SubstsRef<'tcx>,
+        method_args: GenericArgsRef<'tcx>,
     },
     /// A call to `Fn(..)::call(..)`, desugared from `my_closure(a, b, c)`
     FnCall { fn_trait_id: DefId, self_ty: Ty<'tcx> },
@@ -63,7 +63,7 @@ pub fn call_kind<'tcx>(
     tcx: TyCtxt<'tcx>,
     param_env: ParamEnv<'tcx>,
     method_did: DefId,
-    method_substs: SubstsRef<'tcx>,
+    method_args: GenericArgsRef<'tcx>,
     fn_call_span: Span,
     from_hir_call: bool,
     self_arg: Option<Ident>,
@@ -92,19 +92,19 @@ pub fn call_kind<'tcx>(
     // an FnOnce call, an operator (e.g. `<<`), or a
     // deref coercion.
     let kind = if let Some(trait_id) = fn_call {
-        Some(CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_substs.type_at(0) })
+        Some(CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_args.type_at(0) })
     } else if let Some(trait_id) = operator {
-        Some(CallKind::Operator { self_arg, trait_id, self_ty: method_substs.type_at(0) })
+        Some(CallKind::Operator { self_arg, trait_id, self_ty: method_args.type_at(0) })
     } else if is_deref {
         let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
-            Instance::resolve(tcx, param_env, deref_target, method_substs).transpose()
+            Instance::resolve(tcx, param_env, deref_target, method_args).transpose()
         });
         if let Some(Ok(instance)) = deref_target {
             let deref_target_ty = instance.ty(tcx, param_env);
             Some(CallKind::DerefCoercion {
                 deref_target: tcx.def_span(instance.def_id()),
                 deref_target_ty,
-                self_ty: method_substs.type_at(0),
+                self_ty: method_args.type_at(0),
             })
         } else {
             None
@@ -119,24 +119,24 @@ pub fn call_kind<'tcx>(
         let desugaring = if Some(method_did) == tcx.lang_items().into_iter_fn()
             && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
         {
-            Some((CallDesugaringKind::ForLoopIntoIter, method_substs.type_at(0)))
+            Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0)))
         } else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) {
             if Some(method_did) == tcx.lang_items().branch_fn() {
-                Some((CallDesugaringKind::QuestionBranch, method_substs.type_at(0)))
+                Some((CallDesugaringKind::QuestionBranch, method_args.type_at(0)))
             } else if Some(method_did) == tcx.lang_items().from_residual_fn() {
-                Some((CallDesugaringKind::QuestionFromResidual, method_substs.type_at(0)))
+                Some((CallDesugaringKind::QuestionFromResidual, method_args.type_at(0)))
             } else {
                 None
             }
         } else if Some(method_did) == tcx.lang_items().from_output_fn()
             && fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock)
         {
-            Some((CallDesugaringKind::TryBlockFromOutput, method_substs.type_at(0)))
+            Some((CallDesugaringKind::TryBlockFromOutput, method_args.type_at(0)))
         } else if fn_call_span.is_desugaring(DesugaringKind::Await) {
-            Some((CallDesugaringKind::Await, method_substs.type_at(0)))
+            Some((CallDesugaringKind::Await, method_args.type_at(0)))
         } else {
             None
         };
-        CallKind::Normal { self_arg, desugaring, method_did, method_substs }
+        CallKind::Normal { self_arg, desugaring, method_did, method_args }
     })
 }
diff --git a/compiler/rustc_middle/src/util/find_self_call.rs b/compiler/rustc_middle/src/util/find_self_call.rs
index 0eab0adf07e..1b845334c49 100644
--- a/compiler/rustc_middle/src/util/find_self_call.rs
+++ b/compiler/rustc_middle/src/util/find_self_call.rs
@@ -1,5 +1,5 @@
 use crate::mir::*;
-use crate::ty::subst::SubstsRef;
+use crate::ty::GenericArgsRef;
 use crate::ty::{self, TyCtxt};
 use rustc_span::def_id::DefId;
 
@@ -11,21 +11,21 @@ pub fn find_self_call<'tcx>(
     body: &Body<'tcx>,
     local: Local,
     block: BasicBlock,
-) -> Option<(DefId, SubstsRef<'tcx>)> {
+) -> Option<(DefId, GenericArgsRef<'tcx>)> {
     debug!("find_self_call(local={:?}): terminator={:?}", local, &body[block].terminator);
     if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
         &body[block].terminator
     {
         debug!("find_self_call: func={:?}", func);
         if let Operand::Constant(box Constant { literal, .. }) = func {
-            if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
+            if let ty::FnDef(def_id, fn_args) = *literal.ty().kind() {
                 if let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
                     tcx.opt_associated_item(def_id)
                 {
-                    debug!("find_self_call: args={:?}", args);
+                    debug!("find_self_call: args={:?}", fn_args);
                     if let [Operand::Move(self_place) | Operand::Copy(self_place), ..] = **args {
                         if self_place.as_local() == Some(local) {
-                            return Some((def_id, substs));
+                            return Some((def_id, fn_args));
                         }
                     }
                 }