Auto merge of #141506 - matthiaskrgr:rollup-80f1geg, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #137323 (Guarantee behavior of transmuting `Option::<T>::None` subject to NPO) - #139254 (std: sys: net: uefi: Implement TCP4 connect) - #141432 (refactor `CanonicalVarKind`) - #141480 (document some -Z flags as living in the rustc-dev-guide) - #141486 (rustdoc book: add argument explanation for `html_playground_url`) - #141496 (Enable `[issue-links]` and `[no-mentions]` in triagebot) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
038d599eda
28 changed files with 450 additions and 295 deletions
|
|
@ -17,8 +17,7 @@ use tracing::debug;
|
|||
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::infer::canonical::{
|
||||
Canonical, CanonicalQueryInput, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind,
|
||||
OriginalQueryValues,
|
||||
Canonical, CanonicalQueryInput, CanonicalTyVarKind, CanonicalVarKind, OriginalQueryValues,
|
||||
};
|
||||
|
||||
impl<'tcx> InferCtxt<'tcx> {
|
||||
|
|
@ -174,10 +173,8 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
|
|||
match r.kind() {
|
||||
ty::ReLateParam(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyParam(..) => r,
|
||||
|
||||
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(placeholder) },
|
||||
r,
|
||||
),
|
||||
ty::RePlaceholder(placeholder) => canonicalizer
|
||||
.canonical_var_for_region(CanonicalVarKind::PlaceholderRegion(placeholder), r),
|
||||
|
||||
ty::ReVar(vid) => {
|
||||
let universe = infcx
|
||||
|
|
@ -186,10 +183,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
|
|||
.unwrap_region_constraints()
|
||||
.probe_value(vid)
|
||||
.unwrap_err();
|
||||
canonicalizer.canonical_var_for_region(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) },
|
||||
r,
|
||||
)
|
||||
canonicalizer.canonical_var_for_region(CanonicalVarKind::Region(universe), r)
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
|
@ -294,7 +288,7 @@ struct Canonicalizer<'cx, 'tcx> {
|
|||
/// Set to `None` to disable the resolution of inference variables.
|
||||
infcx: Option<&'cx InferCtxt<'tcx>>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
variables: SmallVec<[CanonicalVarInfo<'tcx>; 8]>,
|
||||
variables: SmallVec<[CanonicalVarKind<'tcx>; 8]>,
|
||||
query_state: &'cx mut OriginalQueryValues<'tcx>,
|
||||
// Note that indices is only used once `var_values` is big enough to be
|
||||
// heap-allocated.
|
||||
|
|
@ -368,9 +362,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
|||
ui = ty::UniverseIndex::ROOT;
|
||||
}
|
||||
self.canonicalize_ty_var(
|
||||
CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
||||
},
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
||||
t,
|
||||
)
|
||||
}
|
||||
|
|
@ -382,10 +374,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
|||
if nt != t {
|
||||
return self.fold_ty(nt);
|
||||
} else {
|
||||
self.canonicalize_ty_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
|
||||
t,
|
||||
)
|
||||
self.canonicalize_ty_var(CanonicalVarKind::Ty(CanonicalTyVarKind::Int), t)
|
||||
}
|
||||
}
|
||||
ty::Infer(ty::FloatVar(vid)) => {
|
||||
|
|
@ -393,10 +382,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
|||
if nt != t {
|
||||
return self.fold_ty(nt);
|
||||
} else {
|
||||
self.canonicalize_ty_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
|
||||
t,
|
||||
)
|
||||
self.canonicalize_ty_var(CanonicalVarKind::Ty(CanonicalTyVarKind::Float), t)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -408,10 +394,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
|||
if !self.canonicalize_mode.preserve_universes() {
|
||||
placeholder.universe = ty::UniverseIndex::ROOT;
|
||||
}
|
||||
self.canonicalize_ty_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) },
|
||||
t,
|
||||
)
|
||||
self.canonicalize_ty_var(CanonicalVarKind::PlaceholderTy(placeholder), t)
|
||||
}
|
||||
|
||||
ty::Bound(debruijn, _) => {
|
||||
|
|
@ -483,10 +466,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
|||
// FIXME: perf problem described in #55921.
|
||||
ui = ty::UniverseIndex::ROOT;
|
||||
}
|
||||
return self.canonicalize_const_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
|
||||
ct,
|
||||
);
|
||||
return self.canonicalize_const_var(CanonicalVarKind::Const(ui), ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -501,10 +481,8 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
ty::ConstKind::Placeholder(placeholder) => {
|
||||
return self.canonicalize_const_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderConst(placeholder) },
|
||||
ct,
|
||||
);
|
||||
return self
|
||||
.canonicalize_const_var(CanonicalVarKind::PlaceholderConst(placeholder), ct);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -595,7 +573,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
debug_assert!(!out_value.has_infer() && !out_value.has_placeholders());
|
||||
|
||||
let canonical_variables =
|
||||
tcx.mk_canonical_var_infos(&canonicalizer.universe_canonicalized_variables());
|
||||
tcx.mk_canonical_var_kinds(&canonicalizer.universe_canonicalized_variables());
|
||||
|
||||
let max_universe = canonical_variables
|
||||
.iter()
|
||||
|
|
@ -610,18 +588,22 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
/// or returns an existing variable if `kind` has already been
|
||||
/// seen. `kind` is expected to be an unbound variable (or
|
||||
/// potentially a free region).
|
||||
fn canonical_var(&mut self, info: CanonicalVarInfo<'tcx>, kind: GenericArg<'tcx>) -> BoundVar {
|
||||
fn canonical_var(
|
||||
&mut self,
|
||||
var_kind: CanonicalVarKind<'tcx>,
|
||||
value: GenericArg<'tcx>,
|
||||
) -> BoundVar {
|
||||
let Canonicalizer { variables, query_state, indices, .. } = self;
|
||||
|
||||
let var_values = &mut query_state.var_values;
|
||||
|
||||
let universe = info.universe();
|
||||
let universe = var_kind.universe();
|
||||
if universe != ty::UniverseIndex::ROOT {
|
||||
assert!(self.canonicalize_mode.preserve_universes());
|
||||
|
||||
// Insert universe into the universe map. To preserve the order of the
|
||||
// universes in the value being canonicalized, we don't update the
|
||||
// universe in `info` until we have finished canonicalizing.
|
||||
// universe in `var_kind` until we have finished canonicalizing.
|
||||
match query_state.universe_map.binary_search(&universe) {
|
||||
Err(idx) => query_state.universe_map.insert(idx, universe),
|
||||
Ok(_) => {}
|
||||
|
|
@ -636,14 +618,14 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
if !var_values.spilled() {
|
||||
// `var_values` is stack-allocated. `indices` isn't used yet. Do a
|
||||
// direct linear search of `var_values`.
|
||||
if let Some(idx) = var_values.iter().position(|&k| k == kind) {
|
||||
if let Some(idx) = var_values.iter().position(|&v| v == value) {
|
||||
// `kind` is already present in `var_values`.
|
||||
BoundVar::new(idx)
|
||||
} else {
|
||||
// `kind` isn't present in `var_values`. Append it. Likewise
|
||||
// for `info` and `variables`.
|
||||
variables.push(info);
|
||||
var_values.push(kind);
|
||||
// for `var_kind` and `variables`.
|
||||
variables.push(var_kind);
|
||||
var_values.push(value);
|
||||
assert_eq!(variables.len(), var_values.len());
|
||||
|
||||
// If `var_values` has become big enough to be heap-allocated,
|
||||
|
|
@ -653,7 +635,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
*indices = var_values
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, &kind)| (kind, BoundVar::new(i)))
|
||||
.map(|(i, &value)| (value, BoundVar::new(i)))
|
||||
.collect();
|
||||
}
|
||||
// The cv is the index of the appended element.
|
||||
|
|
@ -661,9 +643,9 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
}
|
||||
} else {
|
||||
// `var_values` is large. Do a hashmap search via `indices`.
|
||||
*indices.entry(kind).or_insert_with(|| {
|
||||
variables.push(info);
|
||||
var_values.push(kind);
|
||||
*indices.entry(value).or_insert_with(|| {
|
||||
variables.push(var_kind);
|
||||
var_values.push(value);
|
||||
assert_eq!(variables.len(), var_values.len());
|
||||
BoundVar::new(variables.len() - 1)
|
||||
})
|
||||
|
|
@ -673,7 +655,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
/// Replaces the universe indexes used in `var_values` with their index in
|
||||
/// `query_state.universe_map`. This minimizes the maximum universe used in
|
||||
/// the canonicalized value.
|
||||
fn universe_canonicalized_variables(self) -> SmallVec<[CanonicalVarInfo<'tcx>; 8]> {
|
||||
fn universe_canonicalized_variables(self) -> SmallVec<[CanonicalVarKind<'tcx>; 8]> {
|
||||
if self.query_state.universe_map.len() == 1 {
|
||||
return self.variables;
|
||||
}
|
||||
|
|
@ -688,37 +670,33 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
|
||||
self.variables
|
||||
.iter()
|
||||
.map(|v| CanonicalVarInfo {
|
||||
kind: match v.kind {
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
|
||||
return *v;
|
||||
}
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => {
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(reverse_universe_map[&u]))
|
||||
}
|
||||
CanonicalVarKind::Region(u) => {
|
||||
CanonicalVarKind::Region(reverse_universe_map[&u])
|
||||
}
|
||||
CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]),
|
||||
CanonicalVarKind::PlaceholderTy(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderTy(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
}
|
||||
CanonicalVarKind::PlaceholderRegion(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderRegion(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
}
|
||||
CanonicalVarKind::PlaceholderConst(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderConst(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
}
|
||||
},
|
||||
.map(|&kind| match kind {
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
|
||||
return kind;
|
||||
}
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => {
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::General(reverse_universe_map[&u]))
|
||||
}
|
||||
CanonicalVarKind::Region(u) => CanonicalVarKind::Region(reverse_universe_map[&u]),
|
||||
CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]),
|
||||
CanonicalVarKind::PlaceholderTy(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderTy(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
}
|
||||
CanonicalVarKind::PlaceholderRegion(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderRegion(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
}
|
||||
CanonicalVarKind::PlaceholderConst(placeholder) => {
|
||||
CanonicalVarKind::PlaceholderConst(ty::Placeholder {
|
||||
universe: reverse_universe_map[&placeholder.universe],
|
||||
..placeholder
|
||||
})
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
@ -740,20 +718,17 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
&mut self,
|
||||
r: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
self.canonical_var_for_region(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Region(ty::UniverseIndex::ROOT) },
|
||||
r,
|
||||
)
|
||||
self.canonical_var_for_region(CanonicalVarKind::Region(ty::UniverseIndex::ROOT), r)
|
||||
}
|
||||
|
||||
/// Creates a canonical variable (with the given `info`)
|
||||
/// representing the region `r`; return a region referencing it.
|
||||
fn canonical_var_for_region(
|
||||
&mut self,
|
||||
info: CanonicalVarInfo<'tcx>,
|
||||
var_kind: CanonicalVarKind<'tcx>,
|
||||
r: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
let var = self.canonical_var(info, r.into());
|
||||
let var = self.canonical_var(var_kind, r.into());
|
||||
let br = ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon };
|
||||
ty::Region::new_bound(self.cx(), self.binder_index, br)
|
||||
}
|
||||
|
|
@ -762,9 +737,13 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
/// if `ty_var` is bound to anything; if so, canonicalize
|
||||
/// *that*. Otherwise, create a new canonical variable for
|
||||
/// `ty_var`.
|
||||
fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo<'tcx>, ty_var: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn canonicalize_ty_var(
|
||||
&mut self,
|
||||
var_kind: CanonicalVarKind<'tcx>,
|
||||
ty_var: Ty<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
debug_assert!(!self.infcx.is_some_and(|infcx| ty_var != infcx.shallow_resolve(ty_var)));
|
||||
let var = self.canonical_var(info, ty_var.into());
|
||||
let var = self.canonical_var(var_kind, ty_var.into());
|
||||
Ty::new_bound(self.tcx, self.binder_index, var.into())
|
||||
}
|
||||
|
||||
|
|
@ -774,13 +753,13 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
|||
/// `const_var`.
|
||||
fn canonicalize_const_var(
|
||||
&mut self,
|
||||
info: CanonicalVarInfo<'tcx>,
|
||||
const_var: ty::Const<'tcx>,
|
||||
var_kind: CanonicalVarKind<'tcx>,
|
||||
ct_var: ty::Const<'tcx>,
|
||||
) -> ty::Const<'tcx> {
|
||||
debug_assert!(
|
||||
!self.infcx.is_some_and(|infcx| const_var != infcx.shallow_resolve_const(const_var))
|
||||
!self.infcx.is_some_and(|infcx| ct_var != infcx.shallow_resolve_const(ct_var))
|
||||
);
|
||||
let var = self.canonical_var(info, const_var.into());
|
||||
let var = self.canonical_var(var_kind, ct_var.into());
|
||||
ty::Const::new_bound(self.tcx, self.binder_index, var)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,14 +81,14 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
fn instantiate_canonical_vars(
|
||||
&self,
|
||||
span: Span,
|
||||
variables: &List<CanonicalVarInfo<'tcx>>,
|
||||
variables: &List<CanonicalVarKind<'tcx>>,
|
||||
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
|
||||
) -> CanonicalVarValues<'tcx> {
|
||||
CanonicalVarValues {
|
||||
var_values: self.tcx.mk_args_from_iter(
|
||||
variables
|
||||
.iter()
|
||||
.map(|info| self.instantiate_canonical_var(span, info, &universe_map)),
|
||||
.map(|kind| self.instantiate_canonical_var(span, kind, &universe_map)),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
@ -104,10 +104,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
pub fn instantiate_canonical_var(
|
||||
&self,
|
||||
span: Span,
|
||||
cv_info: CanonicalVarInfo<'tcx>,
|
||||
kind: CanonicalVarKind<'tcx>,
|
||||
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
|
||||
) -> GenericArg<'tcx> {
|
||||
match cv_info.kind {
|
||||
match kind {
|
||||
CanonicalVarKind::Ty(ty_kind) => {
|
||||
let ty = match ty_kind {
|
||||
CanonicalTyVarKind::General(ui) => {
|
||||
|
|
|
|||
|
|
@ -445,17 +445,17 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// a fresh inference variable.
|
||||
let result_args = CanonicalVarValues {
|
||||
var_values: self.tcx.mk_args_from_iter(
|
||||
query_response.variables.iter().enumerate().map(|(index, info)| {
|
||||
if info.universe() != ty::UniverseIndex::ROOT {
|
||||
query_response.variables.iter().enumerate().map(|(index, var_kind)| {
|
||||
if var_kind.universe() != ty::UniverseIndex::ROOT {
|
||||
// A variable from inside a binder of the query. While ideally these shouldn't
|
||||
// exist at all, we have to deal with them for now.
|
||||
self.instantiate_canonical_var(cause.span, info, |u| {
|
||||
self.instantiate_canonical_var(cause.span, var_kind, |u| {
|
||||
universe_map[u.as_usize()]
|
||||
})
|
||||
} else if info.is_existential() {
|
||||
} else if var_kind.is_existential() {
|
||||
match opt_values[BoundVar::new(index)] {
|
||||
Some(k) => k,
|
||||
None => self.instantiate_canonical_var(cause.span, info, |u| {
|
||||
None => self.instantiate_canonical_var(cause.span, var_kind, |u| {
|
||||
universe_map[u.as_usize()]
|
||||
}),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use rustc_data_structures::fx::FxHashMap;
|
|||
use rustc_data_structures::sync::Lock;
|
||||
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
|
||||
pub use rustc_type_ir as ir;
|
||||
pub use rustc_type_ir::{CanonicalTyVarKind, CanonicalVarKind};
|
||||
pub use rustc_type_ir::CanonicalTyVarKind;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::mir::ConstraintCategory;
|
||||
|
|
@ -35,9 +35,9 @@ use crate::ty::{self, GenericArg, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt}
|
|||
|
||||
pub type CanonicalQueryInput<'tcx, V> = ir::CanonicalQueryInput<TyCtxt<'tcx>, V>;
|
||||
pub type Canonical<'tcx, V> = ir::Canonical<TyCtxt<'tcx>, V>;
|
||||
pub type CanonicalVarInfo<'tcx> = ir::CanonicalVarInfo<TyCtxt<'tcx>>;
|
||||
pub type CanonicalVarKind<'tcx> = ir::CanonicalVarKind<TyCtxt<'tcx>>;
|
||||
pub type CanonicalVarValues<'tcx> = ir::CanonicalVarValues<TyCtxt<'tcx>>;
|
||||
pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>;
|
||||
pub type CanonicalVarKinds<'tcx> = &'tcx List<CanonicalVarKind<'tcx>>;
|
||||
|
||||
/// When we canonicalize a value to form a query, we wind up replacing
|
||||
/// various parts of it with canonical variables. This struct stores
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use rustc_span::source_map::Spanned;
|
|||
use rustc_span::{Span, SpanDecoder, SpanEncoder};
|
||||
|
||||
use crate::arena::ArenaAllocatable;
|
||||
use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
|
||||
use crate::infer::canonical::{CanonicalVarKind, CanonicalVarKinds};
|
||||
use crate::mir::interpret::{AllocId, ConstAllocation, CtfeProvenance};
|
||||
use crate::mir::mono::MonoItem;
|
||||
use crate::mir::{self};
|
||||
|
|
@ -310,11 +310,11 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Region<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarInfos<'tcx> {
|
||||
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarKinds<'tcx> {
|
||||
fn decode(decoder: &mut D) -> Self {
|
||||
let len = decoder.read_usize();
|
||||
decoder.interner().mk_canonical_var_infos_from_iter(
|
||||
(0..len).map::<CanonicalVarInfo<'tcx>, _>(|_| Decodable::decode(decoder)),
|
||||
(0..len).map::<CanonicalVarKind<'tcx>, _>(|_| Decodable::decode(decoder)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ use tracing::{debug, instrument};
|
|||
|
||||
use crate::arena::Arena;
|
||||
use crate::dep_graph::{DepGraph, DepKindStruct};
|
||||
use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
|
||||
use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind, CanonicalVarKinds};
|
||||
use crate::lint::lint_level;
|
||||
use crate::metadata::ModChild;
|
||||
use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
|
||||
|
|
@ -107,9 +107,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
self.mk_predefined_opaques_in_body(data)
|
||||
}
|
||||
type LocalDefIds = &'tcx ty::List<LocalDefId>;
|
||||
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
||||
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
|
||||
self.mk_canonical_var_infos(infos)
|
||||
type CanonicalVarKinds = CanonicalVarKinds<'tcx>;
|
||||
fn mk_canonical_var_kinds(
|
||||
self,
|
||||
kinds: &[ty::CanonicalVarKind<Self>],
|
||||
) -> Self::CanonicalVarKinds {
|
||||
self.mk_canonical_var_kinds(kinds)
|
||||
}
|
||||
|
||||
type ExternalConstraints = ExternalConstraints<'tcx>;
|
||||
|
|
@ -833,7 +836,7 @@ pub struct CtxtInterners<'tcx> {
|
|||
const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
|
||||
args: InternedSet<'tcx, GenericArgs<'tcx>>,
|
||||
type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
|
||||
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
|
||||
canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
|
||||
region: InternedSet<'tcx, RegionKind<'tcx>>,
|
||||
poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
|
||||
predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
|
||||
|
|
@ -872,7 +875,7 @@ impl<'tcx> CtxtInterners<'tcx> {
|
|||
type_lists: InternedSet::with_capacity(N * 4),
|
||||
region: InternedSet::with_capacity(N * 4),
|
||||
poly_existential_predicates: InternedSet::with_capacity(N / 4),
|
||||
canonical_var_infos: InternedSet::with_capacity(N / 2),
|
||||
canonical_var_kinds: InternedSet::with_capacity(N / 2),
|
||||
predicate: InternedSet::with_capacity(N),
|
||||
clauses: InternedSet::with_capacity(N),
|
||||
projs: InternedSet::with_capacity(N * 4),
|
||||
|
|
@ -2675,7 +2678,7 @@ slice_interners!(
|
|||
const_lists: pub mk_const_list(Const<'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>),
|
||||
canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
|
||||
poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
|
||||
projs: pub mk_projs(ProjectionKind),
|
||||
place_elems: pub mk_place_elems(PlaceElem<'tcx>),
|
||||
|
|
@ -3055,9 +3058,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: CollectAndApply<CanonicalVarInfo<'tcx>, &'tcx List<CanonicalVarInfo<'tcx>>>,
|
||||
T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
|
||||
{
|
||||
T::collect_and_apply(iter, |xs| self.mk_canonical_var_infos(xs))
|
||||
T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
|
||||
}
|
||||
|
||||
pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack};
|
|||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::solve::{Goal, QueryInput};
|
||||
use rustc_type_ir::{
|
||||
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, InferCtxtLike,
|
||||
Interner, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
||||
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarKind, InferCtxtLike, Interner,
|
||||
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
||||
};
|
||||
|
||||
use crate::delegate::SolverDelegate;
|
||||
|
|
@ -50,7 +50,7 @@ pub struct Canonicalizer<'a, D: SolverDelegate<Interner = I>, I: Interner> {
|
|||
|
||||
// Mutable fields.
|
||||
variables: &'a mut Vec<I::GenericArg>,
|
||||
primitive_var_infos: Vec<CanonicalVarInfo<I>>,
|
||||
var_kinds: Vec<CanonicalVarKind<I>>,
|
||||
variable_lookup_table: HashMap<I::GenericArg, usize>,
|
||||
binder_index: ty::DebruijnIndex,
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
|
||||
variables,
|
||||
variable_lookup_table: Default::default(),
|
||||
primitive_var_infos: Vec::new(),
|
||||
var_kinds: Vec::new(),
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
cache: Default::default(),
|
||||
|
|
@ -106,7 +106,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
|
||||
variables,
|
||||
variable_lookup_table: Default::default(),
|
||||
primitive_var_infos: Vec::new(),
|
||||
var_kinds: Vec::new(),
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
cache: Default::default(),
|
||||
|
|
@ -123,7 +123,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
// We're able to reuse the `variable_lookup_table` as whether or not
|
||||
// it already contains an entry for `'static` does not matter.
|
||||
variable_lookup_table: env_canonicalizer.variable_lookup_table,
|
||||
primitive_var_infos: env_canonicalizer.primitive_var_infos,
|
||||
var_kinds: env_canonicalizer.var_kinds,
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
// We do not reuse the cache as it may contain entries whose canonicalized
|
||||
|
|
@ -149,7 +149,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
fn get_or_insert_bound_var(
|
||||
&mut self,
|
||||
arg: impl Into<I::GenericArg>,
|
||||
canonical_var_info: CanonicalVarInfo<I>,
|
||||
kind: CanonicalVarKind<I>,
|
||||
) -> ty::BoundVar {
|
||||
// FIXME: 16 is made up and arbitrary. We should look at some
|
||||
// perf data here.
|
||||
|
|
@ -162,14 +162,14 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
*self.variable_lookup_table.entry(arg).or_insert_with(|| {
|
||||
let var = self.variables.len();
|
||||
self.variables.push(arg);
|
||||
self.primitive_var_infos.push(canonical_var_info);
|
||||
self.var_kinds.push(kind);
|
||||
var
|
||||
})
|
||||
} else {
|
||||
self.variables.iter().position(|&v| v == arg).unwrap_or_else(|| {
|
||||
let var = self.variables.len();
|
||||
self.variables.push(arg);
|
||||
self.primitive_var_infos.push(canonical_var_info);
|
||||
self.var_kinds.push(kind);
|
||||
var
|
||||
})
|
||||
};
|
||||
|
|
@ -177,8 +177,8 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
ty::BoundVar::from(idx)
|
||||
}
|
||||
|
||||
fn finalize(self) -> (ty::UniverseIndex, I::CanonicalVars) {
|
||||
let mut var_infos = self.primitive_var_infos;
|
||||
fn finalize(self) -> (ty::UniverseIndex, I::CanonicalVarKinds) {
|
||||
let mut var_kinds = self.var_kinds;
|
||||
// See the rustc-dev-guide section about how we deal with universes
|
||||
// during canonicalization in the new solver.
|
||||
match self.canonicalize_mode {
|
||||
|
|
@ -192,25 +192,25 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
// information for placeholders and inference variables created inside
|
||||
// of the query.
|
||||
CanonicalizeMode::Response { max_input_universe } => {
|
||||
for var in var_infos.iter_mut() {
|
||||
for var in var_kinds.iter_mut() {
|
||||
let uv = var.universe();
|
||||
let new_uv = ty::UniverseIndex::from(
|
||||
uv.index().saturating_sub(max_input_universe.index()),
|
||||
);
|
||||
*var = var.with_updated_universe(new_uv);
|
||||
}
|
||||
let max_universe = var_infos
|
||||
let max_universe = var_kinds
|
||||
.iter()
|
||||
.map(|info| info.universe())
|
||||
.map(|kind| kind.universe())
|
||||
.max()
|
||||
.unwrap_or(ty::UniverseIndex::ROOT);
|
||||
|
||||
let var_infos = self.delegate.cx().mk_canonical_var_infos(&var_infos);
|
||||
return (max_universe, var_infos);
|
||||
let var_kinds = self.delegate.cx().mk_canonical_var_kinds(&var_kinds);
|
||||
return (max_universe, var_kinds);
|
||||
}
|
||||
}
|
||||
|
||||
// Given a `var_infos` with existentials `En` and universals `Un` in
|
||||
// Given a `var_kinds` with existentials `En` and universals `Un` in
|
||||
// universes `n`, this algorithm compresses them in place so that:
|
||||
//
|
||||
// - the new universe indices are as small as possible
|
||||
|
|
@ -219,12 +219,12 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
// 2. put a placeholder in the same universe as an existential which cannot name it
|
||||
//
|
||||
// Let's walk through an example:
|
||||
// - var_infos: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 0, next_orig_uv: 0
|
||||
// - var_infos: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 0, next_orig_uv: 1
|
||||
// - var_infos: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 1, next_orig_uv: 2
|
||||
// - var_infos: [E0, U1, E5, U1, E1, E6, U6], curr_compressed_uv: 1, next_orig_uv: 5
|
||||
// - var_infos: [E0, U1, E2, U1, E1, E6, U6], curr_compressed_uv: 2, next_orig_uv: 6
|
||||
// - var_infos: [E0, U1, E1, U1, E1, E3, U3], curr_compressed_uv: 2, next_orig_uv: -
|
||||
// - var_kinds: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 0, next_orig_uv: 0
|
||||
// - var_kinds: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 0, next_orig_uv: 1
|
||||
// - var_kinds: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 1, next_orig_uv: 2
|
||||
// - var_kinds: [E0, U1, E5, U1, E1, E6, U6], curr_compressed_uv: 1, next_orig_uv: 5
|
||||
// - var_kinds: [E0, U1, E2, U1, E1, E6, U6], curr_compressed_uv: 2, next_orig_uv: 6
|
||||
// - var_kinds: [E0, U1, E1, U1, E1, E3, U3], curr_compressed_uv: 2, next_orig_uv: -
|
||||
//
|
||||
// This algorithm runs in `O(mn)` where `n` is the number of different universes and
|
||||
// `m` the number of variables. This should be fine as both are expected to be small.
|
||||
|
|
@ -232,7 +232,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
let mut existential_in_new_uv = None;
|
||||
let mut next_orig_uv = Some(ty::UniverseIndex::ROOT);
|
||||
while let Some(orig_uv) = next_orig_uv.take() {
|
||||
let mut update_uv = |var: &mut CanonicalVarInfo<I>, orig_uv, is_existential| {
|
||||
let mut update_uv = |var: &mut CanonicalVarKind<I>, orig_uv, is_existential| {
|
||||
let uv = var.universe();
|
||||
match uv.cmp(&orig_uv) {
|
||||
Ordering::Less => (), // Already updated
|
||||
|
|
@ -284,7 +284,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
// Whenever we compress the universe of a placeholder, no existential with
|
||||
// an already compressed universe can name that placeholder.
|
||||
for is_existential in [false, true] {
|
||||
for var in var_infos.iter_mut() {
|
||||
for var in var_kinds.iter_mut() {
|
||||
// We simply put all regions from the input into the highest
|
||||
// compressed universe, so we only deal with them at the end.
|
||||
if !var.is_region() {
|
||||
|
|
@ -298,7 +298,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
|
||||
// We put all regions into a separate universe.
|
||||
let mut first_region = true;
|
||||
for var in var_infos.iter_mut() {
|
||||
for var in var_kinds.iter_mut() {
|
||||
if var.is_region() {
|
||||
if first_region {
|
||||
first_region = false;
|
||||
|
|
@ -309,8 +309,8 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
}
|
||||
}
|
||||
|
||||
let var_infos = self.delegate.cx().mk_canonical_var_infos(&var_infos);
|
||||
(curr_compressed_uv, var_infos)
|
||||
let var_kinds = self.delegate.cx().mk_canonical_var_kinds(&var_kinds);
|
||||
(curr_compressed_uv, var_kinds)
|
||||
}
|
||||
|
||||
fn cached_fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||
|
|
@ -391,7 +391,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
|||
}
|
||||
};
|
||||
|
||||
let var = self.get_or_insert_bound_var(t, CanonicalVarInfo { kind });
|
||||
let var = self.get_or_insert_bound_var(t, kind);
|
||||
|
||||
Ty::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
}
|
||||
|
|
@ -475,7 +475,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
|
|||
}
|
||||
};
|
||||
|
||||
let var = self.get_or_insert_bound_var(r, CanonicalVarInfo { kind });
|
||||
let var = self.get_or_insert_bound_var(r, kind);
|
||||
|
||||
Region::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
}
|
||||
|
|
@ -525,7 +525,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
|
|||
| ty::ConstKind::Expr(_) => return c.super_fold_with(self),
|
||||
};
|
||||
|
||||
let var = self.get_or_insert_bound_var(c, CanonicalVarInfo { kind });
|
||||
let var = self.get_or_insert_bound_var(c, kind);
|
||||
|
||||
Const::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
|
|||
|
||||
fn instantiate_canonical_var_with_infer(
|
||||
&self,
|
||||
cv_info: ty::CanonicalVarInfo<Self::Interner>,
|
||||
kind: ty::CanonicalVarKind<Self::Interner>,
|
||||
span: <Self::Interner as Interner>::Span,
|
||||
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
|
||||
) -> <Self::Interner as Interner>::GenericArg;
|
||||
|
|
|
|||
|
|
@ -360,15 +360,15 @@ where
|
|||
}
|
||||
|
||||
let var_values = delegate.cx().mk_args_from_iter(
|
||||
response.variables.iter().enumerate().map(|(index, info)| {
|
||||
if info.universe() != ty::UniverseIndex::ROOT {
|
||||
response.variables.iter().enumerate().map(|(index, var_kind)| {
|
||||
if var_kind.universe() != ty::UniverseIndex::ROOT {
|
||||
// A variable from inside a binder of the query. While ideally these shouldn't
|
||||
// exist at all (see the FIXME at the start of this method), we have to deal with
|
||||
// them for now.
|
||||
delegate.instantiate_canonical_var_with_infer(info, span, |idx| {
|
||||
delegate.instantiate_canonical_var_with_infer(var_kind, span, |idx| {
|
||||
prev_universe + idx.index()
|
||||
})
|
||||
} else if info.is_existential() {
|
||||
} else if var_kind.is_existential() {
|
||||
// As an optimization we sometimes avoid creating a new inference variable here.
|
||||
//
|
||||
// All new inference variables we create start out in the current universe of the caller.
|
||||
|
|
@ -379,12 +379,13 @@ where
|
|||
if let Some(v) = opt_values[ty::BoundVar::from_usize(index)] {
|
||||
v
|
||||
} else {
|
||||
delegate.instantiate_canonical_var_with_infer(info, span, |_| prev_universe)
|
||||
delegate
|
||||
.instantiate_canonical_var_with_infer(var_kind, span, |_| prev_universe)
|
||||
}
|
||||
} else {
|
||||
// For placeholders which were already part of the input, we simply map this
|
||||
// universal bound variable back the placeholder of the input.
|
||||
original_values[info.expect_placeholder_index()]
|
||||
original_values[var_kind.expect_placeholder_index()]
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ where
|
|||
|
||||
/// The variable info for the `var_values`, only used to make an ambiguous response
|
||||
/// with no constraints.
|
||||
variables: I::CanonicalVars,
|
||||
variables: I::CanonicalVarKinds,
|
||||
|
||||
/// What kind of goal we're currently computing, see the enum definition
|
||||
/// for more info.
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ where
|
|||
fn response_no_constraints_raw<I: Interner>(
|
||||
cx: I,
|
||||
max_universe: ty::UniverseIndex,
|
||||
variables: I::CanonicalVars,
|
||||
variables: I::CanonicalVarKinds,
|
||||
certainty: Certainty,
|
||||
) -> CanonicalResponse<I> {
|
||||
ty::Canonical {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use rustc_hir::LangItem;
|
|||
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
|
||||
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
|
||||
use rustc_infer::infer::canonical::{
|
||||
Canonical, CanonicalExt as _, CanonicalQueryInput, CanonicalVarInfo, CanonicalVarValues,
|
||||
Canonical, CanonicalExt as _, CanonicalQueryInput, CanonicalVarKind, CanonicalVarValues,
|
||||
};
|
||||
use rustc_infer::infer::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TyCtxtInferExt};
|
||||
use rustc_infer::traits::solve::Goal;
|
||||
|
|
@ -190,11 +190,11 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||
|
||||
fn instantiate_canonical_var_with_infer(
|
||||
&self,
|
||||
cv_info: CanonicalVarInfo<'tcx>,
|
||||
kind: CanonicalVarKind<'tcx>,
|
||||
span: Span,
|
||||
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
self.0.instantiate_canonical_var(span, cv_info, universe_map)
|
||||
self.0.instantiate_canonical_var(span, kind, universe_map)
|
||||
}
|
||||
|
||||
fn add_item_bounds_for_hidden_type(
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ pub struct CanonicalQueryInput<I: Interner, V> {
|
|||
pub struct Canonical<I: Interner, V> {
|
||||
pub value: V,
|
||||
pub max_universe: UniverseIndex,
|
||||
pub variables: I::CanonicalVars,
|
||||
pub variables: I::CanonicalVarKinds,
|
||||
}
|
||||
|
||||
impl<I: Interner, V> Canonical<I, V> {
|
||||
|
|
@ -89,63 +89,6 @@ impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
|
|||
/// a copy of the canonical value in some other inference context,
|
||||
/// with fresh inference variables replacing the canonical values.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
pub struct CanonicalVarInfo<I: Interner> {
|
||||
pub kind: CanonicalVarKind<I>,
|
||||
}
|
||||
|
||||
impl<I: Interner> CanonicalVarInfo<I> {
|
||||
pub fn universe(self) -> UniverseIndex {
|
||||
self.kind.universe()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarInfo<I> {
|
||||
CanonicalVarInfo { kind: self.kind.with_updated_universe(ui) }
|
||||
}
|
||||
|
||||
pub fn is_existential(&self) -> bool {
|
||||
match self.kind {
|
||||
CanonicalVarKind::Ty(_) => true,
|
||||
CanonicalVarKind::PlaceholderTy(_) => false,
|
||||
CanonicalVarKind::Region(_) => true,
|
||||
CanonicalVarKind::PlaceholderRegion(..) => false,
|
||||
CanonicalVarKind::Const(_) => true,
|
||||
CanonicalVarKind::PlaceholderConst(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_region(&self) -> bool {
|
||||
match self.kind {
|
||||
CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true,
|
||||
CanonicalVarKind::Ty(_)
|
||||
| CanonicalVarKind::PlaceholderTy(_)
|
||||
| CanonicalVarKind::Const(_)
|
||||
| CanonicalVarKind::PlaceholderConst(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_placeholder_index(self) -> usize {
|
||||
match self.kind {
|
||||
CanonicalVarKind::Ty(_) | CanonicalVarKind::Region(_) | CanonicalVarKind::Const(_) => {
|
||||
panic!("expected placeholder: {self:?}")
|
||||
}
|
||||
|
||||
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(),
|
||||
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(),
|
||||
CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.var().as_usize(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes the "kind" of the canonical variable. This is a "kind"
|
||||
/// in the type-theory sense of the term -- i.e., a "meta" type system
|
||||
/// that analyzes type-like values.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
|
||||
|
|
@ -214,6 +157,39 @@ impl<I: Interner> CanonicalVarKind<I> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_existential(self) -> bool {
|
||||
match self {
|
||||
CanonicalVarKind::Ty(_) => true,
|
||||
CanonicalVarKind::PlaceholderTy(_) => false,
|
||||
CanonicalVarKind::Region(_) => true,
|
||||
CanonicalVarKind::PlaceholderRegion(..) => false,
|
||||
CanonicalVarKind::Const(_) => true,
|
||||
CanonicalVarKind::PlaceholderConst(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_region(self) -> bool {
|
||||
match self {
|
||||
CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true,
|
||||
CanonicalVarKind::Ty(_)
|
||||
| CanonicalVarKind::PlaceholderTy(_)
|
||||
| CanonicalVarKind::Const(_)
|
||||
| CanonicalVarKind::PlaceholderConst(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_placeholder_index(self) -> usize {
|
||||
match self {
|
||||
CanonicalVarKind::Ty(_) | CanonicalVarKind::Region(_) | CanonicalVarKind::Const(_) => {
|
||||
panic!("expected placeholder: {self:?}")
|
||||
}
|
||||
|
||||
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(),
|
||||
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(),
|
||||
CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.var().as_usize(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Rust actually has more than one category of type variables;
|
||||
|
|
@ -306,11 +282,11 @@ impl<I: Interner> CanonicalVarValues<I> {
|
|||
|
||||
// Given a list of canonical variables, construct a set of values which are
|
||||
// the identity response.
|
||||
pub fn make_identity(cx: I, infos: I::CanonicalVars) -> CanonicalVarValues<I> {
|
||||
pub fn make_identity(cx: I, infos: I::CanonicalVarKinds) -> CanonicalVarValues<I> {
|
||||
CanonicalVarValues {
|
||||
var_values: cx.mk_args_from_iter(infos.iter().enumerate().map(
|
||||
|(i, info)| -> I::GenericArg {
|
||||
match info.kind {
|
||||
|(i, kind)| -> I::GenericArg {
|
||||
match kind {
|
||||
CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => {
|
||||
Ty::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i))
|
||||
.into()
|
||||
|
|
|
|||
|
|
@ -64,13 +64,16 @@ pub trait Interner:
|
|||
+ TypeVisitable<Self>
|
||||
+ SliceLike<Item = Self::LocalDefId>;
|
||||
|
||||
type CanonicalVars: Copy
|
||||
type CanonicalVarKinds: Copy
|
||||
+ Debug
|
||||
+ Hash
|
||||
+ Eq
|
||||
+ SliceLike<Item = ty::CanonicalVarInfo<Self>>
|
||||
+ SliceLike<Item = ty::CanonicalVarKind<Self>>
|
||||
+ Default;
|
||||
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
|
||||
fn mk_canonical_var_kinds(
|
||||
self,
|
||||
kinds: &[ty::CanonicalVarKind<Self>],
|
||||
) -> Self::CanonicalVarKinds;
|
||||
|
||||
type ExternalConstraints: Copy
|
||||
+ Debug
|
||||
|
|
|
|||
|
|
@ -120,20 +120,22 @@
|
|||
//!
|
||||
//! Rust guarantees to optimize the following types `T` such that
|
||||
//! [`Option<T>`] has the same size, alignment, and [function call ABI] as `T`. In some
|
||||
//! of these cases, Rust further guarantees that
|
||||
//! `transmute::<_, Option<T>>([0u8; size_of::<T>()])` is sound and
|
||||
//! produces `Option::<T>::None`. These cases are identified by the
|
||||
//! second column:
|
||||
//! of these cases, Rust further guarantees the following:
|
||||
//! - `transmute::<_, Option<T>>([0u8; size_of::<T>()])` is sound and produces
|
||||
//! `Option::<T>::None`
|
||||
//! - `transmute::<_, [u8; size_of::<T>()]>(Option::<T>::None)` is sound and produces
|
||||
//! `[0u8; size_of::<T>()]`
|
||||
//! These cases are identified by the second column:
|
||||
//!
|
||||
//! | `T` | `transmute::<_, Option<T>>([0u8; size_of::<T>()])` sound? |
|
||||
//! |---------------------------------------------------------------------|----------------------------------------------------------------------|
|
||||
//! | [`Box<U>`] (specifically, only `Box<U, Global>`) | when `U: Sized` |
|
||||
//! | `&U` | when `U: Sized` |
|
||||
//! | `&mut U` | when `U: Sized` |
|
||||
//! | `fn`, `extern "C" fn`[^extern_fn] | always |
|
||||
//! | [`num::NonZero*`] | always |
|
||||
//! | [`ptr::NonNull<U>`] | when `U: Sized` |
|
||||
//! | `#[repr(transparent)]` struct around one of the types in this list. | when it holds for the inner type |
|
||||
//! | `T` | Transmuting between `[0u8; size_of::<T>()]` and `Option::<T>::None` sound? |
|
||||
//! |---------------------------------------------------------------------|----------------------------------------------------------------------------|
|
||||
//! | [`Box<U>`] (specifically, only `Box<U, Global>`) | when `U: Sized` |
|
||||
//! | `&U` | when `U: Sized` |
|
||||
//! | `&mut U` | when `U: Sized` |
|
||||
//! | `fn`, `extern "C" fn`[^extern_fn] | always |
|
||||
//! | [`num::NonZero*`] | always |
|
||||
//! | [`ptr::NonNull<U>`] | when `U: Sized` |
|
||||
//! | `#[repr(transparent)]` struct around one of the types in this list. | when it holds for the inner type |
|
||||
//!
|
||||
//! [^extern_fn]: this remains true for any argument/return types and any other ABI: `extern "abi" fn` (_e.g._, `extern "system" fn`)
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -4,11 +4,14 @@ use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
|||
use crate::sys::unsupported;
|
||||
use crate::time::Duration;
|
||||
|
||||
pub struct TcpStream(!);
|
||||
mod tcp;
|
||||
pub(crate) mod tcp4;
|
||||
|
||||
pub struct TcpStream(#[expect(dead_code)] tcp::Tcp);
|
||||
|
||||
impl TcpStream {
|
||||
pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
|
||||
unsupported()
|
||||
pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
|
||||
tcp::Tcp::connect(addr?).map(Self)
|
||||
}
|
||||
|
||||
pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
|
||||
|
|
@ -16,105 +19,105 @@ impl TcpStream {
|
|||
}
|
||||
|
||||
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.0
|
||||
false
|
||||
}
|
||||
|
||||
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.0
|
||||
false
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<TcpStream> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn linger(&self) -> io::Result<Option<Duration>> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn nodelay(&self) -> io::Result<bool> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
|
||||
self.0
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for TcpStream {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
21
library/std/src/sys/net/connection/uefi/tcp.rs
Normal file
21
library/std/src/sys/net/connection/uefi/tcp.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
use super::tcp4;
|
||||
use crate::io;
|
||||
use crate::net::SocketAddr;
|
||||
|
||||
pub(crate) enum Tcp {
|
||||
V4(#[expect(dead_code)] tcp4::Tcp4),
|
||||
}
|
||||
|
||||
impl Tcp {
|
||||
pub(crate) fn connect(addr: &SocketAddr) -> io::Result<Self> {
|
||||
match addr {
|
||||
SocketAddr::V4(x) => {
|
||||
let temp = tcp4::Tcp4::new()?;
|
||||
temp.configure(true, Some(x), None)?;
|
||||
temp.connect()?;
|
||||
Ok(Tcp::V4(temp))
|
||||
}
|
||||
SocketAddr::V6(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
118
library/std/src/sys/net/connection/uefi/tcp4.rs
Normal file
118
library/std/src/sys/net/connection/uefi/tcp4.rs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
use r_efi::efi::{self, Status};
|
||||
use r_efi::protocols::tcp4;
|
||||
|
||||
use crate::io;
|
||||
use crate::net::SocketAddrV4;
|
||||
use crate::ptr::NonNull;
|
||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
||||
use crate::sys::pal::helpers;
|
||||
|
||||
const TYPE_OF_SERVICE: u8 = 8;
|
||||
const TIME_TO_LIVE: u8 = 255;
|
||||
|
||||
pub(crate) struct Tcp4 {
|
||||
protocol: NonNull<tcp4::Protocol>,
|
||||
flag: AtomicBool,
|
||||
#[expect(dead_code)]
|
||||
service_binding: helpers::ServiceProtocol,
|
||||
}
|
||||
|
||||
const DEFAULT_ADDR: efi::Ipv4Address = efi::Ipv4Address { addr: [0u8; 4] };
|
||||
|
||||
impl Tcp4 {
|
||||
pub(crate) fn new() -> io::Result<Self> {
|
||||
let service_binding = helpers::ServiceProtocol::open(tcp4::SERVICE_BINDING_PROTOCOL_GUID)?;
|
||||
let protocol = helpers::open_protocol(service_binding.child_handle(), tcp4::PROTOCOL_GUID)?;
|
||||
|
||||
Ok(Self { service_binding, protocol, flag: AtomicBool::new(false) })
|
||||
}
|
||||
|
||||
pub(crate) fn configure(
|
||||
&self,
|
||||
active: bool,
|
||||
remote_address: Option<&SocketAddrV4>,
|
||||
station_address: Option<&SocketAddrV4>,
|
||||
) -> io::Result<()> {
|
||||
let protocol = self.protocol.as_ptr();
|
||||
|
||||
let (remote_address, remote_port) = if let Some(x) = remote_address {
|
||||
(helpers::ipv4_to_r_efi(*x.ip()), x.port())
|
||||
} else {
|
||||
(DEFAULT_ADDR, 0)
|
||||
};
|
||||
|
||||
// FIXME: Remove when passive connections with proper subnet handling are added
|
||||
assert!(station_address.is_none());
|
||||
let use_default_address = efi::Boolean::TRUE;
|
||||
let (station_address, station_port) = (DEFAULT_ADDR, 0);
|
||||
let subnet_mask = helpers::ipv4_to_r_efi(crate::net::Ipv4Addr::new(0, 0, 0, 0));
|
||||
|
||||
let mut config_data = tcp4::ConfigData {
|
||||
type_of_service: TYPE_OF_SERVICE,
|
||||
time_to_live: TIME_TO_LIVE,
|
||||
access_point: tcp4::AccessPoint {
|
||||
use_default_address,
|
||||
remote_address,
|
||||
remote_port,
|
||||
active_flag: active.into(),
|
||||
station_address,
|
||||
station_port,
|
||||
subnet_mask,
|
||||
},
|
||||
control_option: crate::ptr::null_mut(),
|
||||
};
|
||||
|
||||
let r = unsafe { ((*protocol).configure)(protocol, &mut config_data) };
|
||||
if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
|
||||
}
|
||||
|
||||
pub(crate) fn connect(&self) -> io::Result<()> {
|
||||
let evt = unsafe { self.create_evt() }?;
|
||||
let completion_token =
|
||||
tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS };
|
||||
|
||||
let protocol = self.protocol.as_ptr();
|
||||
let mut conn_token = tcp4::ConnectionToken { completion_token };
|
||||
|
||||
let r = unsafe { ((*protocol).connect)(protocol, &mut conn_token) };
|
||||
if r.is_error() {
|
||||
return Err(io::Error::from_raw_os_error(r.as_usize()));
|
||||
}
|
||||
|
||||
self.wait_for_flag();
|
||||
|
||||
if completion_token.status.is_error() {
|
||||
Err(io::Error::from_raw_os_error(completion_token.status.as_usize()))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn create_evt(&self) -> io::Result<helpers::OwnedEvent> {
|
||||
self.flag.store(false, Ordering::Relaxed);
|
||||
helpers::OwnedEvent::new(
|
||||
efi::EVT_NOTIFY_SIGNAL,
|
||||
efi::TPL_CALLBACK,
|
||||
Some(toggle_atomic_flag),
|
||||
Some(unsafe { NonNull::new_unchecked(self.flag.as_ptr().cast()) }),
|
||||
)
|
||||
}
|
||||
|
||||
fn wait_for_flag(&self) {
|
||||
while !self.flag.load(Ordering::Relaxed) {
|
||||
let _ = self.poll();
|
||||
}
|
||||
}
|
||||
|
||||
fn poll(&self) -> io::Result<()> {
|
||||
let protocol = self.protocol.as_ptr();
|
||||
let r = unsafe { ((*protocol).poll)(protocol) };
|
||||
|
||||
if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
|
||||
}
|
||||
}
|
||||
|
||||
extern "efiapi" fn toggle_atomic_flag(_: r_efi::efi::Event, ctx: *mut crate::ffi::c_void) {
|
||||
let flag = unsafe { AtomicBool::from_ptr(ctx.cast()) };
|
||||
flag.store(true, Ordering::Relaxed);
|
||||
}
|
||||
|
|
@ -653,7 +653,6 @@ pub(crate) struct ServiceProtocol {
|
|||
}
|
||||
|
||||
impl ServiceProtocol {
|
||||
#[expect(dead_code)]
|
||||
pub(crate) fn open(service_guid: r_efi::efi::Guid) -> io::Result<Self> {
|
||||
let handles = locate_handles(service_guid)?;
|
||||
|
||||
|
|
@ -670,7 +669,6 @@ impl ServiceProtocol {
|
|||
Err(io::const_error!(io::ErrorKind::NotFound, "no service binding protocol found"))
|
||||
}
|
||||
|
||||
#[expect(dead_code)]
|
||||
pub(crate) fn child_handle(&self) -> NonNull<crate::ffi::c_void> {
|
||||
self.child_handle
|
||||
}
|
||||
|
|
@ -732,6 +730,10 @@ impl OwnedEvent {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn as_ptr(&self) -> efi::Event {
|
||||
self.0.as_ptr()
|
||||
}
|
||||
|
||||
pub(crate) fn into_raw(self) -> *mut crate::ffi::c_void {
|
||||
let r = self.0.as_ptr();
|
||||
crate::mem::forget(self);
|
||||
|
|
@ -755,3 +757,7 @@ impl Drop for OwnedEvent {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn ipv4_to_r_efi(addr: crate::net::Ipv4Addr) -> efi::Ipv4Address {
|
||||
efi::Ipv4Address { addr: addr.octets() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,8 +88,10 @@ on your documentation examples make requests to.
|
|||
```
|
||||
|
||||
Now, when you press "run", the button will make a request to this domain. The request
|
||||
URL will contain 2 query parameters: `code` and `edition` for the code in the documentation
|
||||
and the Rust edition respectively.
|
||||
URL will contain 3 query parameters:
|
||||
1. `code` for the code in the documentation
|
||||
2. `version` for the Rust channel, e.g. nightly, which is decided by whether `code` contain unstable features
|
||||
3. `edition` for the Rust edition, e.g. 2024
|
||||
|
||||
If you don't use this attribute, there will be no run buttons.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
# `eagerly-emit-delayed-bugs`
|
||||
|
||||
This feature is perma-unstable and has no tracking issue.
|
||||
|
||||
------------------------
|
||||
|
||||
This flag converts all [`span_delayed_bug()`] calls to [`bug!`] calls, exiting the compiler immediately and allowing you to generate a backtrace of where the delayed bug occurred.
|
||||
For full documentation, see [the rustc-dev-guide][dev-guide-delayed].
|
||||
|
||||
[`bug!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/macro.bug.html
|
||||
[`span_delayed_bug()`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagCtxtHandle.html#method.span_delayed_bug
|
||||
[dev-guide-delayed]: https://rustc-dev-guide.rust-lang.org/compiler-debugging.html#debugging-delayed-bugs
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# `track-diagnostics`
|
||||
|
||||
This feature is perma-unstable and has no tracking issue.
|
||||
|
||||
------------------------
|
||||
|
||||
This flag prints the source code span in the compiler where a diagnostic was generated, respecting [`#[track_caller]`][track_caller]. Note that this may be different from the place it was emitted.
|
||||
For full documentation, see [the rustc-dev-guide][dev-guide-track-diagnostics].
|
||||
|
||||
[track_caller]: https://doc.rust-lang.org/reference/attributes/codegen.html#the-track_caller-attribute
|
||||
[dev-guide-track-diagnostics]: https://rustc-dev-guide.rust-lang.org/compiler-debugging.html#getting-the-error-creation-location
|
||||
13
src/doc/unstable-book/src/compiler-flags/treat-err-as-bug.md
Normal file
13
src/doc/unstable-book/src/compiler-flags/treat-err-as-bug.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# `treat-err-as-bug`
|
||||
|
||||
This feature is perma-unstable and has no tracking issue.
|
||||
|
||||
------------------------
|
||||
|
||||
This flag converts the selected error to a [`bug!`] call, exiting the compiler immediately and allowing you to generate a backtrace of where the error occurred.
|
||||
For full documentation, see [the rustc-dev-guide][dev-guide-backtrace].
|
||||
|
||||
Note that the compiler automatically sets `RUST_BACKTRACE=1` for itself, and so you do not need to set it yourself when using this flag.
|
||||
|
||||
[`bug!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/macro.bug.html
|
||||
[dev-guide-backtrace]: https://rustc-dev-guide.rust-lang.org/compiler-debugging.html#getting-a-backtrace-for-errors
|
||||
|
|
@ -1,34 +1,34 @@
|
|||
// MIR for `address_of_reborrow` after SimplifyCfg-initial
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10]
|
||||
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10]
|
||||
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
|
||||
| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
|
||||
| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
|
||||
| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
|
||||
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10]
|
||||
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10]
|
||||
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
|
||||
| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
|
||||
| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
|
||||
| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
|
||||
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10]
|
||||
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send
|
||||
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10]
|
||||
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send
|
||||
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
|
||||
| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
|
||||
| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
|
||||
| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
|
||||
| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
|
||||
| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
|
||||
| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32]
|
||||
| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32]
|
||||
|
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test
|
||||
| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test
|
||||
| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
|
||||
| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
|
||||
| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [Region(U0), Region(U0), Region(U0), Region(U0)] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
|
||||
| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [Region(U0), Region(U0), Region(U0), Region(U0)] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
|
||||
|
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ pub trait Interner: Sized {
|
|||
type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>;
|
||||
type BoundVars: IntoIterator<Item = Self::BoundVar>;
|
||||
type BoundVar;
|
||||
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
|
||||
type CanonicalVarKinds: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarKind<Self>>;
|
||||
type Ty: Copy
|
||||
+ DebugWithInfcx<Self>
|
||||
+ Hash
|
||||
|
|
@ -77,7 +77,7 @@ pub trait Interner: Sized {
|
|||
type ClosureKind: Copy + Debug + Hash + Eq;
|
||||
|
||||
// Required method
|
||||
fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
|
||||
fn mk_canonical_var_kinds(self, kinds: &[CanonicalVarKind<Self>]) -> Self::CanonicalVarKinds;
|
||||
}
|
||||
|
||||
pub trait DebugWithInfcx<I: Interner>: Debug {
|
||||
|
|
@ -104,10 +104,6 @@ pub trait TypeSuperVisitable<I: Interner>: TypeVisitable<I> {
|
|||
fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result;
|
||||
}
|
||||
|
||||
pub struct CanonicalVarInfo<I: Interner> {
|
||||
pub kind: CanonicalVarKind<I>,
|
||||
}
|
||||
|
||||
pub struct CanonicalVarKind<I>(std::marker::PhantomData<I>);
|
||||
|
||||
pub struct TyKind<I>(std::marker::PhantomData<I>);
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
|
||||
const EXPECTED = [
|
||||
{
|
||||
'query': 'canonicalvarinfo, intoiterator -> intoiterator',
|
||||
'query': 'CanonicalVarKind, intoiterator -> intoiterator',
|
||||
'others': [],
|
||||
},
|
||||
{
|
||||
'query': '[canonicalvarinfo], interner<tys=intoiterator> -> intoiterator',
|
||||
'query': '[CanonicalVarKind], interner<tys=intoiterator> -> intoiterator',
|
||||
'others': [
|
||||
{ 'path': 'looks_like_rustc_interner::Interner', 'name': 'mk_canonical_var_infos' },
|
||||
{ 'path': 'looks_like_rustc_interner::Interner', 'name': 'mk_canonical_var_kinds' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1423,3 +1423,12 @@ compiletest = [
|
|||
|
||||
[behind-upstream]
|
||||
days-threshold = 14
|
||||
|
||||
# Canonicalize issue numbers to avoid closing the wrong issue
|
||||
# when commits are included in subtrees, as well as warning links in commits.
|
||||
# Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html
|
||||
[issue-links]
|
||||
|
||||
# Prevents mentions in commits to avoid users being spammed
|
||||
# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html
|
||||
[no-mentions]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue