Auto merge of #139536 - matthiaskrgr:rollup-j6goald, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #139476 (rm `RegionInferenceContext::var_infos`) - #139485 (compiletest: Stricter parsing for diagnostic kinds) - #139491 (Update books) - #139500 (document panic behavior of Vec::resize and Vec::resize_with) - #139501 (Fix stack overflow in exhaustiveness due to recursive HIR opaque hidden types) - #139504 (add missing word in doc comment) - #139509 (clean: remove Deref<Target=RegionKind> impl for Region and use `.kind()`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
de5b8a4c77
89 changed files with 531 additions and 305 deletions
|
@ -406,8 +406,8 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
|
||||||
// started MIR borrowchecking with, so the region
|
// started MIR borrowchecking with, so the region
|
||||||
// constraints have already been taken. Use the data from
|
// constraints have already been taken. Use the data from
|
||||||
// our `mbcx` instead.
|
// our `mbcx` instead.
|
||||||
|vid| mbcx.regioncx.var_infos[vid].origin,
|
|vid| RegionVariableOrigin::Nll(mbcx.regioncx.definitions[vid].origin),
|
||||||
|vid| mbcx.regioncx.var_infos[vid].universe,
|
|vid| mbcx.regioncx.definitions[vid].universe,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -487,7 +487,7 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
|
||||||
let (sub_region, cause) = info?;
|
let (sub_region, cause) = info?;
|
||||||
|
|
||||||
debug!(?sub_region, "cause = {:#?}", cause);
|
debug!(?sub_region, "cause = {:#?}", cause);
|
||||||
let error = match (error_region, *sub_region) {
|
let error = match (error_region, sub_region.kind()) {
|
||||||
(Some(error_region), ty::ReVar(vid)) => RegionResolutionError::SubSupConflict(
|
(Some(error_region), ty::ReVar(vid)) => RegionResolutionError::SubSupConflict(
|
||||||
vid,
|
vid,
|
||||||
region_var_origin(vid),
|
region_var_origin(vid),
|
||||||
|
|
|
@ -8,9 +8,7 @@ use rustc_errors::{Applicability, Diag, EmissionGuarantee, MultiSpan, listify};
|
||||||
use rustc_hir::def::{CtorKind, Namespace};
|
use rustc_hir::def::{CtorKind, Namespace};
|
||||||
use rustc_hir::{self as hir, CoroutineKind, LangItem};
|
use rustc_hir::{self as hir, CoroutineKind, LangItem};
|
||||||
use rustc_index::IndexSlice;
|
use rustc_index::IndexSlice;
|
||||||
use rustc_infer::infer::{
|
use rustc_infer::infer::{BoundRegionConversionTime, NllRegionVariableOrigin};
|
||||||
BoundRegionConversionTime, NllRegionVariableOrigin, RegionVariableOrigin,
|
|
||||||
};
|
|
||||||
use rustc_infer::traits::SelectionError;
|
use rustc_infer::traits::SelectionError;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
|
@ -587,7 +585,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
// this by hooking into the pretty printer and telling it to label the
|
// this by hooking into the pretty printer and telling it to label the
|
||||||
// lifetimes without names with the value `'0`.
|
// lifetimes without names with the value `'0`.
|
||||||
if let ty::Ref(region, ..) = ty.kind() {
|
if let ty::Ref(region, ..) = ty.kind() {
|
||||||
match **region {
|
match region.kind() {
|
||||||
ty::ReBound(_, ty::BoundRegion { kind: br, .. })
|
ty::ReBound(_, ty::BoundRegion { kind: br, .. })
|
||||||
| ty::RePlaceholder(ty::PlaceholderRegion {
|
| ty::RePlaceholder(ty::PlaceholderRegion {
|
||||||
bound: ty::BoundRegion { kind: br, .. },
|
bound: ty::BoundRegion { kind: br, .. },
|
||||||
|
@ -607,7 +605,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, Namespace::TypeNS);
|
let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, Namespace::TypeNS);
|
||||||
|
|
||||||
let region = if let ty::Ref(region, ..) = ty.kind() {
|
let region = if let ty::Ref(region, ..) = ty.kind() {
|
||||||
match **region {
|
match region.kind() {
|
||||||
ty::ReBound(_, ty::BoundRegion { kind: br, .. })
|
ty::ReBound(_, ty::BoundRegion { kind: br, .. })
|
||||||
| ty::RePlaceholder(ty::PlaceholderRegion {
|
| ty::RePlaceholder(ty::PlaceholderRegion {
|
||||||
bound: ty::BoundRegion { kind: br, .. },
|
bound: ty::BoundRegion { kind: br, .. },
|
||||||
|
@ -633,9 +631,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
) {
|
) {
|
||||||
let predicate_span = path.iter().find_map(|constraint| {
|
let predicate_span = path.iter().find_map(|constraint| {
|
||||||
let outlived = constraint.sub;
|
let outlived = constraint.sub;
|
||||||
if let Some(origin) = self.regioncx.var_infos.get(outlived)
|
if let Some(origin) = self.regioncx.definitions.get(outlived)
|
||||||
&& let RegionVariableOrigin::Nll(NllRegionVariableOrigin::Placeholder(_)) =
|
&& let NllRegionVariableOrigin::Placeholder(_) = origin.origin
|
||||||
origin.origin
|
|
||||||
&& let ConstraintCategory::Predicate(span) = constraint.category
|
&& let ConstraintCategory::Predicate(span) = constraint.category
|
||||||
{
|
{
|
||||||
Some(span)
|
Some(span)
|
||||||
|
|
|
@ -190,7 +190,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
fold_regions(tcx, ty, |region, _| match *region {
|
fold_regions(tcx, ty, |region, _| match region.kind() {
|
||||||
ty::ReVar(vid) => self.to_error_region(vid).unwrap_or(region),
|
ty::ReVar(vid) => self.to_error_region(vid).unwrap_or(region),
|
||||||
_ => region,
|
_ => region,
|
||||||
})
|
})
|
||||||
|
@ -198,7 +198,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
|
|
||||||
/// Returns `true` if a closure is inferred to be an `FnMut` closure.
|
/// Returns `true` if a closure is inferred to be an `FnMut` closure.
|
||||||
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
|
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
|
||||||
if let Some(ty::ReLateParam(late_param)) = self.to_error_region(fr).as_deref()
|
if let Some(r) = self.to_error_region(fr)
|
||||||
|
&& let ty::ReLateParam(late_param) = r.kind()
|
||||||
&& let ty::LateParamRegionKind::ClosureEnv = late_param.kind
|
&& let ty::LateParamRegionKind::ClosureEnv = late_param.kind
|
||||||
&& let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty
|
&& let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty
|
||||||
{
|
{
|
||||||
|
@ -832,7 +833,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
if let (Some(f), Some(outlived_f)) =
|
if let (Some(f), Some(outlived_f)) =
|
||||||
(self.to_error_region(fr), self.to_error_region(outlived_fr))
|
(self.to_error_region(fr), self.to_error_region(outlived_fr))
|
||||||
{
|
{
|
||||||
if *outlived_f != ty::ReStatic {
|
if outlived_f.kind() != ty::ReStatic {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let suitable_region = self.infcx.tcx.is_suitable_region(self.mir_def_id(), f);
|
let suitable_region = self.infcx.tcx.is_suitable_region(self.mir_def_id(), f);
|
||||||
|
|
|
@ -288,7 +288,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
|
|
||||||
debug!("give_region_a_name: error_region = {:?}", error_region);
|
debug!("give_region_a_name: error_region = {:?}", error_region);
|
||||||
match *error_region {
|
match error_region.kind() {
|
||||||
ty::ReEarlyParam(ebr) => ebr.has_name().then(|| {
|
ty::ReEarlyParam(ebr) => ebr.has_name().then(|| {
|
||||||
let def_id = tcx.generics_of(self.mir_def_id()).region_param(ebr, tcx).def_id;
|
let def_id = tcx.generics_of(self.mir_def_id()).region_param(ebr, tcx).def_id;
|
||||||
let span = tcx.hir_span_if_local(def_id).unwrap_or(DUMMY_SP);
|
let span = tcx.hir_span_if_local(def_id).unwrap_or(DUMMY_SP);
|
||||||
|
@ -896,7 +896,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
fr: RegionVid,
|
fr: RegionVid,
|
||||||
) -> Option<RegionName> {
|
) -> Option<RegionName> {
|
||||||
let ty::ReEarlyParam(region) = *self.to_error_region(fr)? else {
|
let ty::ReEarlyParam(region) = self.to_error_region(fr)?.kind() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
if region.has_name() {
|
if region.has_name() {
|
||||||
|
@ -912,7 +912,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
|
|
||||||
let found = tcx
|
let found = tcx
|
||||||
.any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| {
|
.any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| {
|
||||||
*r == ty::ReEarlyParam(region)
|
r.kind() == ty::ReEarlyParam(region)
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(RegionName {
|
Some(RegionName {
|
||||||
|
@ -931,7 +931,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
fr: RegionVid,
|
fr: RegionVid,
|
||||||
) -> Option<RegionName> {
|
) -> Option<RegionName> {
|
||||||
let ty::ReEarlyParam(region) = *self.to_error_region(fr)? else {
|
let ty::ReEarlyParam(region) = self.to_error_region(fr)?.kind() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
if region.has_name() {
|
if region.has_name() {
|
||||||
|
@ -1007,7 +1007,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
if data.projection_term.self_ty() == ty => {}
|
if data.projection_term.self_ty() == ty => {}
|
||||||
_ => return false,
|
_ => return false,
|
||||||
}
|
}
|
||||||
tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyParam(region))
|
tcx.any_free_region_meets(pred, |r| r.kind() == ty::ReEarlyParam(region))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
|
@ -334,7 +334,7 @@ fn emit_mermaid_nll_regions<'tcx>(
|
||||||
writeln!(out, "flowchart TD")?;
|
writeln!(out, "flowchart TD")?;
|
||||||
|
|
||||||
// Emit the region nodes.
|
// Emit the region nodes.
|
||||||
for region in regioncx.var_infos.indices() {
|
for region in regioncx.definitions.indices() {
|
||||||
write!(out, "{}[\"", region.as_usize())?;
|
write!(out, "{}[\"", region.as_usize())?;
|
||||||
render_region(region, regioncx, out)?;
|
render_region(region, regioncx, out)?;
|
||||||
writeln!(out, "\"]")?;
|
writeln!(out, "\"]")?;
|
||||||
|
@ -387,7 +387,7 @@ fn emit_mermaid_nll_sccs<'tcx>(
|
||||||
// Gather and emit the SCC nodes.
|
// Gather and emit the SCC nodes.
|
||||||
let mut nodes_per_scc: IndexVec<_, _> =
|
let mut nodes_per_scc: IndexVec<_, _> =
|
||||||
regioncx.constraint_sccs().all_sccs().map(|_| Vec::new()).collect();
|
regioncx.constraint_sccs().all_sccs().map(|_| Vec::new()).collect();
|
||||||
for region in regioncx.var_infos.indices() {
|
for region in regioncx.definitions.indices() {
|
||||||
let scc = regioncx.constraint_sccs().scc(region);
|
let scc = regioncx.constraint_sccs().scc(region);
|
||||||
nodes_per_scc[scc].push(region);
|
nodes_per_scc[scc].push(region);
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,13 +141,11 @@ impl RegionTracker {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RegionInferenceContext<'tcx> {
|
pub struct RegionInferenceContext<'tcx> {
|
||||||
pub var_infos: VarInfos,
|
|
||||||
|
|
||||||
/// Contains the definition for every region variable. Region
|
/// Contains the definition for every region variable. Region
|
||||||
/// variables are identified by their index (`RegionVid`). The
|
/// variables are identified by their index (`RegionVid`). The
|
||||||
/// definition contains information about where the region came
|
/// definition contains information about where the region came
|
||||||
/// from as well as its final inferred value.
|
/// from as well as its final inferred value.
|
||||||
definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>,
|
pub(crate) definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>,
|
||||||
|
|
||||||
/// The liveness constraints added to each region. For most
|
/// The liveness constraints added to each region. For most
|
||||||
/// regions, these start out empty and steadily grow, though for
|
/// regions, these start out empty and steadily grow, though for
|
||||||
|
@ -455,7 +453,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
Rc::new(member_constraints.into_mapped(|r| constraint_sccs.scc(r)));
|
Rc::new(member_constraints.into_mapped(|r| constraint_sccs.scc(r)));
|
||||||
|
|
||||||
let mut result = Self {
|
let mut result = Self {
|
||||||
var_infos,
|
|
||||||
definitions,
|
definitions,
|
||||||
liveness_constraints,
|
liveness_constraints,
|
||||||
constraints,
|
constraints,
|
||||||
|
|
|
@ -186,7 +186,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
fold_regions(tcx, ty, |region, _| match *region {
|
fold_regions(tcx, ty, |region, _| match region.kind() {
|
||||||
ty::ReVar(vid) => {
|
ty::ReVar(vid) => {
|
||||||
let scc = self.constraint_sccs.scc(vid);
|
let scc = self.constraint_sccs.scc(vid);
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||||
/// are dealt with during trait solving.
|
/// are dealt with during trait solving.
|
||||||
fn replace_placeholders_with_nll<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T {
|
fn replace_placeholders_with_nll<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T {
|
||||||
if value.has_placeholders() {
|
if value.has_placeholders() {
|
||||||
fold_regions(self.tcx, value, |r, _| match *r {
|
fold_regions(self.tcx, value, |r, _| match r.kind() {
|
||||||
ty::RePlaceholder(placeholder) => {
|
ty::RePlaceholder(placeholder) => {
|
||||||
self.constraints.placeholder_region(self.infcx, placeholder)
|
self.constraints.placeholder_region(self.infcx, placeholder)
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
|
fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
|
||||||
if let ty::RePlaceholder(placeholder) = *r {
|
if let ty::RePlaceholder(placeholder) = r.kind() {
|
||||||
self.constraints.placeholder_region(self.infcx, placeholder).as_var()
|
self.constraints.placeholder_region(self.infcx, placeholder).as_var()
|
||||||
} else {
|
} else {
|
||||||
self.universal_regions.to_region_vid(r)
|
self.universal_regions.to_region_vid(r)
|
||||||
|
|
|
@ -271,7 +271,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
match *r {
|
match r.kind() {
|
||||||
// ignore bound regions, keep visiting
|
// ignore bound regions, keep visiting
|
||||||
ty::ReBound(_, _) => {}
|
ty::ReBound(_, _) => {}
|
||||||
_ => (self.op)(r),
|
_ => (self.op)(r),
|
||||||
|
|
|
@ -909,19 +909,19 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
|
||||||
/// if it is a placeholder. Handling placeholders requires access to the
|
/// if it is a placeholder. Handling placeholders requires access to the
|
||||||
/// `MirTypeckRegionConstraints`.
|
/// `MirTypeckRegionConstraints`.
|
||||||
fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
|
fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
|
||||||
if let ty::ReVar(..) = *r {
|
match r.kind() {
|
||||||
r.as_var()
|
ty::ReVar(..) => r.as_var(),
|
||||||
} else if let ty::ReError(guar) = *r {
|
ty::ReError(guar) => {
|
||||||
self.tainted_by_errors.set(Some(guar));
|
self.tainted_by_errors.set(Some(guar));
|
||||||
// We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the
|
// We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the
|
||||||
// `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if
|
// `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if
|
||||||
// errors are being emitted and 2) it leaves the happy path unaffected.
|
// errors are being emitted and 2) it leaves the happy path unaffected.
|
||||||
self.fr_static
|
self.fr_static
|
||||||
} else {
|
}
|
||||||
*self
|
_ => *self
|
||||||
.indices
|
.indices
|
||||||
.get(&r)
|
.get(&r)
|
||||||
.unwrap_or_else(|| bug!("cannot convert `{:?}` to a region vid", r))
|
.unwrap_or_else(|| bug!("cannot convert `{:?}` to a region vid", r)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -442,7 +442,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
if let ty::ReLateParam(fr) = *r {
|
if let ty::ReLateParam(fr) = r.kind() {
|
||||||
ty::Region::new_late_param(
|
ty::Region::new_late_param(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
fr.scope,
|
fr.scope,
|
||||||
|
|
|
@ -631,7 +631,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||||
// Ignore `'static` lifetimes for the purpose of this lint: it's
|
// Ignore `'static` lifetimes for the purpose of this lint: it's
|
||||||
// because we know it outlives everything and so doesn't give meaningful
|
// because we know it outlives everything and so doesn't give meaningful
|
||||||
// clues. Also ignore `ReError`, to avoid knock-down errors.
|
// clues. Also ignore `ReError`, to avoid knock-down errors.
|
||||||
if let ty::ReStatic | ty::ReError(_) = **region_a {
|
if let ty::ReStatic | ty::ReError(_) = region_a.kind() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// For each region argument (e.g., `'a` in our example), check for a
|
// For each region argument (e.g., `'a` in our example), check for a
|
||||||
|
@ -672,7 +672,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||||
// Again, skip `'static` because it outlives everything. Also, we trivially
|
// Again, skip `'static` because it outlives everything. Also, we trivially
|
||||||
// know that a region outlives itself. Also ignore `ReError`, to avoid
|
// know that a region outlives itself. Also ignore `ReError`, to avoid
|
||||||
// knock-down errors.
|
// knock-down errors.
|
||||||
if matches!(**region_b, ty::ReStatic | ty::ReError(_)) || region_a == region_b {
|
if matches!(region_b.kind(), ty::ReStatic | ty::ReError(_)) || region_a == region_b {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if region_known_to_outlive(tcx, item_def_id, param_env, wf_tys, *region_a, *region_b) {
|
if region_known_to_outlive(tcx, item_def_id, param_env, wf_tys, *region_a, *region_b) {
|
||||||
|
|
|
@ -656,7 +656,7 @@ fn infringing_fields_error<'tcx>(
|
||||||
.entry((ty.clone(), predicate.clone()))
|
.entry((ty.clone(), predicate.clone()))
|
||||||
.or_default()
|
.or_default()
|
||||||
.push(origin.span());
|
.push(origin.span());
|
||||||
if let ty::RegionKind::ReEarlyParam(ebr) = *b
|
if let ty::RegionKind::ReEarlyParam(ebr) = b.kind()
|
||||||
&& ebr.has_name()
|
&& ebr.has_name()
|
||||||
{
|
{
|
||||||
bounds.push((b.to_string(), a.to_string(), None));
|
bounds.push((b.to_string(), a.to_string(), None));
|
||||||
|
|
|
@ -1416,7 +1416,7 @@ fn recover_infer_ret_ty<'tcx>(
|
||||||
GenericParamKind::Lifetime { .. } => true,
|
GenericParamKind::Lifetime { .. } => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
let fn_sig = fold_regions(tcx, fn_sig, |r, _| match *r {
|
let fn_sig = fold_regions(tcx, fn_sig, |r, _| match r.kind() {
|
||||||
ty::ReErased => {
|
ty::ReErased => {
|
||||||
if has_region_params {
|
if has_region_params {
|
||||||
ty::Region::new_error_with_message(
|
ty::Region::new_error_with_message(
|
||||||
|
|
|
@ -359,7 +359,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
|
||||||
) {
|
) {
|
||||||
for param in opaque_own_params {
|
for param in opaque_own_params {
|
||||||
let orig_lifetime = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
|
let orig_lifetime = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
|
||||||
if let ty::ReEarlyParam(..) = *orig_lifetime {
|
if let ty::ReEarlyParam(..) = orig_lifetime.kind() {
|
||||||
let dup_lifetime = ty::Region::new_early_param(
|
let dup_lifetime = ty::Region::new_early_param(
|
||||||
tcx,
|
tcx,
|
||||||
ty::EarlyParamRegion { index: param.index, name: param.name },
|
ty::EarlyParamRegion { index: param.index, name: param.name },
|
||||||
|
|
|
@ -80,7 +80,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
if let ty::ReEarlyParam(data) = *r {
|
if let ty::ReEarlyParam(data) = r.kind() {
|
||||||
self.parameters.push(Parameter::from(data));
|
self.parameters.push(Parameter::from(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,7 +146,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
|
||||||
|
|
||||||
fn is_free_region(region: Region<'_>) -> bool {
|
fn is_free_region(region: Region<'_>) -> bool {
|
||||||
// First, screen for regions that might appear in a type header.
|
// First, screen for regions that might appear in a type header.
|
||||||
match *region {
|
match region.kind() {
|
||||||
// These correspond to `T: 'a` relationships:
|
// These correspond to `T: 'a` relationships:
|
||||||
//
|
//
|
||||||
// struct Foo<'a, T> {
|
// struct Foo<'a, T> {
|
||||||
|
|
|
@ -428,7 +428,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
variance: VarianceTermPtr<'a>,
|
variance: VarianceTermPtr<'a>,
|
||||||
) {
|
) {
|
||||||
match *region {
|
match region.kind() {
|
||||||
ty::ReEarlyParam(ref data) => {
|
ty::ReEarlyParam(ref data) => {
|
||||||
self.add_constraint(current, data.index, variance);
|
self.add_constraint(current, data.index, variance);
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
|
||||||
) -> ty::Region<'tcx> {
|
) -> ty::Region<'tcx> {
|
||||||
let infcx = canonicalizer.infcx.unwrap();
|
let infcx = canonicalizer.infcx.unwrap();
|
||||||
|
|
||||||
if let ty::ReVar(vid) = *r {
|
if let ty::ReVar(vid) = r.kind() {
|
||||||
r = infcx
|
r = infcx
|
||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -171,7 +171,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReLateParam(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyParam(..) => r,
|
ty::ReLateParam(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyParam(..) => r,
|
||||||
|
|
||||||
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
|
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
|
||||||
|
@ -227,7 +227,7 @@ impl CanonicalizeMode for CanonicalizeUserTypeAnnotation {
|
||||||
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
|
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
|
||||||
r: ty::Region<'tcx>,
|
r: ty::Region<'tcx>,
|
||||||
) -> ty::Region<'tcx> {
|
) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReEarlyParam(_)
|
ty::ReEarlyParam(_)
|
||||||
| ty::ReLateParam(_)
|
| ty::ReLateParam(_)
|
||||||
| ty::ReErased
|
| ty::ReErased
|
||||||
|
@ -321,7 +321,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReBound(index, ..) => {
|
ty::ReBound(index, ..) => {
|
||||||
if index >= self.binder_index {
|
if index >= self.binder_index {
|
||||||
bug!("escaping late-bound region during canonicalization");
|
bug!("escaping late-bound region during canonicalization");
|
||||||
|
|
|
@ -432,7 +432,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
GenericArgKind::Lifetime(result_value) => {
|
GenericArgKind::Lifetime(result_value) => {
|
||||||
// e.g., here `result_value` might be `'?1` in the example above...
|
// e.g., here `result_value` might be `'?1` in the example above...
|
||||||
if let ty::ReBound(debruijn, br) = *result_value {
|
if let ty::ReBound(debruijn, br) = result_value.kind() {
|
||||||
// ... in which case we would set `canonical_vars[0]` to `Some('static)`.
|
// ... in which case we would set `canonical_vars[0]` to `Some('static)`.
|
||||||
|
|
||||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||||
|
|
|
@ -109,7 +109,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReBound(..) => {
|
ty::ReBound(..) => {
|
||||||
// leave bound regions alone
|
// leave bound regions alone
|
||||||
r
|
r
|
||||||
|
|
|
@ -218,7 +218,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
VarValue::Value(cur_region) => {
|
VarValue::Value(cur_region) => {
|
||||||
match *cur_region {
|
match cur_region.kind() {
|
||||||
// If this empty region is from a universe that can name the
|
// If this empty region is from a universe that can name the
|
||||||
// placeholder universe, then the LUB is the Placeholder region
|
// placeholder universe, then the LUB is the Placeholder region
|
||||||
// (which is the cur_region). Otherwise, the LUB is the Static
|
// (which is the cur_region). Otherwise, the LUB is the Static
|
||||||
|
@ -310,7 +310,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
|
|
||||||
match *b_data {
|
match *b_data {
|
||||||
VarValue::Empty(empty_ui) => {
|
VarValue::Empty(empty_ui) => {
|
||||||
let lub = match *a_region {
|
let lub = match a_region.kind() {
|
||||||
RePlaceholder(placeholder) => {
|
RePlaceholder(placeholder) => {
|
||||||
// If this empty region is from a universe that can
|
// If this empty region is from a universe that can
|
||||||
// name the placeholder, then the placeholder is
|
// name the placeholder, then the placeholder is
|
||||||
|
@ -350,7 +350,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
// tighter bound than `'static`.
|
// tighter bound than `'static`.
|
||||||
//
|
//
|
||||||
// (This might e.g. arise from being asked to prove `for<'a> { 'b: 'a }`.)
|
// (This might e.g. arise from being asked to prove `for<'a> { 'b: 'a }`.)
|
||||||
if let ty::RePlaceholder(p) = *lub
|
if let ty::RePlaceholder(p) = lub.kind()
|
||||||
&& b_universe.cannot_name(p.universe)
|
&& b_universe.cannot_name(p.universe)
|
||||||
{
|
{
|
||||||
lub = self.tcx().lifetimes.re_static;
|
lub = self.tcx().lifetimes.re_static;
|
||||||
|
@ -377,7 +377,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
a_ui.min(b_ui) == b_ui
|
a_ui.min(b_ui) == b_ui
|
||||||
}
|
}
|
||||||
(VarValue::Value(a), VarValue::Empty(_)) => {
|
(VarValue::Value(a), VarValue::Empty(_)) => {
|
||||||
match *a {
|
match a.kind() {
|
||||||
// this is always on an error path,
|
// this is always on an error path,
|
||||||
// so it doesn't really matter if it's shorter or longer than an empty region
|
// so it doesn't really matter if it's shorter or longer than an empty region
|
||||||
ReError(_) => false,
|
ReError(_) => false,
|
||||||
|
@ -410,7 +410,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(VarValue::Empty(a_ui), VarValue::Value(b)) => {
|
(VarValue::Empty(a_ui), VarValue::Value(b)) => {
|
||||||
match *b {
|
match b.kind() {
|
||||||
// this is always on an error path,
|
// this is always on an error path,
|
||||||
// so it doesn't really matter if it's shorter or longer than an empty region
|
// so it doesn't really matter if it's shorter or longer than an empty region
|
||||||
ReError(_) => false,
|
ReError(_) => false,
|
||||||
|
@ -479,7 +479,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
/// term "concrete regions").
|
/// term "concrete regions").
|
||||||
#[instrument(level = "trace", skip(self), ret)]
|
#[instrument(level = "trace", skip(self), ret)]
|
||||||
fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
|
fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
|
||||||
match (*a, *b) {
|
match (a.kind(), b.kind()) {
|
||||||
(ReBound(..), _) | (_, ReBound(..)) | (ReErased, _) | (_, ReErased) => {
|
(ReBound(..), _) | (_, ReBound(..)) | (ReErased, _) | (_, ReErased) => {
|
||||||
bug!("cannot relate region: LUB({:?}, {:?})", a, b);
|
bug!("cannot relate region: LUB({:?}, {:?})", a, b);
|
||||||
}
|
}
|
||||||
|
@ -725,7 +725,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
// SubSupConflict(ReLateParam, ReLateParam) when reporting error, and so
|
// SubSupConflict(ReLateParam, ReLateParam) when reporting error, and so
|
||||||
// the user will more likely get a specific suggestion.
|
// the user will more likely get a specific suggestion.
|
||||||
fn region_order_key(x: &RegionAndOrigin<'_>) -> u8 {
|
fn region_order_key(x: &RegionAndOrigin<'_>) -> u8 {
|
||||||
match *x.region {
|
match x.region.kind() {
|
||||||
ReEarlyParam(_) => 0,
|
ReEarlyParam(_) => 0,
|
||||||
ReLateParam(_) => 1,
|
ReLateParam(_) => 1,
|
||||||
_ => 2,
|
_ => 2,
|
||||||
|
@ -737,7 +737,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
let node_universe = self.var_infos[node_idx].universe;
|
let node_universe = self.var_infos[node_idx].universe;
|
||||||
|
|
||||||
for lower_bound in &lower_bounds {
|
for lower_bound in &lower_bounds {
|
||||||
let effective_lower_bound = if let ty::RePlaceholder(p) = *lower_bound.region {
|
let effective_lower_bound = if let ty::RePlaceholder(p) = lower_bound.region.kind() {
|
||||||
if node_universe.cannot_name(p.universe) {
|
if node_universe.cannot_name(p.universe) {
|
||||||
self.tcx().lifetimes.re_static
|
self.tcx().lifetimes.re_static
|
||||||
} else {
|
} else {
|
||||||
|
@ -785,7 +785,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
.expect("lower_vid_bounds should at least include `node_idx`");
|
.expect("lower_vid_bounds should at least include `node_idx`");
|
||||||
|
|
||||||
for upper_bound in &upper_bounds {
|
for upper_bound in &upper_bounds {
|
||||||
if let ty::RePlaceholder(p) = *upper_bound.region {
|
if let ty::RePlaceholder(p) = upper_bound.region.kind() {
|
||||||
if min_universe.cannot_name(p.universe) {
|
if min_universe.cannot_name(p.universe) {
|
||||||
let origin = self.var_infos[node_idx].origin;
|
let origin = self.var_infos[node_idx].origin;
|
||||||
errors.push(RegionResolutionError::UpperBoundUniverseConflict(
|
errors.push(RegionResolutionError::UpperBoundUniverseConflict(
|
||||||
|
@ -913,7 +913,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
generic_ty: Ty<'tcx>,
|
generic_ty: Ty<'tcx>,
|
||||||
min: ty::Region<'tcx>,
|
min: ty::Region<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if let ty::ReError(_) = *min {
|
if let ty::ReError(_) = min.kind() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,18 +931,18 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
VerifyBound::OutlivedBy(r) => {
|
VerifyBound::OutlivedBy(r) => {
|
||||||
let a = match *min {
|
let a = match min.kind() {
|
||||||
ty::ReVar(rid) => var_values.values[rid],
|
ty::ReVar(rid) => var_values.values[rid],
|
||||||
_ => VarValue::Value(min),
|
_ => VarValue::Value(min),
|
||||||
};
|
};
|
||||||
let b = match **r {
|
let b = match r.kind() {
|
||||||
ty::ReVar(rid) => var_values.values[rid],
|
ty::ReVar(rid) => var_values.values[rid],
|
||||||
_ => VarValue::Value(*r),
|
_ => VarValue::Value(*r),
|
||||||
};
|
};
|
||||||
self.sub_region_values(a, b)
|
self.sub_region_values(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
VerifyBound::IsEmpty => match *min {
|
VerifyBound::IsEmpty => match min.kind() {
|
||||||
ty::ReVar(rid) => match var_values.values[rid] {
|
ty::ReVar(rid) => match var_values.values[rid] {
|
||||||
VarValue::ErrorValue => false,
|
VarValue::ErrorValue => false,
|
||||||
VarValue::Empty(_) => true,
|
VarValue::Empty(_) => true,
|
||||||
|
@ -989,7 +989,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
r: ty::Region<'tcx>,
|
r: ty::Region<'tcx>,
|
||||||
) -> ty::Region<'tcx> {
|
) -> ty::Region<'tcx> {
|
||||||
let result = match *r {
|
let result = match r.kind() {
|
||||||
ty::ReVar(rid) => match self.values[rid] {
|
ty::ReVar(rid) => match self.values[rid] {
|
||||||
VarValue::Empty(_) => r,
|
VarValue::Empty(_) => r,
|
||||||
VarValue::Value(r) => r,
|
VarValue::Value(r) => r,
|
||||||
|
|
|
@ -69,7 +69,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> {
|
||||||
region_bound_pairs
|
region_bound_pairs
|
||||||
.insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a));
|
.insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a));
|
||||||
}
|
}
|
||||||
OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) {
|
OutlivesBound::RegionSubRegion(r_a, r_b) => match (r_a.kind(), r_b.kind()) {
|
||||||
(
|
(
|
||||||
ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
|
ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
|
||||||
ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
|
ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
|
||||||
|
|
|
@ -29,7 +29,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
match *r {
|
match r.kind() {
|
||||||
// ignore bound regions, keep visiting
|
// ignore bound regions, keep visiting
|
||||||
ty::ReBound(_, _) => {}
|
ty::ReBound(_, _) => {}
|
||||||
_ => (self.op)(r),
|
_ => (self.op)(r),
|
||||||
|
|
|
@ -155,7 +155,7 @@ impl<'a, 'tcx> LeakCheck<'a, 'tcx> {
|
||||||
self.scc_universes[scc].take_min(universe, *region);
|
self.scc_universes[scc].take_min(universe, *region);
|
||||||
|
|
||||||
// Detect those SCCs that directly contain a placeholder
|
// Detect those SCCs that directly contain a placeholder
|
||||||
if let ty::RePlaceholder(placeholder) = **region {
|
if let ty::RePlaceholder(placeholder) = region.kind() {
|
||||||
if self.outer_universe.cannot_name(placeholder.universe) {
|
if self.outer_universe.cannot_name(placeholder.universe) {
|
||||||
// Update `scc_placeholders` to account for the fact that `P: S` must hold.
|
// Update `scc_placeholders` to account for the fact that `P: S` must hold.
|
||||||
match self.scc_placeholders[scc] {
|
match self.scc_placeholders[scc] {
|
||||||
|
|
|
@ -463,7 +463,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
// cannot add constraints once regions are resolved
|
// cannot add constraints once regions are resolved
|
||||||
debug!("origin = {:#?}", origin);
|
debug!("origin = {:#?}", origin);
|
||||||
|
|
||||||
match (*sub, *sup) {
|
match (sub.kind(), sup.kind()) {
|
||||||
(ReBound(..), _) | (_, ReBound(..)) => {
|
(ReBound(..), _) | (_, ReBound(..)) => {
|
||||||
span_bug!(origin.span(), "cannot relate bound region: {:?} <= {:?}", sub, sup);
|
span_bug!(origin.span(), "cannot relate bound region: {:?} <= {:?}", sub, sup);
|
||||||
}
|
}
|
||||||
|
@ -595,7 +595,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn universe(&mut self, region: Region<'tcx>) -> ty::UniverseIndex {
|
pub fn universe(&mut self, region: Region<'tcx>) -> ty::UniverseIndex {
|
||||||
match *region {
|
match region.kind() {
|
||||||
ty::ReStatic
|
ty::ReStatic
|
||||||
| ty::ReErased
|
| ty::ReErased
|
||||||
| ty::ReLateParam(..)
|
| ty::ReLateParam(..)
|
||||||
|
|
|
@ -571,7 +571,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
|
||||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||||
assert_eq!(r, r2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==
|
assert_eq!(r, r2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==
|
||||||
|
|
||||||
match *r {
|
match r.kind() {
|
||||||
// Never make variables for regions bound within the type itself,
|
// Never make variables for regions bound within the type itself,
|
||||||
// nor for erased regions.
|
// nor for erased regions.
|
||||||
ty::ReBound(..) | ty::ReErased => {
|
ty::ReBound(..) | ty::ReErased => {
|
||||||
|
|
|
@ -89,7 +89,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticRegionResolver<'a, 'tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReVar(vid) => self
|
ty::ReVar(vid) => self
|
||||||
.infcx
|
.infcx
|
||||||
.inner
|
.inner
|
||||||
|
@ -153,7 +153,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReVar(_) => Ok(self
|
ty::ReVar(_) => Ok(self
|
||||||
.infcx
|
.infcx
|
||||||
.lexical_region_resolutions
|
.lexical_region_resolutions
|
||||||
|
|
|
@ -1988,7 +1988,7 @@ impl ExplicitOutlivesRequirements {
|
||||||
|
|
||||||
inferred_outlives
|
inferred_outlives
|
||||||
.filter_map(|(clause, _)| match clause.kind().skip_binder() {
|
.filter_map(|(clause, _)| match clause.kind().skip_binder() {
|
||||||
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a {
|
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match a.kind() {
|
||||||
ty::ReEarlyParam(ebr)
|
ty::ReEarlyParam(ebr)
|
||||||
if item_generics.region_param(ebr, tcx).def_id == lifetime.to_def_id() =>
|
if item_generics.region_param(ebr, tcx).def_id == lifetime.to_def_id() =>
|
||||||
{
|
{
|
||||||
|
@ -2038,7 +2038,7 @@ impl ExplicitOutlivesRequirements {
|
||||||
let is_inferred = match tcx.named_bound_var(lifetime.hir_id) {
|
let is_inferred = match tcx.named_bound_var(lifetime.hir_id) {
|
||||||
Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives
|
Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives
|
||||||
.iter()
|
.iter()
|
||||||
.any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { item_generics.region_param(ebr, tcx).def_id == def_id.to_def_id() })),
|
.any(|r| matches!(r.kind(), ty::ReEarlyParam(ebr) if { item_generics.region_param(ebr, tcx).def_id == def_id.to_def_id() })),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -461,7 +461,7 @@ fn extract_def_id_from_arg<'tcx>(
|
||||||
arg: ty::GenericArg<'tcx>,
|
arg: ty::GenericArg<'tcx>,
|
||||||
) -> DefId {
|
) -> DefId {
|
||||||
match arg.unpack() {
|
match arg.unpack() {
|
||||||
ty::GenericArgKind::Lifetime(re) => match *re {
|
ty::GenericArgKind::Lifetime(re) => match re.kind() {
|
||||||
ty::ReEarlyParam(ebr) => generics.region_param(ebr, tcx).def_id,
|
ty::ReEarlyParam(ebr) => generics.region_param(ebr, tcx).def_id,
|
||||||
ty::ReBound(
|
ty::ReBound(
|
||||||
_,
|
_,
|
||||||
|
@ -530,7 +530,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for FunctionalVariances<'tcx> {
|
||||||
a: ty::Region<'tcx>,
|
a: ty::Region<'tcx>,
|
||||||
_: ty::Region<'tcx>,
|
_: ty::Region<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||||
let def_id = match *a {
|
let def_id = match a.kind() {
|
||||||
ty::ReEarlyParam(ebr) => self.generics.region_param(ebr, self.tcx).def_id,
|
ty::ReEarlyParam(ebr) => self.generics.region_param(ebr, self.tcx).def_id,
|
||||||
ty::ReBound(
|
ty::ReBound(
|
||||||
_,
|
_,
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> {
|
||||||
// We must not erase bound regions. `for<'a> fn(&'a ())` and
|
// We must not erase bound regions. `for<'a> fn(&'a ())` and
|
||||||
// `fn(&'free ())` are different types: they may implement different
|
// `fn(&'free ())` are different types: they may implement different
|
||||||
// traits and have a different `TypeId`.
|
// traits and have a different `TypeId`.
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReBound(..) => r,
|
ty::ReBound(..) => r,
|
||||||
_ => self.tcx.lifetimes.re_erased,
|
_ => self.tcx.lifetimes.re_erased,
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,7 +288,7 @@ impl FlagComputation {
|
||||||
|
|
||||||
fn add_region(&mut self, r: ty::Region<'_>) {
|
fn add_region(&mut self, r: ty::Region<'_>) {
|
||||||
self.add_flags(r.type_flags());
|
self.add_flags(r.type_flags());
|
||||||
if let ty::ReBound(debruijn, _) = *r {
|
if let ty::ReBound(debruijn, _) = r.kind() {
|
||||||
self.add_bound_var(debruijn);
|
self.add_bound_var(debruijn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,10 +145,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReBound(debruijn, br) if debruijn == self.current_index => {
|
ty::ReBound(debruijn, br) if debruijn == self.current_index => {
|
||||||
let region = self.delegate.replace_region(br);
|
let region = self.delegate.replace_region(br);
|
||||||
if let ty::ReBound(debruijn1, br) = *region {
|
if let ty::ReBound(debruijn1, br) = region.kind() {
|
||||||
// If the callback returns a bound region,
|
// If the callback returns a bound region,
|
||||||
// that region should always use the INNERMOST
|
// that region should always use the INNERMOST
|
||||||
// debruijn index. Then we adjust it to the
|
// debruijn index. Then we adjust it to the
|
||||||
|
|
|
@ -95,7 +95,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match r.kind() {
|
||||||
// Ignore bound regions and `'static` regions that appear in the
|
// Ignore bound regions and `'static` regions that appear in the
|
||||||
// type, we only need to remap regions that reference lifetimes
|
// type, we only need to remap regions that reference lifetimes
|
||||||
// from the function declaration.
|
// from the function declaration.
|
||||||
|
|
|
@ -2520,7 +2520,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
|
||||||
|
|
||||||
let identify_regions = self.tcx.sess.opts.unstable_opts.identify_regions;
|
let identify_regions = self.tcx.sess.opts.unstable_opts.identify_regions;
|
||||||
|
|
||||||
match *region {
|
match region.kind() {
|
||||||
ty::ReEarlyParam(ref data) => data.has_name(),
|
ty::ReEarlyParam(ref data) => data.has_name(),
|
||||||
|
|
||||||
ty::ReLateParam(ty::LateParamRegion { kind, .. }) => kind.is_named(),
|
ty::ReLateParam(ty::LateParamRegion { kind, .. }) => kind.is_named(),
|
||||||
|
@ -2590,7 +2590,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
|
||||||
// the user might want to diagnose an error, but there is basically no way
|
// the user might want to diagnose an error, but there is basically no way
|
||||||
// to fit that into a short string. Hence the recommendation to use
|
// to fit that into a short string. Hence the recommendation to use
|
||||||
// `explain_region()` or `note_and_explain_region()`.
|
// `explain_region()` or `note_and_explain_region()`.
|
||||||
match *region {
|
match region.kind() {
|
||||||
ty::ReEarlyParam(data) => {
|
ty::ReEarlyParam(data) => {
|
||||||
p!(write("{}", data.name));
|
p!(write("{}", data.name));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -2680,7 +2680,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
let name = &mut self.name;
|
let name = &mut self.name;
|
||||||
let region = match *r {
|
let region = match r.kind() {
|
||||||
ty::ReBound(db, br) if db >= self.current_index => {
|
ty::ReBound(db, br) if db >= self.current_index => {
|
||||||
*self.region_map.entry(br).or_insert_with(|| name(Some(db), self.current_index, br))
|
*self.region_map.entry(br).or_insert_with(|| name(Some(db), self.current_index, br))
|
||||||
}
|
}
|
||||||
|
@ -2704,7 +2704,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
_ => return r,
|
_ => return r,
|
||||||
};
|
};
|
||||||
if let ty::ReBound(debruijn1, br) = *region {
|
if let ty::ReBound(debruijn1, br) = region.kind() {
|
||||||
assert_eq!(debruijn1, ty::INNERMOST);
|
assert_eq!(debruijn1, ty::INNERMOST);
|
||||||
ty::Region::new_bound(self.tcx, self.current_index, br)
|
ty::Region::new_bound(self.tcx, self.current_index, br)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
use rustc_errors::MultiSpan;
|
use rustc_errors::MultiSpan;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
@ -22,7 +20,7 @@ impl<'tcx> rustc_type_ir::inherent::IntoKind for Region<'tcx> {
|
||||||
type Kind = RegionKind<'tcx>;
|
type Kind = RegionKind<'tcx>;
|
||||||
|
|
||||||
fn kind(self) -> RegionKind<'tcx> {
|
fn kind(self) -> RegionKind<'tcx> {
|
||||||
*self
|
*self.0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +30,7 @@ impl<'tcx> rustc_type_ir::Flags for Region<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
|
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
|
||||||
match **self {
|
match self.kind() {
|
||||||
ty::ReBound(debruijn, _) => debruijn.shifted_in(1),
|
ty::ReBound(debruijn, _) => debruijn.shifted_in(1),
|
||||||
_ => ty::INNERMOST,
|
_ => ty::INNERMOST,
|
||||||
}
|
}
|
||||||
|
@ -163,7 +161,7 @@ impl<'tcx> Region<'tcx> {
|
||||||
|
|
||||||
pub fn get_name(self) -> Option<Symbol> {
|
pub fn get_name(self) -> Option<Symbol> {
|
||||||
if self.has_name() {
|
if self.has_name() {
|
||||||
match *self {
|
match self.kind() {
|
||||||
ty::ReEarlyParam(ebr) => Some(ebr.name),
|
ty::ReEarlyParam(ebr) => Some(ebr.name),
|
||||||
ty::ReBound(_, br) => br.kind.get_name(),
|
ty::ReBound(_, br) => br.kind.get_name(),
|
||||||
ty::ReLateParam(fr) => fr.kind.get_name(),
|
ty::ReLateParam(fr) => fr.kind.get_name(),
|
||||||
|
@ -185,7 +183,7 @@ impl<'tcx> Region<'tcx> {
|
||||||
|
|
||||||
/// Is this region named by the user?
|
/// Is this region named by the user?
|
||||||
pub fn has_name(self) -> bool {
|
pub fn has_name(self) -> bool {
|
||||||
match *self {
|
match self.kind() {
|
||||||
ty::ReEarlyParam(ebr) => ebr.has_name(),
|
ty::ReEarlyParam(ebr) => ebr.has_name(),
|
||||||
ty::ReBound(_, br) => br.kind.is_named(),
|
ty::ReBound(_, br) => br.kind.is_named(),
|
||||||
ty::ReLateParam(fr) => fr.kind.is_named(),
|
ty::ReLateParam(fr) => fr.kind.is_named(),
|
||||||
|
@ -199,32 +197,32 @@ impl<'tcx> Region<'tcx> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_error(self) -> bool {
|
pub fn is_error(self) -> bool {
|
||||||
matches!(*self, ty::ReError(_))
|
matches!(self.kind(), ty::ReError(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_static(self) -> bool {
|
pub fn is_static(self) -> bool {
|
||||||
matches!(*self, ty::ReStatic)
|
matches!(self.kind(), ty::ReStatic)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_erased(self) -> bool {
|
pub fn is_erased(self) -> bool {
|
||||||
matches!(*self, ty::ReErased)
|
matches!(self.kind(), ty::ReErased)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_bound(self) -> bool {
|
pub fn is_bound(self) -> bool {
|
||||||
matches!(*self, ty::ReBound(..))
|
matches!(self.kind(), ty::ReBound(..))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_placeholder(self) -> bool {
|
pub fn is_placeholder(self) -> bool {
|
||||||
matches!(*self, ty::RePlaceholder(..))
|
matches!(self.kind(), ty::RePlaceholder(..))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
|
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
|
||||||
match *self {
|
match self.kind() {
|
||||||
ty::ReBound(debruijn, _) => debruijn >= index,
|
ty::ReBound(debruijn, _) => debruijn >= index,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -233,7 +231,7 @@ impl<'tcx> Region<'tcx> {
|
||||||
pub fn type_flags(self) -> TypeFlags {
|
pub fn type_flags(self) -> TypeFlags {
|
||||||
let mut flags = TypeFlags::empty();
|
let mut flags = TypeFlags::empty();
|
||||||
|
|
||||||
match *self {
|
match self.kind() {
|
||||||
ty::ReVar(..) => {
|
ty::ReVar(..) => {
|
||||||
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
||||||
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
|
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
|
||||||
|
@ -275,14 +273,14 @@ impl<'tcx> Region<'tcx> {
|
||||||
|
|
||||||
/// True for free regions other than `'static`.
|
/// True for free regions other than `'static`.
|
||||||
pub fn is_param(self) -> bool {
|
pub fn is_param(self) -> bool {
|
||||||
matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_))
|
matches!(self.kind(), ty::ReEarlyParam(_) | ty::ReLateParam(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// True for free region in the current context.
|
/// True for free region in the current context.
|
||||||
///
|
///
|
||||||
/// This is the case for `'static` and param regions.
|
/// This is the case for `'static` and param regions.
|
||||||
pub fn is_free(self) -> bool {
|
pub fn is_free(self) -> bool {
|
||||||
match *self {
|
match self.kind() {
|
||||||
ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true,
|
ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true,
|
||||||
ty::ReVar(..)
|
ty::ReVar(..)
|
||||||
| ty::RePlaceholder(..)
|
| ty::RePlaceholder(..)
|
||||||
|
@ -319,15 +317,6 @@ impl<'tcx> Region<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Deref for Region<'tcx> {
|
|
||||||
type Target = RegionKind<'tcx>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn deref(&self) -> &RegionKind<'tcx> {
|
|
||||||
self.0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||||
#[derive(HashStable)]
|
#[derive(HashStable)]
|
||||||
pub struct EarlyParamRegion {
|
pub struct EarlyParamRegion {
|
||||||
|
|
|
@ -758,7 +758,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
GenericArgKind::Lifetime(r) => match *r {
|
GenericArgKind::Lifetime(r) => match r.kind() {
|
||||||
ty::ReBound(debruijn, br) => {
|
ty::ReBound(debruijn, br) => {
|
||||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||||
assert_eq!(debruijn, ty::INNERMOST);
|
assert_eq!(debruijn, ty::INNERMOST);
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReBound(debruijn, _) if debruijn < self.outer_index => {
|
ty::ReBound(debruijn, _) if debruijn < self.outer_index => {
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
if let ty::ReBound(debruijn, br) = *r {
|
if let ty::ReBound(debruijn, br) = r.kind() {
|
||||||
if debruijn == self.current_index {
|
if debruijn == self.current_index {
|
||||||
self.regions.insert(br.kind);
|
self.regions.insert(br.kind);
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
if let ty::RePlaceholder(placeholder) = *r {
|
if let ty::RePlaceholder(placeholder) = r.kind() {
|
||||||
self.max_universe = ty::UniverseIndex::from_u32(
|
self.max_universe = ty::UniverseIndex::from_u32(
|
||||||
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
use rustc_abi::{FIRST_VARIANT, FieldIdx, Integer, VariantIdx};
|
use rustc_abi::{FIRST_VARIANT, FieldIdx, Integer, VariantIdx};
|
||||||
use rustc_arena::DroplessArena;
|
use rustc_arena::DroplessArena;
|
||||||
|
@ -11,7 +12,8 @@ use rustc_middle::mir::{self, Const};
|
||||||
use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary};
|
use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary};
|
||||||
use rustc_middle::ty::layout::IntegerExt;
|
use rustc_middle::ty::layout::IntegerExt;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef,
|
self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
|
||||||
|
TypeVisitableExt, TypeVisitor, VariantDef,
|
||||||
};
|
};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
|
@ -135,11 +137,22 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
||||||
/// Returns the hidden type corresponding to this key if the body under analysis is allowed to
|
/// Returns the hidden type corresponding to this key if the body under analysis is allowed to
|
||||||
/// know it.
|
/// know it.
|
||||||
fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>> {
|
fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>> {
|
||||||
self.typeck_results
|
if let Some(hidden_ty) = self.typeck_results.concrete_opaque_types.get(&key.def_id) {
|
||||||
.concrete_opaque_types
|
let ty = ty::EarlyBinder::bind(hidden_ty.ty).instantiate(self.tcx, key.args);
|
||||||
.get(&key.def_id)
|
if ty.visit_with(&mut RecursiveOpaque { def_id: key.def_id.into() }).is_continue() {
|
||||||
.map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args))
|
Some(ty)
|
||||||
|
} else {
|
||||||
|
// HACK: We skip revealing opaque types which recursively expand
|
||||||
|
// to themselves. This is because we may infer hidden types like
|
||||||
|
// `Opaque<T> = Opaque<Opaque<T>>` or `Opaque<T> = Opaque<(T,)>`
|
||||||
|
// in hir typeck.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This can take a non-revealed `Ty` because it reveals opaques itself.
|
// This can take a non-revealed `Ty` because it reveals opaques itself.
|
||||||
pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
|
pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
|
||||||
!ty.inhabited_predicate(self.tcx).apply_revealing_opaque(
|
!ty.inhabited_predicate(self.tcx).apply_revealing_opaque(
|
||||||
|
@ -1105,3 +1118,20 @@ pub fn analyze_match<'p, 'tcx>(
|
||||||
|
|
||||||
Ok(report)
|
Ok(report)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RecursiveOpaque {
|
||||||
|
def_id: DefId,
|
||||||
|
}
|
||||||
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for RecursiveOpaque {
|
||||||
|
type Result = ControlFlow<()>;
|
||||||
|
|
||||||
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
|
||||||
|
if let ty::Alias(ty::Opaque, alias_ty) = t.kind() {
|
||||||
|
if alias_ty.def_id == self.def_id {
|
||||||
|
return ControlFlow::Break(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.has_opaque_types() { t.super_visit_with(self) } else { ControlFlow::Continue(()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -368,7 +368,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_region(&mut self, region: ty::Region<'_>) -> Result<(), PrintError> {
|
fn print_region(&mut self, region: ty::Region<'_>) -> Result<(), PrintError> {
|
||||||
let i = match *region {
|
let i = match region.kind() {
|
||||||
// Erased lifetimes use the index 0, for a
|
// Erased lifetimes use the index 0, for a
|
||||||
// shorter mangling of `L_`.
|
// shorter mangling of `L_`.
|
||||||
ty::ReErased => 0,
|
ty::ReErased => 0,
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub fn find_param_with_region<'tcx>(
|
||||||
anon_region: Region<'tcx>,
|
anon_region: Region<'tcx>,
|
||||||
replace_region: Region<'tcx>,
|
replace_region: Region<'tcx>,
|
||||||
) -> Option<AnonymousParamInfo<'tcx>> {
|
) -> Option<AnonymousParamInfo<'tcx>> {
|
||||||
let (id, kind) = match *anon_region {
|
let (id, kind) = match anon_region.kind() {
|
||||||
ty::ReLateParam(late_param) => (late_param.scope, late_param.kind),
|
ty::ReLateParam(late_param) => (late_param.scope, late_param.kind),
|
||||||
ty::ReEarlyParam(ebr) => {
|
ty::ReEarlyParam(ebr) => {
|
||||||
let region_def = tcx.generics_of(generic_param_scope).region_param(ebr, tcx).def_id;
|
let region_def = tcx.generics_of(generic_param_scope).region_param(ebr, tcx).def_id;
|
||||||
|
|
|
@ -299,7 +299,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
self.tcx.param_env(generic_param_scope),
|
self.tcx.param_env(generic_param_scope),
|
||||||
terr,
|
terr,
|
||||||
);
|
);
|
||||||
match (*sub, *sup) {
|
match (sub.kind(), sup.kind()) {
|
||||||
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
|
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
|
||||||
(ty::RePlaceholder(_), _) => {
|
(ty::RePlaceholder(_), _) => {
|
||||||
note_and_explain_region(
|
note_and_explain_region(
|
||||||
|
@ -391,7 +391,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
infer::RelateParamBound(span, ty, opt_span) => {
|
infer::RelateParamBound(span, ty, opt_span) => {
|
||||||
let prefix = match *sub {
|
let prefix = match sub.kind() {
|
||||||
ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy,
|
ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy,
|
||||||
_ => note_and_explain::PrefixKind::TypeOutlive,
|
_ => note_and_explain::PrefixKind::TypeOutlive,
|
||||||
};
|
};
|
||||||
|
@ -1048,7 +1048,7 @@ pub(super) fn note_and_explain_region<'tcx>(
|
||||||
suffix: &str,
|
suffix: &str,
|
||||||
alt_span: Option<Span>,
|
alt_span: Option<Span>,
|
||||||
) {
|
) {
|
||||||
let (description, span) = match *region {
|
let (description, span) = match region.kind() {
|
||||||
ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => {
|
ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => {
|
||||||
msg_span_from_named_region(tcx, generic_param_scope, region, alt_span)
|
msg_span_from_named_region(tcx, generic_param_scope, region, alt_span)
|
||||||
}
|
}
|
||||||
|
@ -1085,7 +1085,7 @@ fn msg_span_from_named_region<'tcx>(
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
alt_span: Option<Span>,
|
alt_span: Option<Span>,
|
||||||
) -> (String, Option<Span>) {
|
) -> (String, Option<Span>) {
|
||||||
match *region {
|
match region.kind() {
|
||||||
ty::ReEarlyParam(br) => {
|
ty::ReEarlyParam(br) => {
|
||||||
let param_def_id = tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id;
|
let param_def_id = tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id;
|
||||||
let span = tcx.def_span(param_def_id);
|
let span = tcx.def_span(param_def_id);
|
||||||
|
@ -1185,7 +1185,7 @@ pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>(
|
||||||
});
|
});
|
||||||
|
|
||||||
// Explain the region we are capturing.
|
// Explain the region we are capturing.
|
||||||
match *hidden_region {
|
match hidden_region.kind() {
|
||||||
ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
|
ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => {
|
||||||
// Assuming regionck succeeded (*), we ought to always be
|
// Assuming regionck succeeded (*), we ought to always be
|
||||||
// capturing *some* region from the fn header, and hence it
|
// capturing *some* region from the fn header, and hence it
|
||||||
|
|
|
@ -20,7 +20,7 @@ impl<'a> DescriptionCtx<'a> {
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
alt_span: Option<Span>,
|
alt_span: Option<Span>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let (span, kind, arg) = match *region {
|
let (span, kind, arg) = match region.kind() {
|
||||||
ty::ReEarlyParam(br) => {
|
ty::ReEarlyParam(br) => {
|
||||||
let scope = tcx
|
let scope = tcx
|
||||||
.parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id)
|
.parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id)
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
|
||||||
GenericArgKind::Lifetime(lt) => match defining_scope_kind {
|
GenericArgKind::Lifetime(lt) => match defining_scope_kind {
|
||||||
DefiningScopeKind::HirTypeck => continue,
|
DefiningScopeKind::HirTypeck => continue,
|
||||||
DefiningScopeKind::MirBorrowck => {
|
DefiningScopeKind::MirBorrowck => {
|
||||||
matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_))
|
matches!(lt.kind(), ty::ReEarlyParam(_) | ty::ReLateParam(_))
|
||||||
|| (lt.is_static() && opaque_env.param_equal_static(i))
|
|| (lt.is_static() && opaque_env.param_equal_static(i))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -382,7 +382,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
for (new_region, old_region) in
|
for (new_region, old_region) in
|
||||||
iter::zip(new_args.regions(), old_args.regions())
|
iter::zip(new_args.regions(), old_args.regions())
|
||||||
{
|
{
|
||||||
match (*new_region, *old_region) {
|
match (new_region.kind(), old_region.kind()) {
|
||||||
// If both predicates have an `ReBound` (a HRTB) in the
|
// If both predicates have an `ReBound` (a HRTB) in the
|
||||||
// same spot, we do nothing.
|
// same spot, we do nothing.
|
||||||
(ty::ReBound(_, _), ty::ReBound(_, _)) => {}
|
(ty::ReBound(_, _), ty::ReBound(_, _)) => {}
|
||||||
|
|
|
@ -537,7 +537,7 @@ fn plug_infer_with_placeholders<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
if let ty::ReVar(vid) = *r {
|
if let ty::ReVar(vid) = r.kind() {
|
||||||
let r = self
|
let r = self
|
||||||
.infcx
|
.infcx
|
||||||
.inner
|
.inner
|
||||||
|
|
|
@ -797,7 +797,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseEscapingBoundRegions<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
if let ty::ReBound(debruijn, _) = *r
|
if let ty::ReBound(debruijn, _) = r.kind()
|
||||||
&& debruijn < self.binder
|
&& debruijn < self.binder
|
||||||
{
|
{
|
||||||
r
|
r
|
||||||
|
|
|
@ -144,7 +144,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReBound(debruijn, _) if debruijn > self.outer_index => {
|
ty::ReBound(debruijn, _) if debruijn > self.outer_index => {
|
||||||
self.escaping =
|
self.escaping =
|
||||||
self.escaping.max(debruijn.as_usize() - self.outer_index.as_usize());
|
self.escaping.max(debruijn.as_usize() - self.outer_index.as_usize());
|
||||||
|
|
|
@ -289,7 +289,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match r.kind() {
|
||||||
ty::ReBound(debruijn, _)
|
ty::ReBound(debruijn, _)
|
||||||
if debruijn.as_usize()
|
if debruijn.as_usize()
|
||||||
>= self.current_index.as_usize() + self.universe_indices.len() =>
|
>= self.current_index.as_usize() + self.universe_indices.len() =>
|
||||||
|
@ -407,7 +407,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
let r1 = match *r0 {
|
let r1 = match r0.kind() {
|
||||||
ty::ReVar(vid) => self
|
ty::ReVar(vid) => self
|
||||||
.infcx
|
.infcx
|
||||||
.inner
|
.inner
|
||||||
|
@ -417,7 +417,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
|
||||||
_ => r0,
|
_ => r0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let r2 = match *r1 {
|
let r2 = match r1.kind() {
|
||||||
ty::RePlaceholder(p) => {
|
ty::RePlaceholder(p) => {
|
||||||
let replace_var = self.mapped_regions.get(&p);
|
let replace_var = self.mapped_regions.get(&p);
|
||||||
match replace_var {
|
match replace_var {
|
||||||
|
|
|
@ -75,7 +75,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
|
||||||
{
|
{
|
||||||
let orig_lt =
|
let orig_lt =
|
||||||
tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
|
tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
|
||||||
if matches!(*orig_lt, ty::ReLateParam(..)) {
|
if matches!(orig_lt.kind(), ty::ReLateParam(..)) {
|
||||||
mapping.insert(
|
mapping.insert(
|
||||||
orig_lt,
|
orig_lt,
|
||||||
ty::Region::new_early_param(
|
ty::Region::new_early_param(
|
||||||
|
|
|
@ -2803,6 +2803,10 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||||
/// want to use the [`Default`] trait to generate values, you can
|
/// want to use the [`Default`] trait to generate values, you can
|
||||||
/// pass [`Default::default`] as the second argument.
|
/// pass [`Default::default`] as the second argument.
|
||||||
///
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the new capacity exceeds `isize::MAX` _bytes_.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -3010,6 +3014,10 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
|
||||||
/// [`Clone`]), use [`Vec::resize_with`].
|
/// [`Clone`]), use [`Vec::resize_with`].
|
||||||
/// If you only need to resize to a smaller size, use [`Vec::truncate`].
|
/// If you only need to resize to a smaller size, use [`Vec::truncate`].
|
||||||
///
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the new capacity exceeds `isize::MAX` _bytes_.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -101,13 +101,13 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
|
||||||
/// Primary function to implement `Step` logic.
|
/// Primary function to implement `Step` logic.
|
||||||
///
|
///
|
||||||
/// This function can be triggered in two ways:
|
/// This function can be triggered in two ways:
|
||||||
/// 1. Directly from [`Builder::execute_cli`].
|
/// 1. Directly from [`Builder::execute_cli`].
|
||||||
/// 2. Indirectly by being called from other `Step`s using [`Builder::ensure`].
|
/// 2. Indirectly by being called from other `Step`s using [`Builder::ensure`].
|
||||||
///
|
///
|
||||||
/// When called with [`Builder::execute_cli`] (as done by `Build::build`), this function executed twice:
|
/// When called with [`Builder::execute_cli`] (as done by `Build::build`), this function is executed twice:
|
||||||
/// - First in "dry-run" mode to validate certain things (like cyclic Step invocations,
|
/// - First in "dry-run" mode to validate certain things (like cyclic Step invocations,
|
||||||
/// directory creation, etc) super quickly.
|
/// directory creation, etc) super quickly.
|
||||||
/// - Then it's called again to run the actual, very expensive process.
|
/// - Then it's called again to run the actual, very expensive process.
|
||||||
///
|
///
|
||||||
/// When triggered indirectly from other `Step`s, it may still run twice (as dry-run and real mode)
|
/// When triggered indirectly from other `Step`s, it may still run twice (as dry-run and real mode)
|
||||||
/// depending on the `Step::run` implementation of the caller.
|
/// depending on the `Step::run` implementation of the caller.
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit e95ebdfee02514d93f79ec92ae310a804e87f01f
|
Subproject commit 46435cd4eba11b66acaa42c01da5c80ad88aee4b
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6f69823c28ae8d929d6c815181c73d3e99ef16d3
|
Subproject commit 0d7964d5b22cf920237ef1282d869564b4883b88
|
|
@ -182,7 +182,7 @@ fn clean_param_env<'tcx>(
|
||||||
.is_some_and(|pred| tcx.lang_items().sized_trait() == Some(pred.def_id()))
|
.is_some_and(|pred| tcx.lang_items().sized_trait() == Some(pred.def_id()))
|
||||||
})
|
})
|
||||||
.map(|pred| {
|
.map(|pred| {
|
||||||
fold_regions(tcx, pred, |r, _| match *r {
|
fold_regions(tcx, pred, |r, _| match r.kind() {
|
||||||
// FIXME: Don't `unwrap_or`, I think we should panic if we encounter an infer var that
|
// FIXME: Don't `unwrap_or`, I think we should panic if we encounter an infer var that
|
||||||
// we can't map to a concrete region. However, `AutoTraitFinder` *does* leak those kinds
|
// we can't map to a concrete region. However, `AutoTraitFinder` *does* leak those kinds
|
||||||
// of `ReVar`s for some reason at the time of writing. See `rustdoc-ui/` tests.
|
// of `ReVar`s for some reason at the time of writing. See `rustdoc-ui/` tests.
|
||||||
|
@ -362,7 +362,7 @@ fn clean_region_outlives_constraints<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn early_bound_region_name(region: Region<'_>) -> Option<Symbol> {
|
fn early_bound_region_name(region: Region<'_>) -> Option<Symbol> {
|
||||||
match *region {
|
match region.kind() {
|
||||||
ty::ReEarlyParam(r) => Some(r.name),
|
ty::ReEarlyParam(r) => Some(r.name),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,7 +320,7 @@ pub(crate) fn clean_middle_const<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clean_middle_region(region: ty::Region<'_>) -> Option<Lifetime> {
|
pub(crate) fn clean_middle_region(region: ty::Region<'_>) -> Option<Lifetime> {
|
||||||
match *region {
|
match region.kind() {
|
||||||
ty::ReStatic => Some(Lifetime::statik()),
|
ty::ReStatic => Some(Lifetime::statik()),
|
||||||
_ if !region.has_name() => None,
|
_ if !region.has_name() => None,
|
||||||
ty::ReBound(_, ty::BoundRegion { kind: ty::BoundRegionKind::Named(_, name), .. }) => {
|
ty::ReBound(_, ty::BoundRegion { kind: ty::BoundRegionKind::Named(_, name), .. }) => {
|
||||||
|
@ -1941,7 +1941,7 @@ fn clean_trait_object_lifetime_bound<'tcx>(
|
||||||
// Since there is a semantic difference between an implicitly elided (i.e. "defaulted") object
|
// Since there is a semantic difference between an implicitly elided (i.e. "defaulted") object
|
||||||
// lifetime and an explicitly elided object lifetime (`'_`), we intentionally don't hide the
|
// lifetime and an explicitly elided object lifetime (`'_`), we intentionally don't hide the
|
||||||
// latter contrary to `clean_middle_region`.
|
// latter contrary to `clean_middle_region`.
|
||||||
match *region {
|
match region.kind() {
|
||||||
ty::ReStatic => Some(Lifetime::statik()),
|
ty::ReStatic => Some(Lifetime::statik()),
|
||||||
ty::ReEarlyParam(region) => Some(Lifetime(region.name)),
|
ty::ReEarlyParam(region) => Some(Lifetime(region.name)),
|
||||||
ty::ReBound(_, ty::BoundRegion { kind: ty::BoundRegionKind::Named(_, name), .. }) => {
|
ty::ReBound(_, ty::BoundRegion { kind: ty::BoundRegionKind::Named(_, name), .. }) => {
|
||||||
|
@ -1972,7 +1972,7 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
|
||||||
// > If there is a unique bound from the containing type then that is the default
|
// > If there is a unique bound from the containing type then that is the default
|
||||||
// If there is a default object lifetime and the given region is lexically equal to it, elide it.
|
// If there is a default object lifetime and the given region is lexically equal to it, elide it.
|
||||||
match default {
|
match default {
|
||||||
ObjectLifetimeDefault::Static => return *region == ty::ReStatic,
|
ObjectLifetimeDefault::Static => return region.kind() == ty::ReStatic,
|
||||||
// FIXME(fmease): Don't compare lexically but respect de Bruijn indices etc. to handle shadowing correctly.
|
// FIXME(fmease): Don't compare lexically but respect de Bruijn indices etc. to handle shadowing correctly.
|
||||||
ObjectLifetimeDefault::Arg(default) => return region.get_name() == default.get_name(),
|
ObjectLifetimeDefault::Arg(default) => return region.get_name() == default.get_name(),
|
||||||
// > If there is more than one bound from the containing type then an explicit bound must be specified
|
// > If there is more than one bound from the containing type then an explicit bound must be specified
|
||||||
|
@ -1992,7 +1992,7 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
|
||||||
// Note however that at the time of this writing it should be fine to disregard this subtlety
|
// Note however that at the time of this writing it should be fine to disregard this subtlety
|
||||||
// as we neither render const exprs faithfully anyway (hiding them in some places or using `_` instead)
|
// as we neither render const exprs faithfully anyway (hiding them in some places or using `_` instead)
|
||||||
// nor show the contents of fn bodies.
|
// nor show the contents of fn bodies.
|
||||||
[] => *region == ty::ReStatic,
|
[] => region.kind() == ty::ReStatic,
|
||||||
// > If the trait is defined with a single lifetime bound then that bound is used.
|
// > If the trait is defined with a single lifetime bound then that bound is used.
|
||||||
// > If 'static is used for any lifetime bound then 'static is used.
|
// > If 'static is used for any lifetime bound then 'static is used.
|
||||||
// FIXME(fmease): Don't compare lexically but respect de Bruijn indices etc. to handle shadowing correctly.
|
// FIXME(fmease): Don't compare lexically but respect de Bruijn indices etc. to handle shadowing correctly.
|
||||||
|
|
|
@ -3,7 +3,6 @@ use std::fs::File;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::str::FromStr;
|
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
@ -18,30 +17,39 @@ pub enum ErrorKind {
|
||||||
Warning,
|
Warning,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for ErrorKind {
|
impl ErrorKind {
|
||||||
type Err = ();
|
pub fn from_compiler_str(s: &str) -> ErrorKind {
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
match s {
|
||||||
let s = s.to_uppercase();
|
"help" => ErrorKind::Help,
|
||||||
let part0: &str = s.split(':').next().unwrap();
|
"error" | "error: internal compiler error" => ErrorKind::Error,
|
||||||
match part0 {
|
"note" | "failure-note" => ErrorKind::Note,
|
||||||
"HELP" => Ok(ErrorKind::Help),
|
"warning" => ErrorKind::Warning,
|
||||||
"ERROR" => Ok(ErrorKind::Error),
|
_ => panic!("unexpected compiler diagnostic kind `{s}`"),
|
||||||
"NOTE" => Ok(ErrorKind::Note),
|
|
||||||
"SUGGESTION" => Ok(ErrorKind::Suggestion),
|
|
||||||
"WARN" | "WARNING" => Ok(ErrorKind::Warning),
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Either the canonical uppercase string, or some additional versions for compatibility.
|
||||||
|
/// FIXME: consider keeping only the canonical versions here.
|
||||||
|
fn from_user_str(s: &str) -> Option<ErrorKind> {
|
||||||
|
Some(match s {
|
||||||
|
"HELP" | "help" => ErrorKind::Help,
|
||||||
|
"ERROR" | "error" => ErrorKind::Error,
|
||||||
|
"NOTE" | "note" => ErrorKind::Note,
|
||||||
|
"SUGGESTION" => ErrorKind::Suggestion,
|
||||||
|
"WARN" | "WARNING" | "warn" | "warning" => ErrorKind::Warning,
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ErrorKind {
|
impl fmt::Display for ErrorKind {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
ErrorKind::Help => write!(f, "help message"),
|
ErrorKind::Help => write!(f, "HELP"),
|
||||||
ErrorKind::Error => write!(f, "error"),
|
ErrorKind::Error => write!(f, "ERROR"),
|
||||||
ErrorKind::Note => write!(f, "note"),
|
ErrorKind::Note => write!(f, "NOTE"),
|
||||||
ErrorKind::Suggestion => write!(f, "suggestion"),
|
ErrorKind::Suggestion => write!(f, "SUGGESTION"),
|
||||||
ErrorKind::Warning => write!(f, "warning"),
|
ErrorKind::Warning => write!(f, "WARN"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +61,10 @@ pub struct Error {
|
||||||
/// `None` if not specified or unknown message kind.
|
/// `None` if not specified or unknown message kind.
|
||||||
pub kind: Option<ErrorKind>,
|
pub kind: Option<ErrorKind>,
|
||||||
pub msg: String,
|
pub msg: String,
|
||||||
|
/// For some `Error`s, like secondary lines of multi-line diagnostics, line annotations
|
||||||
|
/// are not mandatory, even if they would otherwise be mandatory for primary errors.
|
||||||
|
/// Only makes sense for "actual" errors, not for "expected" errors.
|
||||||
|
pub require_annotation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
@ -60,7 +72,7 @@ impl Error {
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
format!(
|
format!(
|
||||||
"{: <10}line {: >3}: {}",
|
"{: <10}line {: >3}: {}",
|
||||||
self.kind.map(|kind| kind.to_string()).unwrap_or_default().to_uppercase(),
|
self.kind.map(|kind| kind.to_string()).unwrap_or_default(),
|
||||||
self.line_num_str(),
|
self.line_num_str(),
|
||||||
self.msg.cyan(),
|
self.msg.cyan(),
|
||||||
)
|
)
|
||||||
|
@ -150,18 +162,12 @@ fn parse_expected(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the part of the comment after the sigil (e.g. `~^^` or ~|).
|
// Get the part of the comment after the sigil (e.g. `~^^` or ~|).
|
||||||
let whole_match = captures.get(0).unwrap();
|
let tag = captures.get(0).unwrap();
|
||||||
let (_, mut msg) = line.split_at(whole_match.end());
|
let rest = line[tag.end()..].trim_start();
|
||||||
|
let (kind_str, _) = rest.split_once(|c: char| !c.is_ascii_alphabetic()).unwrap_or((rest, ""));
|
||||||
let first_word = msg.split_whitespace().next().expect("Encountered unexpected empty comment");
|
let kind = ErrorKind::from_user_str(kind_str);
|
||||||
|
let untrimmed_msg = if kind.is_some() { &rest[kind_str.len()..] } else { rest };
|
||||||
// If we find `//~ ERROR foo` or something like that, skip the first word.
|
let msg = untrimmed_msg.strip_prefix(':').unwrap_or(untrimmed_msg).trim().to_owned();
|
||||||
let kind = first_word.parse::<ErrorKind>().ok();
|
|
||||||
if kind.is_some() {
|
|
||||||
msg = &msg.trim_start().split_at(first_word.len()).1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let msg = msg.trim().to_owned();
|
|
||||||
|
|
||||||
let line_num_adjust = &captures["adjust"];
|
let line_num_adjust = &captures["adjust"];
|
||||||
let (follow_prev, line_num) = if line_num_adjust == "|" {
|
let (follow_prev, line_num) = if line_num_adjust == "|" {
|
||||||
|
@ -177,12 +183,12 @@ fn parse_expected(
|
||||||
debug!(
|
debug!(
|
||||||
"line={:?} tag={:?} follow_prev={:?} kind={:?} msg={:?}",
|
"line={:?} tag={:?} follow_prev={:?} kind={:?} msg={:?}",
|
||||||
line_num,
|
line_num,
|
||||||
whole_match.as_str(),
|
tag.as_str(),
|
||||||
follow_prev,
|
follow_prev,
|
||||||
kind,
|
kind,
|
||||||
msg
|
msg
|
||||||
);
|
);
|
||||||
Some((follow_prev, Error { line_num, kind, msg }))
|
Some((follow_prev, Error { line_num, kind, msg, require_annotation: true }))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//! These structs are a subset of the ones found in `rustc_errors::json`.
|
//! These structs are a subset of the ones found in `rustc_errors::json`.
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
@ -142,43 +141,34 @@ pub fn extract_rendered(output: &str) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_output(file_name: &str, output: &str, proc_res: &ProcRes) -> Vec<Error> {
|
pub fn parse_output(file_name: &str, output: &str, proc_res: &ProcRes) -> Vec<Error> {
|
||||||
output.lines().flat_map(|line| parse_line(file_name, line, output, proc_res)).collect()
|
let mut errors = Vec::new();
|
||||||
}
|
for line in output.lines() {
|
||||||
|
// The compiler sometimes intermingles non-JSON stuff into the
|
||||||
fn parse_line(file_name: &str, line: &str, output: &str, proc_res: &ProcRes) -> Vec<Error> {
|
// output. This hack just skips over such lines. Yuck.
|
||||||
// The compiler sometimes intermingles non-JSON stuff into the
|
if line.starts_with('{') {
|
||||||
// output. This hack just skips over such lines. Yuck.
|
match serde_json::from_str::<Diagnostic>(line) {
|
||||||
if line.starts_with('{') {
|
Ok(diagnostic) => push_actual_errors(&mut errors, &diagnostic, &[], file_name),
|
||||||
match serde_json::from_str::<Diagnostic>(line) {
|
Err(error) => {
|
||||||
Ok(diagnostic) => {
|
// Ignore the future compat report message - this is handled
|
||||||
let mut expected_errors = vec![];
|
// by `extract_rendered`
|
||||||
push_expected_errors(&mut expected_errors, &diagnostic, &[], file_name);
|
if serde_json::from_str::<FutureIncompatReport>(line).is_err() {
|
||||||
expected_errors
|
proc_res.fatal(
|
||||||
}
|
|
||||||
Err(error) => {
|
|
||||||
// Ignore the future compat report message - this is handled
|
|
||||||
// by `extract_rendered`
|
|
||||||
if serde_json::from_str::<FutureIncompatReport>(line).is_ok() {
|
|
||||||
vec![]
|
|
||||||
} else {
|
|
||||||
proc_res.fatal(
|
|
||||||
Some(&format!(
|
Some(&format!(
|
||||||
"failed to decode compiler output as json: \
|
"failed to decode compiler output as json: `{}`\nline: {}\noutput: {}",
|
||||||
`{}`\nline: {}\noutput: {}",
|
|
||||||
error, line, output
|
error, line, output
|
||||||
)),
|
)),
|
||||||
|| (),
|
|| (),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
}
|
}
|
||||||
|
errors
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_expected_errors(
|
fn push_actual_errors(
|
||||||
expected_errors: &mut Vec<Error>,
|
errors: &mut Vec<Error>,
|
||||||
diagnostic: &Diagnostic,
|
diagnostic: &Diagnostic,
|
||||||
default_spans: &[&DiagnosticSpan],
|
default_spans: &[&DiagnosticSpan],
|
||||||
file_name: &str,
|
file_name: &str,
|
||||||
|
@ -236,44 +226,47 @@ fn push_expected_errors(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convert multi-line messages into multiple expected
|
// Convert multi-line messages into multiple errors.
|
||||||
// errors. We expect to replace these with something
|
// We expect to replace these with something more structured anyhow.
|
||||||
// more structured shortly anyhow.
|
|
||||||
let mut message_lines = diagnostic.message.lines();
|
let mut message_lines = diagnostic.message.lines();
|
||||||
if let Some(first_line) = message_lines.next() {
|
let kind = Some(ErrorKind::from_compiler_str(&diagnostic.level));
|
||||||
let ignore = |s| {
|
let first_line = message_lines.next().unwrap_or(&diagnostic.message);
|
||||||
static RE: OnceLock<Regex> = OnceLock::new();
|
if primary_spans.is_empty() {
|
||||||
RE.get_or_init(|| {
|
static RE: OnceLock<Regex> = OnceLock::new();
|
||||||
Regex::new(r"aborting due to \d+ previous errors?|\d+ warnings? emitted").unwrap()
|
let re_init =
|
||||||
})
|
|| Regex::new(r"aborting due to \d+ previous errors?|\d+ warnings? emitted").unwrap();
|
||||||
.is_match(s)
|
errors.push(Error {
|
||||||
};
|
line_num: None,
|
||||||
|
kind,
|
||||||
if primary_spans.is_empty() && !ignore(first_line) {
|
msg: with_code(None, first_line),
|
||||||
let msg = with_code(None, first_line);
|
require_annotation: diagnostic.level != "failure-note"
|
||||||
let kind = ErrorKind::from_str(&diagnostic.level).ok();
|
&& !RE.get_or_init(re_init).is_match(first_line),
|
||||||
expected_errors.push(Error { line_num: None, kind, msg });
|
});
|
||||||
} else {
|
} else {
|
||||||
for span in primary_spans {
|
for span in primary_spans {
|
||||||
let msg = with_code(Some(span), first_line);
|
errors.push(Error {
|
||||||
let kind = ErrorKind::from_str(&diagnostic.level).ok();
|
line_num: Some(span.line_start),
|
||||||
expected_errors.push(Error { line_num: Some(span.line_start), kind, msg });
|
kind,
|
||||||
}
|
msg: with_code(Some(span), first_line),
|
||||||
|
require_annotation: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for next_line in message_lines {
|
for next_line in message_lines {
|
||||||
if primary_spans.is_empty() {
|
if primary_spans.is_empty() {
|
||||||
expected_errors.push(Error {
|
errors.push(Error {
|
||||||
line_num: None,
|
line_num: None,
|
||||||
kind: None,
|
kind,
|
||||||
msg: with_code(None, next_line),
|
msg: with_code(None, next_line),
|
||||||
|
require_annotation: false,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
for span in primary_spans {
|
for span in primary_spans {
|
||||||
expected_errors.push(Error {
|
errors.push(Error {
|
||||||
line_num: Some(span.line_start),
|
line_num: Some(span.line_start),
|
||||||
kind: None,
|
kind,
|
||||||
msg: with_code(Some(span), next_line),
|
msg: with_code(Some(span), next_line),
|
||||||
|
require_annotation: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,10 +276,11 @@ fn push_expected_errors(
|
||||||
for span in primary_spans {
|
for span in primary_spans {
|
||||||
if let Some(ref suggested_replacement) = span.suggested_replacement {
|
if let Some(ref suggested_replacement) = span.suggested_replacement {
|
||||||
for (index, line) in suggested_replacement.lines().enumerate() {
|
for (index, line) in suggested_replacement.lines().enumerate() {
|
||||||
expected_errors.push(Error {
|
errors.push(Error {
|
||||||
line_num: Some(span.line_start + index),
|
line_num: Some(span.line_start + index),
|
||||||
kind: Some(ErrorKind::Suggestion),
|
kind: Some(ErrorKind::Suggestion),
|
||||||
msg: line.to_string(),
|
msg: line.to_string(),
|
||||||
|
require_annotation: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,39 +289,41 @@ fn push_expected_errors(
|
||||||
// Add notes for the backtrace
|
// Add notes for the backtrace
|
||||||
for span in primary_spans {
|
for span in primary_spans {
|
||||||
if let Some(frame) = &span.expansion {
|
if let Some(frame) = &span.expansion {
|
||||||
push_backtrace(expected_errors, frame, file_name);
|
push_backtrace(errors, frame, file_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add notes for any labels that appear in the message.
|
// Add notes for any labels that appear in the message.
|
||||||
for span in spans_in_this_file.iter().filter(|span| span.label.is_some()) {
|
for span in spans_in_this_file.iter().filter(|span| span.label.is_some()) {
|
||||||
expected_errors.push(Error {
|
errors.push(Error {
|
||||||
line_num: Some(span.line_start),
|
line_num: Some(span.line_start),
|
||||||
kind: Some(ErrorKind::Note),
|
kind: Some(ErrorKind::Note),
|
||||||
msg: span.label.clone().unwrap(),
|
msg: span.label.clone().unwrap(),
|
||||||
|
require_annotation: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flatten out the children.
|
// Flatten out the children.
|
||||||
for child in &diagnostic.children {
|
for child in &diagnostic.children {
|
||||||
push_expected_errors(expected_errors, child, primary_spans, file_name);
|
push_actual_errors(errors, child, primary_spans, file_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_backtrace(
|
fn push_backtrace(
|
||||||
expected_errors: &mut Vec<Error>,
|
errors: &mut Vec<Error>,
|
||||||
expansion: &DiagnosticSpanMacroExpansion,
|
expansion: &DiagnosticSpanMacroExpansion,
|
||||||
file_name: &str,
|
file_name: &str,
|
||||||
) {
|
) {
|
||||||
if Path::new(&expansion.span.file_name) == Path::new(&file_name) {
|
if Path::new(&expansion.span.file_name) == Path::new(&file_name) {
|
||||||
expected_errors.push(Error {
|
errors.push(Error {
|
||||||
line_num: Some(expansion.span.line_start),
|
line_num: Some(expansion.span.line_start),
|
||||||
kind: Some(ErrorKind::Note),
|
kind: Some(ErrorKind::Note),
|
||||||
msg: format!("in this expansion of {}", expansion.macro_decl_name),
|
msg: format!("in this expansion of {}", expansion.macro_decl_name),
|
||||||
|
require_annotation: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(previous_expansion) = &expansion.span.expansion {
|
if let Some(previous_expansion) = &expansion.span.expansion {
|
||||||
push_backtrace(expected_errors, previous_expansion, file_name);
|
push_backtrace(errors, previous_expansion, file_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -810,7 +810,7 @@ impl<'test> TestCx<'test> {
|
||||||
expect_help: bool,
|
expect_help: bool,
|
||||||
expect_note: bool,
|
expect_note: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
!actual_error.msg.is_empty()
|
actual_error.require_annotation
|
||||||
&& match actual_error.kind {
|
&& match actual_error.kind {
|
||||||
Some(ErrorKind::Help) => expect_help,
|
Some(ErrorKind::Help) => expect_help,
|
||||||
Some(ErrorKind::Note) => expect_note,
|
Some(ErrorKind::Note) => expect_note,
|
||||||
|
|
|
@ -15,6 +15,7 @@ pub struct Foo;
|
||||||
|
|
||||||
pub fn consume_foo(_: Foo) {}
|
pub fn consume_foo(_: Foo) {}
|
||||||
//[cfail2]~^ NOTE function defined here
|
//[cfail2]~^ NOTE function defined here
|
||||||
|
//[cfail2]~| NOTE
|
||||||
|
|
||||||
pub fn produce_foo() -> Foo {
|
pub fn produce_foo() -> Foo {
|
||||||
Foo
|
Foo
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
|
fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
|
||||||
//~^ Error future cannot be sent between threads safely
|
//~^ ERROR future cannot be sent between threads safely
|
||||||
async { (ty, ty1) }
|
async { (ty, ty1) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,5 +19,5 @@ async fn wrong_mutex() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
fake_spawn(wrong_mutex()); //~ Error future cannot be sent between threads safely
|
fake_spawn(wrong_mutex()); //~ ERROR future cannot be sent between threads safely
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,18 +5,18 @@ pub struct Example4<const N: usize = 13, const M: usize = 4>;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let e: Example<13> = ();
|
let e: Example<13> = ();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~| expected struct `Example`
|
//~| expected struct `Example`
|
||||||
let e: Example2<u32, 13> = ();
|
let e: Example2<u32, 13> = ();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~| expected struct `Example2`
|
//~| expected struct `Example2`
|
||||||
let e: Example3<13, u32> = ();
|
let e: Example3<13, u32> = ();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~| expected struct `Example3`
|
//~| expected struct `Example3`
|
||||||
let e: Example3<7> = ();
|
let e: Example3<7> = ();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~| expected struct `Example3<7>`
|
//~| expected struct `Example3<7>`
|
||||||
let e: Example4<7> = ();
|
let e: Example4<7> = ();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~| expected struct `Example4<7>`
|
//~| expected struct `Example4<7>`
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ trait Foo {
|
||||||
[Adt; std::mem::size_of::<Self::Assoc>()]: ,
|
[Adt; std::mem::size_of::<Self::Assoc>()]: ,
|
||||||
{
|
{
|
||||||
<[Adt; std::mem::size_of::<Self::Assoc>()] as Foo>::bar()
|
<[Adt; std::mem::size_of::<Self::Assoc>()] as Foo>::bar()
|
||||||
//~^ Error: the trait bound
|
//~^ ERROR the trait bound
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bar() {}
|
fn bar() {}
|
||||||
|
|
|
@ -15,15 +15,15 @@ where
|
||||||
|
|
||||||
// errors are bad but seems to be pre-existing issue #86198
|
// errors are bad but seems to be pre-existing issue #86198
|
||||||
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~^^ Error: unconstrained generic constant
|
//~^^ ERROR unconstrained generic constant
|
||||||
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
|
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~^^ Error: unconstrained generic constant
|
//~^^ ERROR unconstrained generic constant
|
||||||
assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
|
assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
assert_impl::<HasCastInTraitImpl<14, 13>>();
|
assert_impl::<HasCastInTraitImpl<14, 13>>();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
}
|
}
|
||||||
pub fn use_trait_impl_2<const N: usize>()
|
pub fn use_trait_impl_2<const N: usize>()
|
||||||
where
|
where
|
||||||
|
@ -33,15 +33,15 @@ where
|
||||||
|
|
||||||
// errors are bad but seems to be pre-existing issue #86198
|
// errors are bad but seems to be pre-existing issue #86198
|
||||||
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~^^ Error: unconstrained generic constant
|
//~^^ ERROR unconstrained generic constant
|
||||||
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
|
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~^^ Error: unconstrained generic constant
|
//~^^ ERROR unconstrained generic constant
|
||||||
assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
|
assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
assert_impl::<HasCastInTraitImpl<14, 13>>();
|
assert_impl::<HasCastInTraitImpl<14, 13>>();
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -9,8 +9,8 @@ pub trait True {}
|
||||||
|
|
||||||
impl<const LHS: u32, const RHS: u32> True for IsLessOrEqual<LHS, RHS> where
|
impl<const LHS: u32, const RHS: u32> True for IsLessOrEqual<LHS, RHS> where
|
||||||
Condition<{ LHS <= RHS }>: True
|
Condition<{ LHS <= RHS }>: True
|
||||||
//[min]~^ Error generic parameters may not be used in const operations
|
//[min]~^ ERROR generic parameters may not be used in const operations
|
||||||
//[min]~| Error generic parameters may not be used in const operations
|
//[min]~| ERROR generic parameters may not be used in const operations
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
impl True for Condition<true> {}
|
impl True for Condition<true> {}
|
||||||
|
@ -21,8 +21,8 @@ where
|
||||||
IsLessOrEqual<I, 8>: True,
|
IsLessOrEqual<I, 8>: True,
|
||||||
IsLessOrEqual<J, 8>: True,
|
IsLessOrEqual<J, 8>: True,
|
||||||
IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
|
IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
|
||||||
//[min]~^ Error generic parameters may not be used in const operations
|
//[min]~^ ERROR generic parameters may not be used in const operations
|
||||||
//[min]~| Error generic parameters may not be used in const operations
|
//[min]~| ERROR generic parameters may not be used in const operations
|
||||||
// Condition<{ 8 - I <= 8 - J }>: True,
|
// Condition<{ 8 - I <= 8 - J }>: True,
|
||||||
{
|
{
|
||||||
fn print() {
|
fn print() {
|
||||||
|
|
|
@ -14,7 +14,7 @@ trait Foo {
|
||||||
[(); std::mem::size_of::<Self::Assoc>()]: ,
|
[(); std::mem::size_of::<Self::Assoc>()]: ,
|
||||||
{
|
{
|
||||||
Self::AssocInstance == [(); std::mem::size_of::<Self::Assoc>()];
|
Self::AssocInstance == [(); std::mem::size_of::<Self::Assoc>()];
|
||||||
//~^ Error: mismatched types
|
//~^ ERROR mismatched types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@ fn main() {
|
||||||
//~| NOTE constant of non-structural type
|
//~| NOTE constant of non-structural type
|
||||||
|
|
||||||
trait Trait: Sized { const ASSOC: Option<Self>; } //~ NOTE constant defined here
|
trait Trait: Sized { const ASSOC: Option<Self>; } //~ NOTE constant defined here
|
||||||
|
//~^ NOTE
|
||||||
impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
|
impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
|
||||||
match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
|
match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
|
||||||
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
|
|
|
@ -118,14 +118,14 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: constant of non-structural type `NoDerive` in a pattern
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
--> $DIR/reject_non_structural.rs:97:28
|
--> $DIR/reject_non_structural.rs:98:28
|
||||||
|
|
|
|
||||||
LL | struct NoDerive;
|
LL | struct NoDerive;
|
||||||
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
...
|
...
|
||||||
LL | trait Trait: Sized { const ASSOC: Option<Self>; }
|
LL | trait Trait: Sized { const ASSOC: Option<Self>; }
|
||||||
| ------------------ ------------------------- constant defined here
|
| ------------------ ------------------------- constant defined here
|
||||||
LL | impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
|
...
|
||||||
LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
|
LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
|
||||||
| ^^^^^^^^^^^^^^^ constant of non-structural type
|
| ^^^^^^^^^^^^^^^ constant of non-structural type
|
||||||
|
|
|
|
||||||
|
@ -136,7 +136,7 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: constant of non-structural type `NoDerive` in a pattern
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
--> $DIR/reject_non_structural.rs:102:28
|
--> $DIR/reject_non_structural.rs:103:28
|
||||||
|
|
|
|
||||||
LL | struct NoDerive;
|
LL | struct NoDerive;
|
||||||
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
@ -153,7 +153,7 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: constant of non-structural type `NoDerive` in a pattern
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
--> $DIR/reject_non_structural.rs:107:29
|
--> $DIR/reject_non_structural.rs:108:29
|
||||||
|
|
|
|
||||||
LL | struct NoDerive;
|
LL | struct NoDerive;
|
||||||
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn foo(x: i32, y: u32, z: i32);
|
fn foo(x: i32, y: u32, z: i32);
|
||||||
//~^ NOTE function defined here
|
//~^ NOTE function defined here
|
||||||
|
//~| NOTE
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0061]: this function takes 3 arguments but 2 arguments were supplied
|
error[E0061]: this function takes 3 arguments but 2 arguments were supplied
|
||||||
--> $DIR/param-mismatch-foreign.rs:7:5
|
--> $DIR/param-mismatch-foreign.rs:8:5
|
||||||
|
|
|
|
||||||
LL | foo(1i32, 2i32);
|
LL | foo(1i32, 2i32);
|
||||||
| ^^^ ---- argument #2 of type `u32` is missing
|
| ^^^ ---- argument #2 of type `u32` is missing
|
||||||
|
|
|
@ -6,7 +6,7 @@ trait Foo {
|
||||||
|
|
||||||
impl Foo for () {
|
impl Foo for () {
|
||||||
fn foo<U: Debug>(&self, _: &U) { }
|
fn foo<U: Debug>(&self, _: &U) { }
|
||||||
//~^ Error method `foo` has incompatible signature for trait
|
//~^ ERROR method `foo` has incompatible signature for trait
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Bar {
|
trait Bar {
|
||||||
|
@ -15,7 +15,7 @@ trait Bar {
|
||||||
|
|
||||||
impl Bar for () {
|
impl Bar for () {
|
||||||
fn bar(&self, _: &impl Debug) { }
|
fn bar(&self, _: &impl Debug) { }
|
||||||
//~^ Error method `bar` has incompatible signature for trait
|
//~^ ERROR method `bar` has incompatible signature for trait
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Baz {
|
trait Baz {
|
||||||
|
@ -24,7 +24,7 @@ trait Baz {
|
||||||
|
|
||||||
impl Baz for () {
|
impl Baz for () {
|
||||||
fn baz<T: Debug>(&self, _: &impl Debug, _: &T) { }
|
fn baz<T: Debug>(&self, _: &impl Debug, _: &T) { }
|
||||||
//~^ Error method `baz` has incompatible signature for trait
|
//~^ ERROR method `baz` has incompatible signature for trait
|
||||||
}
|
}
|
||||||
|
|
||||||
// With non-local trait (#49841):
|
// With non-local trait (#49841):
|
||||||
|
@ -35,7 +35,7 @@ struct X;
|
||||||
|
|
||||||
impl Hash for X {
|
impl Hash for X {
|
||||||
fn hash(&self, hasher: &mut impl Hasher) {}
|
fn hash(&self, hasher: &mut impl Hasher) {}
|
||||||
//~^ Error method `hash` has incompatible signature for trait
|
//~^ ERROR method `hash` has incompatible signature for trait
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
warning: function cannot return without recursing
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:17:1
|
||||||
|
|
|
||||||
|
LL | fn build<T>(x: T) -> impl Sized {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
|
||||||
|
LL |
|
||||||
|
LL | let (x,) = (build(x),);
|
||||||
|
| -------- recursive call site
|
||||||
|
|
|
||||||
|
= help: a `loop` may express intention better if this is on purpose
|
||||||
|
= note: `#[warn(unconditional_recursion)]` on by default
|
||||||
|
|
||||||
|
warning: function cannot return without recursing
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:27:1
|
||||||
|
|
|
||||||
|
LL | fn build2<T>(x: T) -> impl Sized {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
|
||||||
|
...
|
||||||
|
LL | let (x,) = (build2(x),);
|
||||||
|
| --------- recursive call site
|
||||||
|
|
|
||||||
|
= help: a `loop` may express intention better if this is on purpose
|
||||||
|
|
||||||
|
error[E0720]: cannot resolve opaque type
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:27:23
|
||||||
|
|
|
||||||
|
LL | fn build2<T>(x: T) -> impl Sized {
|
||||||
|
| ^^^^^^^^^^ recursive opaque type
|
||||||
|
...
|
||||||
|
LL | (build2(x),)
|
||||||
|
| ------------ returning here with type `(impl Sized,)`
|
||||||
|
|
||||||
|
warning: function cannot return without recursing
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:40:1
|
||||||
|
|
|
||||||
|
LL | fn build3<T>(x: T) -> impl Sized {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
|
||||||
|
LL |
|
||||||
|
LL | let (x,) = (build3((x,)),);
|
||||||
|
| ------------ recursive call site
|
||||||
|
|
|
||||||
|
= help: a `loop` may express intention better if this is on purpose
|
||||||
|
|
||||||
|
error[E0792]: expected generic type parameter, found `(T,)`
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:49:5
|
||||||
|
|
|
||||||
|
LL | fn build3<T>(x: T) -> impl Sized {
|
||||||
|
| - this generic parameter must be used with a generic type parameter
|
||||||
|
...
|
||||||
|
LL | build3(x)
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors; 3 warnings emitted
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0720, E0792.
|
||||||
|
For more information about an error, try `rustc --explain E0720`.
|
80
tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr
Normal file
80
tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
error[E0284]: type annotations needed: cannot satisfy `impl Sized == _`
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:19:17
|
||||||
|
|
|
||||||
|
LL | let (x,) = (build(x),);
|
||||||
|
| ^^^^^^^^ cannot satisfy `impl Sized == _`
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:31:6
|
||||||
|
|
|
||||||
|
LL | (build2(x),)
|
||||||
|
| ^^^^^^^^^ types differ
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:31:5
|
||||||
|
|
|
||||||
|
LL | (build2(x),)
|
||||||
|
| ^^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:31:5
|
||||||
|
|
|
||||||
|
LL | (build2(x),)
|
||||||
|
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `(impl Sized,)`
|
||||||
|
= note: tuples must have a statically known size to be initialized
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:42:17
|
||||||
|
|
|
||||||
|
LL | let (x,) = (build3((x,)),);
|
||||||
|
| ^^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:42:16
|
||||||
|
|
|
||||||
|
LL | let (x,) = (build3((x,)),);
|
||||||
|
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `(impl Sized,)`
|
||||||
|
= note: tuples must have a statically known size to be initialized
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:42:16
|
||||||
|
|
|
||||||
|
LL | fn build3<T>(x: T) -> impl Sized {
|
||||||
|
| ---------- the found opaque type
|
||||||
|
LL |
|
||||||
|
LL | let (x,) = (build3((x,)),);
|
||||||
|
| ^^^^^^^^^^^^^^^ types differ
|
||||||
|
|
|
||||||
|
= note: expected type `_`
|
||||||
|
found tuple `(impl Sized,)`
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:42:17
|
||||||
|
|
|
||||||
|
LL | let (x,) = (build3((x,)),);
|
||||||
|
| ^^^^^^^^^^^^ types differ
|
||||||
|
|
|
||||||
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:42:16
|
||||||
|
|
|
||||||
|
LL | let (x,) = (build3((x,)),);
|
||||||
|
| ^^^^^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
|
||||||
|
--> $DIR/recursive-in-exhaustiveness.rs:42:17
|
||||||
|
|
|
||||||
|
LL | let (x,) = (build3((x,)),);
|
||||||
|
| ^^^^^^^^^^^^ types differ
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0271, E0277, E0284, E0308.
|
||||||
|
For more information about an error, try `rustc --explain E0271`.
|
53
tests/ui/impl-trait/recursive-in-exhaustiveness.rs
Normal file
53
tests/ui/impl-trait/recursive-in-exhaustiveness.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
// Test several spicy non-trivial recursive opaque definitions inferred from HIR typeck
|
||||||
|
// don't cause stack overflows in exhaustiveness code, which currently reveals opaques
|
||||||
|
// manually in a way that is not overflow aware.
|
||||||
|
//
|
||||||
|
// These should eventually be outright rejected, but today (some) non-trivial recursive
|
||||||
|
// opaque definitions are accepted, and changing that requires an FCP, so for now just
|
||||||
|
// make sure we don't stack overflow :^)
|
||||||
|
|
||||||
|
// Opaque<T> = Opaque<Opaque<T>>
|
||||||
|
//
|
||||||
|
// We unfortunately accept this today, and due to how opaque type relating is implemented
|
||||||
|
// in the NLL type relation, this defines `Opaque<T> = T`.
|
||||||
|
fn build<T>(x: T) -> impl Sized {
|
||||||
|
//[current]~^ WARN function cannot return without recursing
|
||||||
|
let (x,) = (build(x),);
|
||||||
|
//[next]~^ ERROR type annotations needed
|
||||||
|
build(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opaque<T> = (Opaque<T>,)
|
||||||
|
//
|
||||||
|
// Not allowed today. Detected as recursive.
|
||||||
|
fn build2<T>(x: T) -> impl Sized {
|
||||||
|
//[current]~^ ERROR cannot resolve opaque type
|
||||||
|
//[current]~| WARN function cannot return without recursing
|
||||||
|
let (x,) = (build2(x),);
|
||||||
|
(build2(x),)
|
||||||
|
//[next]~^ ERROR type mismatch resolving
|
||||||
|
//[next]~| ERROR type mismatch resolving
|
||||||
|
//[next]~| ERROR the size for values of type
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opaque<T> = Opaque<(T,)>
|
||||||
|
//
|
||||||
|
// Not allowed today. Detected as not defining.
|
||||||
|
fn build3<T>(x: T) -> impl Sized {
|
||||||
|
//[current]~^ WARN function cannot return without recursing
|
||||||
|
let (x,) = (build3((x,)),);
|
||||||
|
//[next]~^ ERROR type mismatch resolving
|
||||||
|
//[next]~| ERROR type mismatch resolving
|
||||||
|
//[next]~| ERROR type mismatch resolving
|
||||||
|
//[next]~| ERROR type mismatch resolving
|
||||||
|
//[next]~| ERROR the size for values of type
|
||||||
|
//[next]~| ERROR mismatched types
|
||||||
|
build3(x)
|
||||||
|
//[current]~^ ERROR expected generic type parameter, found `(T,)`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -3,5 +3,5 @@ struct Foo;
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut a = Foo;
|
let mut a = Foo;
|
||||||
let ref b = Foo;
|
let ref b = Foo;
|
||||||
a += *b; //~ Error: binary assignment operation `+=` cannot be applied to type `Foo`
|
a += *b; //~ ERROR binary assignment operation `+=` cannot be applied to type `Foo`
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,9 @@ struct bool; //~ NOTE the other `bool` is defined in the current crate
|
||||||
struct str; //~ NOTE the other `str` is defined in the current crate
|
struct str; //~ NOTE the other `str` is defined in the current crate
|
||||||
|
|
||||||
fn foo(_: bool) {} //~ NOTE function defined here
|
fn foo(_: bool) {} //~ NOTE function defined here
|
||||||
|
//~^ NOTE
|
||||||
fn bar(_: &str) {} //~ NOTE function defined here
|
fn bar(_: &str) {} //~ NOTE function defined here
|
||||||
|
//~^ NOTE
|
||||||
fn main() {
|
fn main() {
|
||||||
foo(true);
|
foo(true);
|
||||||
//~^ ERROR mismatched types [E0308]
|
//~^ ERROR mismatched types [E0308]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/similar_paths_primitive.rs:10:9
|
--> $DIR/similar_paths_primitive.rs:11:9
|
||||||
|
|
|
|
||||||
LL | foo(true);
|
LL | foo(true);
|
||||||
| --- ^^^^ expected `bool`, found a different `bool`
|
| --- ^^^^ expected `bool`, found a different `bool`
|
||||||
|
@ -20,7 +20,7 @@ LL | fn foo(_: bool) {}
|
||||||
| ^^^ -------
|
| ^^^ -------
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/similar_paths_primitive.rs:16:9
|
--> $DIR/similar_paths_primitive.rs:17:9
|
||||||
|
|
|
|
||||||
LL | bar("hello");
|
LL | bar("hello");
|
||||||
| --- ^^^^^^^ expected `str`, found a different `str`
|
| --- ^^^^^^^ expected `str`, found a different `str`
|
||||||
|
@ -35,7 +35,7 @@ note: the other `str` is defined in the current crate
|
||||||
LL | struct str;
|
LL | struct str;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
note: function defined here
|
note: function defined here
|
||||||
--> $DIR/similar_paths_primitive.rs:7:4
|
--> $DIR/similar_paths_primitive.rs:8:4
|
||||||
|
|
|
|
||||||
LL | fn bar(_: &str) {}
|
LL | fn bar(_: &str) {}
|
||||||
| ^^^ -------
|
| ^^^ -------
|
||||||
|
|
|
@ -102,5 +102,5 @@ fn main() {
|
||||||
();
|
();
|
||||||
();
|
();
|
||||||
();
|
();
|
||||||
dbg!(lib::Dummy); //~ Error: `Dummy` doesn't implement `Debug`
|
dbg!(lib::Dummy); //~ ERROR `Dummy` doesn't implement `Debug`
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ fn foo() {
|
||||||
//~| NOTE inside of this loop
|
//~| NOTE inside of this loop
|
||||||
//~| HELP consider moving the expression out of the loop
|
//~| HELP consider moving the expression out of the loop
|
||||||
//~| NOTE in this expansion of desugaring of `for` loop
|
//~| NOTE in this expansion of desugaring of `for` loop
|
||||||
|
//~| NOTE
|
||||||
|
//~| NOTE
|
||||||
baz.push(foo);
|
baz.push(foo);
|
||||||
//~^ NOTE value moved here
|
//~^ NOTE value moved here
|
||||||
//~| HELP consider cloning the value
|
//~| HELP consider cloning the value
|
||||||
|
@ -30,17 +32,19 @@ fn main() {
|
||||||
for foo in foos {
|
for foo in foos {
|
||||||
//~^ NOTE this reinitialization might get skipped
|
//~^ NOTE this reinitialization might get skipped
|
||||||
//~| NOTE move occurs because `foo` has type `String`
|
//~| NOTE move occurs because `foo` has type `String`
|
||||||
|
//~| NOTE
|
||||||
for bar in &bars {
|
for bar in &bars {
|
||||||
//~^ NOTE inside of this loop
|
//~^ NOTE inside of this loop
|
||||||
//~| HELP consider moving the expression out of the loop
|
//~| HELP consider moving the expression out of the loop
|
||||||
//~| NOTE in this expansion of desugaring of `for` loop
|
//~| NOTE in this expansion of desugaring of `for` loop
|
||||||
|
//~| NOTE
|
||||||
if foo == *bar {
|
if foo == *bar {
|
||||||
baz.push(foo);
|
baz.push(foo);
|
||||||
//~^ NOTE value moved here
|
//~^ NOTE value moved here
|
||||||
//~| HELP consider cloning the value
|
//~| HELP consider cloning the value
|
||||||
continue;
|
continue;
|
||||||
//~^ NOTE verify that your loop breaking logic is correct
|
//~^ NOTE verify that your loop breaking logic is correct
|
||||||
//~| NOTE this `continue` advances the loop at line 33
|
//~| NOTE this `continue` advances the loop at line 36
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qux.push(foo);
|
qux.push(foo);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0382]: use of moved value: `foo`
|
error[E0382]: use of moved value: `foo`
|
||||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:19:14
|
--> $DIR/nested-loop-moved-value-wrong-continue.rs:21:14
|
||||||
|
|
|
|
||||||
LL | for foo in foos { for bar in &bars { if foo == *bar {
|
LL | for foo in foos { for bar in &bars { if foo == *bar {
|
||||||
| --- ---------------- inside of this loop
|
| --- ---------------- inside of this loop
|
||||||
|
@ -14,13 +14,13 @@ LL | qux.push(foo);
|
||||||
| ^^^ value used here after move
|
| ^^^ value used here after move
|
||||||
|
|
|
|
||||||
note: verify that your loop breaking logic is correct
|
note: verify that your loop breaking logic is correct
|
||||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:15:9
|
--> $DIR/nested-loop-moved-value-wrong-continue.rs:17:9
|
||||||
|
|
|
|
||||||
LL | for foo in foos { for bar in &bars { if foo == *bar {
|
LL | for foo in foos { for bar in &bars { if foo == *bar {
|
||||||
| --------------- ----------------
|
| --------------- ----------------
|
||||||
...
|
...
|
||||||
LL | continue;
|
LL | continue;
|
||||||
| ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 18:8
|
| ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 20:8
|
||||||
help: consider moving the expression out of the loop so it is only moved once
|
help: consider moving the expression out of the loop so it is only moved once
|
||||||
|
|
|
|
||||||
LL ~ for foo in foos { let mut value = baz.push(foo);
|
LL ~ for foo in foos { let mut value = baz.push(foo);
|
||||||
|
@ -36,7 +36,7 @@ LL | baz.push(foo.clone());
|
||||||
| ++++++++
|
| ++++++++
|
||||||
|
|
||||||
error[E0382]: use of moved value: `foo`
|
error[E0382]: use of moved value: `foo`
|
||||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:46:18
|
--> $DIR/nested-loop-moved-value-wrong-continue.rs:50:18
|
||||||
|
|
|
|
||||||
LL | for foo in foos {
|
LL | for foo in foos {
|
||||||
| ---
|
| ---
|
||||||
|
@ -54,7 +54,7 @@ LL | qux.push(foo);
|
||||||
| ^^^ value used here after move
|
| ^^^ value used here after move
|
||||||
|
|
|
|
||||||
note: verify that your loop breaking logic is correct
|
note: verify that your loop breaking logic is correct
|
||||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:41:17
|
--> $DIR/nested-loop-moved-value-wrong-continue.rs:45:17
|
||||||
|
|
|
|
||||||
LL | for foo in foos {
|
LL | for foo in foos {
|
||||||
| ---------------
|
| ---------------
|
||||||
|
@ -63,7 +63,7 @@ LL | for bar in &bars {
|
||||||
| ----------------
|
| ----------------
|
||||||
...
|
...
|
||||||
LL | continue;
|
LL | continue;
|
||||||
| ^^^^^^^^ this `continue` advances the loop at line 33
|
| ^^^^^^^^ this `continue` advances the loop at line 36
|
||||||
help: consider moving the expression out of the loop so it is only moved once
|
help: consider moving the expression out of the loop so it is only moved once
|
||||||
|
|
|
|
||||||
LL ~ let mut value = baz.push(foo);
|
LL ~ let mut value = baz.push(foo);
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub fn a() {
|
||||||
|
|
||||||
#[export_name="fail"]
|
#[export_name="fail"]
|
||||||
pub fn b() {
|
pub fn b() {
|
||||||
//~^ Error symbol `fail` is already defined
|
//~^ ERROR symbol `fail` is already defined
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -10,5 +10,6 @@ const async const fn test() {}
|
||||||
//~| ERROR functions cannot be both `const` and `async`
|
//~| ERROR functions cannot be both `const` and `async`
|
||||||
//~| NOTE `const` because of this
|
//~| NOTE `const` because of this
|
||||||
//~| NOTE `async` because of this
|
//~| NOTE `async` because of this
|
||||||
|
//~| NOTE
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -15,5 +15,6 @@ async unsafe const fn test() {}
|
||||||
//~| ERROR functions cannot be both `const` and `async`
|
//~| ERROR functions cannot be both `const` and `async`
|
||||||
//~| NOTE `const` because of this
|
//~| NOTE `const` because of this
|
||||||
//~| NOTE `async` because of this
|
//~| NOTE `async` because of this
|
||||||
|
//~| NOTE
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -6,11 +6,14 @@ extern crate issue_91800_macro;
|
||||||
#[derive(MyTrait)]
|
#[derive(MyTrait)]
|
||||||
//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon
|
//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon
|
||||||
//~| ERROR proc-macro derive produced unparsable tokens
|
//~| ERROR proc-macro derive produced unparsable tokens
|
||||||
|
//~| ERROR
|
||||||
#[attribute_macro]
|
#[attribute_macro]
|
||||||
//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon
|
//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon
|
||||||
|
//~| ERROR
|
||||||
struct MyStruct;
|
struct MyStruct;
|
||||||
|
|
||||||
fn_macro! {}
|
fn_macro! {}
|
||||||
//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon
|
//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon
|
||||||
|
//~| ERROR
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -21,7 +21,7 @@ LL | #[derive(MyTrait)]
|
||||||
= note: this error originates in the derive macro `MyTrait` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `MyTrait` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: macros that expand to items must be delimited with braces or followed by a semicolon
|
error: macros that expand to items must be delimited with braces or followed by a semicolon
|
||||||
--> $DIR/issue-91800.rs:9:1
|
--> $DIR/issue-91800.rs:10:1
|
||||||
|
|
|
|
||||||
LL | #[attribute_macro]
|
LL | #[attribute_macro]
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -29,7 +29,7 @@ LL | #[attribute_macro]
|
||||||
= note: this error originates in the attribute macro `attribute_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the attribute macro `attribute_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
--> $DIR/issue-91800.rs:9:1
|
--> $DIR/issue-91800.rs:10:1
|
||||||
|
|
|
|
||||||
LL | #[attribute_macro]
|
LL | #[attribute_macro]
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -37,7 +37,7 @@ LL | #[attribute_macro]
|
||||||
= note: this error originates in the attribute macro `attribute_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the attribute macro `attribute_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: macros that expand to items must be delimited with braces or followed by a semicolon
|
error: macros that expand to items must be delimited with braces or followed by a semicolon
|
||||||
--> $DIR/issue-91800.rs:13:1
|
--> $DIR/issue-91800.rs:15:1
|
||||||
|
|
|
|
||||||
LL | fn_macro! {}
|
LL | fn_macro! {}
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
@ -45,7 +45,7 @@ LL | fn_macro! {}
|
||||||
= note: this error originates in the macro `fn_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `fn_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
--> $DIR/issue-91800.rs:13:1
|
--> $DIR/issue-91800.rs:15:1
|
||||||
|
|
|
|
||||||
LL | fn_macro! {}
|
LL | fn_macro! {}
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
@ -4,15 +4,15 @@ struct A {
|
||||||
|
|
||||||
impl A {
|
impl A {
|
||||||
fn new(cofig: String) -> Self {
|
fn new(cofig: String) -> Self {
|
||||||
Self { config } //~ Error cannot find value `config` in this scope
|
Self { config } //~ ERROR cannot find value `config` in this scope
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_something(cofig: String) {
|
fn do_something(cofig: String) {
|
||||||
println!("{config}"); //~ Error cannot find value `config` in this scope
|
println!("{config}"); //~ ERROR cannot find value `config` in this scope
|
||||||
}
|
}
|
||||||
|
|
||||||
fn self_is_available(self, cofig: String) {
|
fn self_is_available(self, cofig: String) {
|
||||||
println!("{config}"); //~ Error cannot find value `config` in this scope
|
println!("{config}"); //~ ERROR cannot find value `config` in this scope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ trait Cat {
|
||||||
fn uwu<T: Cat>(c: T) {
|
fn uwu<T: Cat>(c: T) {
|
||||||
c.nya();
|
c.nya();
|
||||||
//~^ ERROR no method named `nya` found for type parameter `T` in the current scope
|
//~^ ERROR no method named `nya` found for type parameter `T` in the current scope
|
||||||
//~| Suggestion T::nya()
|
//~| SUGGESTION T::nya()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -17,7 +17,7 @@ impl Foo for S2 {
|
||||||
type Item = impl Debug;
|
type Item = impl Debug;
|
||||||
|
|
||||||
fn foo<T: Debug>(_: T) -> Self::Item {
|
fn foo<T: Debug>(_: T) -> Self::Item {
|
||||||
//~^ Error type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
//~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||||
S::<T>(Default::default())
|
S::<T>(Default::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue