Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dejargonize subst #120958

Merged
merged 3 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {

// If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably)
// borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`.
// These types seem reasonably opaque enough that they could be substituted with their
// These types seem reasonably opaque enough that they could be instantiated with their
// borrowed variants in a function body when we see a move error.
let borrow_level = match *ty.kind() {
ty::Param(_) => tcx
Expand Down
24 changes: 12 additions & 12 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// be allowed:
/// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }`
///
/// Then we map the regions in both the type and the subst to their
/// Then we map the regions in both the type and the generic parameters to their
/// `external_name` giving `concrete_type = &'a i32`,
/// `args = ['static, 'a]`. This will then allow
/// `infer_opaque_definition_from_instantiation` to determine that
Expand Down Expand Up @@ -77,9 +77,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let args = opaque_type_key.args;
debug!(?concrete_type, ?args);

let mut subst_regions = vec![self.universal_regions.fr_static];
let mut arg_regions = vec![self.universal_regions.fr_static];

let to_universal_region = |vid, subst_regions: &mut Vec<_>| {
let to_universal_region = |vid, arg_regions: &mut Vec<_>| {
trace!(?vid);
let scc = self.constraint_sccs.scc(vid);
trace!(?scc);
Expand All @@ -88,11 +88,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}) {
Some(region) => {
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(vid);
arg_regions.push(vid);
region
}
None => {
subst_regions.push(vid);
arg_regions.push(vid);
ty::Region::new_error_with_message(
infcx.tcx,
concrete_type.span,
Expand All @@ -106,10 +106,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// This will ensure they get precedence when folding the regions in the concrete type.
if let Some(&ci) = member_constraints.get(&opaque_type_key) {
for &vid in self.member_constraints.choice_regions(ci) {
to_universal_region(vid, &mut subst_regions);
to_universal_region(vid, &mut arg_regions);
}
}
debug!(?subst_regions);
debug!(?arg_regions);

// Next, insert universal regions from args, so we can translate regions that appear
// in them but are not subject to member constraints, for instance closure args.
Expand All @@ -119,18 +119,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
return region;
}
let vid = self.to_region_vid(region);
to_universal_region(vid, &mut subst_regions)
to_universal_region(vid, &mut arg_regions)
});
debug!(?universal_args);
debug!(?subst_regions);
debug!(?arg_regions);

// Deduplicate the set of regions while keeping the chosen order.
let subst_regions = subst_regions.into_iter().collect::<FxIndexSet<_>>();
debug!(?subst_regions);
let arg_regions = arg_regions.into_iter().collect::<FxIndexSet<_>>();
debug!(?arg_regions);

let universal_concrete_type =
infcx.tcx.fold_regions(concrete_type, |region, _| match *region {
ty::ReVar(vid) => subst_regions
ty::ReVar(vid) => arg_regions
.iter()
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
.and_then(|ur_vid| self.definitions[*ur_vid].external_name)
Expand Down
15 changes: 9 additions & 6 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,18 +554,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

/// Call this on things you got out of the MIR (so it is as generic as the current
/// stack frame), to bring it into the proper environment for this interpreter.
pub(super) fn subst_from_current_frame_and_normalize_erasing_regions<
pub(super) fn instantiate_from_current_frame_and_normalize_erasing_regions<
T: TypeFoldable<TyCtxt<'tcx>>,
>(
&self,
value: T,
) -> Result<T, ErrorHandled> {
self.subst_from_frame_and_normalize_erasing_regions(self.frame(), value)
self.instantiate_from_frame_and_normalize_erasing_regions(self.frame(), value)
}

/// Call this on things you got out of the MIR (so it is as generic as the provided
/// stack frame), to bring it into the proper environment for this interpreter.
pub(super) fn subst_from_frame_and_normalize_erasing_regions<T: TypeFoldable<TyCtxt<'tcx>>>(
pub(super) fn instantiate_from_frame_and_normalize_erasing_regions<
T: TypeFoldable<TyCtxt<'tcx>>,
>(
&self,
frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>,
value: T,
Expand Down Expand Up @@ -656,7 +658,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

let layout = from_known_layout(self.tcx, self.param_env, layout, || {
let local_ty = frame.body.local_decls[local].ty;
let local_ty = self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
let local_ty =
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
self.layout_of(local_ty)
})?;

Expand Down Expand Up @@ -791,8 +794,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Make sure all the constants required by this frame evaluate successfully (post-monomorphization check).
if M::POST_MONO_CHECKS {
for &const_ in &body.required_consts {
let c =
self.subst_from_current_frame_and_normalize_erasing_regions(const_.const_)?;
let c = self
.instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?;
c.eval(*self.tcx, self.param_env, Some(const_.span)).map_err(|err| {
err.emit_note(*self.tcx);
err
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,9 +696,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
trace!("eval_place_to_op: got {:?}", op);
// Sanity-check the type we ended up with.
if cfg!(debug_assertions) {
let normalized_place_ty = self.subst_from_current_frame_and_normalize_erasing_regions(
mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
)?;
let normalized_place_ty = self
.instantiate_from_current_frame_and_normalize_erasing_regions(
mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
)?;
if !mir_assign_valid_types(
*self.tcx,
self.param_env,
Expand Down Expand Up @@ -731,8 +732,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&Copy(place) | &Move(place) => self.eval_place_to_op(place, layout)?,

Constant(constant) => {
let c =
self.subst_from_current_frame_and_normalize_erasing_regions(constant.const_)?;
let c = self.instantiate_from_current_frame_and_normalize_erasing_regions(
constant.const_,
)?;

// This can still fail:
// * During ConstProp, with `TooGeneric` or since the `required_consts` were not all
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,9 +542,10 @@ where
trace!("{:?}", self.dump_place(&place));
// Sanity-check the type we ended up with.
if cfg!(debug_assertions) {
let normalized_place_ty = self.subst_from_current_frame_and_normalize_erasing_regions(
mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
)?;
let normalized_place_ty = self
.instantiate_from_current_frame_and_normalize_erasing_regions(
mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
)?;
if !mir_assign_valid_types(
*self.tcx,
self.param_env,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}

NullaryOp(ref null_op, ty) => {
let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?;
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
let layout = self.layout_of(ty)?;
if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op
&& layout.is_unsized()
Expand Down Expand Up @@ -276,7 +276,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Cast(cast_kind, ref operand, cast_ty) => {
let src = self.eval_operand(operand, None)?;
let cast_ty =
self.subst_from_current_frame_and_normalize_erasing_regions(cast_ty)?;
self.instantiate_from_current_frame_and_normalize_erasing_regions(cast_ty)?;
self.cast(&src, cast_kind, cast_ty, &dest)?;
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Drop { place, target, unwind, replace: _ } => {
let frame = self.frame();
let ty = place.ty(&frame.body.local_decls, *self.tcx).ty;
let ty = self.subst_from_frame_and_normalize_erasing_regions(frame, ty)?;
let ty = self.instantiate_from_frame_and_normalize_erasing_regions(frame, ty)?;
let instance = Instance::resolve_drop_in_place(*self.tcx, ty);
if let ty::InstanceDef::DropGlue(_, None) = instance.def {
// This is the branch we enter if and only if the dropped type has no drop glue
Expand Down Expand Up @@ -672,8 +672,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Construct the destination place for this argument. At this point all
// locals are still dead, so we cannot construct a `PlaceTy`.
let dest = mir::Place::from(local);
// `layout_of_local` does more than just the substitution we need to get the
// type, but the result gets cached so this avoids calling the substitution
// `layout_of_local` does more than just the instantiation we need to get the
// type, but the result gets cached so this avoids calling the instantiation
// query *again* the next time this local is accessed.
let ty = self.layout_of_local(self.frame(), local, None)?.ty;
if Some(local) == body.spread_arg {
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_const_eval/src/interpret/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ where
}

struct FoundParam;
struct UsedParamsNeedSubstVisitor<'tcx> {
struct UsedParamsNeedInstantiationVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
}

impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedSubstVisitor<'tcx> {
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> {
type BreakTy = FoundParam;

fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
Expand All @@ -38,17 +38,17 @@ where
| ty::FnDef(def_id, args) => {
let instance = ty::InstanceDef::Item(def_id);
let unused_params = self.tcx.unused_generic_params(instance);
for (index, subst) in args.into_iter().enumerate() {
for (index, arg) in args.into_iter().enumerate() {
let index = index
.try_into()
.expect("more generic parameters than can fit into a `u32`");
// Only recurse when generic parameters in fns, closures and coroutines
// are used and have to be instantiated.
//
// Just in case there are closures or coroutines within this subst,
// Just in case there are closures or coroutines within this arg,
// recurse.
if unused_params.is_used(index) && subst.has_param() {
return subst.visit_with(self);
if unused_params.is_used(index) && arg.has_param() {
return arg.visit_with(self);
}
}
ControlFlow::Continue(())
Expand All @@ -65,7 +65,7 @@ where
}
}

let mut vis = UsedParamsNeedSubstVisitor { tcx };
let mut vis = UsedParamsNeedInstantiationVisitor { tcx };
if matches!(ty.visit_with(&mut vis), ControlFlow::Break(FoundParam)) {
throw_inval!(TooGeneric);
} else {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_error_codes/src/error_codes/E0139.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ fn foo<T>(x: Vec<T>) {
In this specific case there's a good chance that the transmute is harmless (but
this is not guaranteed by Rust). However, when alignment and enum optimizations
come into the picture, it's quite likely that the sizes may or may not match
with different type parameter substitutions. It's not possible to check this for
_all_ possible types, so `transmute()` simply only accepts types without any
unsubstituted type parameters.
with different type parameter instantiations. It's not possible to check this
for _all_ possible types, so `transmute()` simply only accepts types without any
uninstantiated type parameters.

If you need this, there's a good chance you're doing something wrong. Keep in
mind that Rust doesn't guarantee much about the layout of different structs
(even two structs with identical declarations may have different layouts). If
there is a solution that avoids the transmute entirely, try it instead.

If it's possible, hand-monomorphize the code by writing the function for each
possible type substitution. It's possible to use traits to do this cleanly,
possible type instantiation. It's possible to use traits to do this cleanly,
for example:

```
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_error_codes/src/error_codes/E0230.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ There will be an error about `bool` not implementing `Index<u8>`, followed by a
note saying "the type `bool` cannot be indexed by `u8`".

As you can see, you can specify type parameters in curly braces for
substitution with the actual types (using the regular format string syntax) in
a given situation. Furthermore, `{Self}` will substitute to the type (in this
case, `bool`) that we tried to use.
instantiation with the actual types (using the regular format string syntax) in
a given situation. Furthermore, `{Self}` will be instantiated to the type (in
this case, `bool`) that we tried to use.

This error appears when the curly braces contain an identifier which doesn't
match with any of the type parameters or the string `Self`. This might happen
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_error_codes/src/error_codes/E0231.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ there will be an error about `bool` not implementing `Index<u8>`, followed by a
note saying "the type `bool` cannot be indexed by `u8`".

As you can see, you can specify type parameters in curly braces for
substitution with the actual types (using the regular format string syntax) in
a given situation. Furthermore, `{Self}` will substitute to the type (in this
case, `bool`) that we tried to use.
instantiation with the actual types (using the regular format string syntax) in
a given situation. Furthermore, `{Self}` will be instantiated to the type (in
this case, `bool`) that we tried to use.

This error appears when the curly braces do not contain an identifier. Please
add one of the same name as a type parameter. If you intended to use literal
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0393.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ fn together_we_will_rule_the_galaxy(son: &A) {}
```

A trait object is defined over a single, fully-defined trait. With a regular
default parameter, this parameter can just be substituted in. However, if the
default parameter, this parameter can just be instantiated in. However, if the
default parameter is `Self`, the trait changes for each concrete type; i.e.
`i32` will be expected to implement `A<i32>`, `bool` will be expected to
implement `A<bool>`, etc... These types will not share an implementation of a
fully-defined trait; instead they share implementations of a trait with
different parameters substituted in for each implementation. This is
different parameters instantiated in for each implementation. This is
irreconcilable with what we need to make a trait object work, and is thus
disallowed. Making the trait concrete by explicitly specifying the value of the
defaulted parameter will fix this issue. Fixed example:
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0794.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ let _ = foo::<'static>;

The type of a concrete instance of a generic function is universally quantified
over late-bound lifetime parameters. This is because we want the function to
work for any lifetime substituted for the late-bound lifetime parameter, no
work for any lifetime instantiated for the late-bound lifetime parameter, no
matter where the function is called. Consequently, it doesn't make sense to
specify arguments for late-bound lifetime parameters, since they are not
resolved until the function's call site(s).
Expand Down Expand Up @@ -56,7 +56,7 @@ let bar_fn3 = bar::<Bar>; // OK

In the definition of `bar`, the lifetime parameter `'a` is late-bound, while
`'b` is early-bound. This is reflected in the type annotation for `bar_fn`,
where `'a` is universally quantified and `'b` is substituted by a specific
where `'a` is universally quantified and `'b` is instantiated with a specific
lifetime. It is not allowed to explicitly specify early-bound lifetime
arguments when late-bound lifetime parameters are present (as for `bar_fn2`,
see [issue #42868](https://github.com/rust-lang/rust/issues/42868)), although
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2536,7 +2536,7 @@ pub struct OpaqueTy<'hir> {
/// lifetimes that are captured from the function signature they originate from.
///
/// This is done by generating a new early-bound lifetime parameter local to the
/// opaque which is substituted in the function signature with the late-bound
/// opaque which is instantiated in the function signature with the late-bound
/// lifetime.
///
/// This mapping associated a captured lifetime (first parameter) with the new
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ hir_analysis_function_not_have_default_implementation = function doesn't have a
hir_analysis_functions_names_duplicated = functions names are duplicated
.note = all `#[rustc_must_implement_one_of]` arguments must be unique

hir_analysis_generic_args_on_overridden_impl = could not resolve generic parameters on overridden impl

hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
.label = cannot specialize default item `{$ident}`
.ok_label = parent `impl` is here
Expand Down Expand Up @@ -365,8 +367,6 @@ hir_analysis_static_mut_ref_lint = {$shared}reference of mutable static is disco

hir_analysis_static_specialize = cannot specialize on `'static` lifetime

hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl

hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
.note = this item must mention the opaque type in its signature in order to be able to register hidden types

Expand Down
Loading
Loading