Rollup merge of #69189 - matthewjasper:erase-the-world, r=nikomatsakis
Erase regions in writeback Regions in `TypeckTables` (except canonicalized user annotations) are now erased. Further, we no longer do lexical region solving on item bodies with `-Zborrowck=mir`. cc #68261 r? @nikomatsakis
This commit is contained in:
commit
3f583fc270
@ -23,7 +23,6 @@ use crate::mir::{
|
|||||||
};
|
};
|
||||||
use crate::traits;
|
use crate::traits;
|
||||||
use crate::traits::{Clause, Clauses, Goal, GoalKind, Goals};
|
use crate::traits::{Clause, Clauses, Goal, GoalKind, Goals};
|
||||||
use crate::ty::free_region_map::FreeRegionMap;
|
|
||||||
use crate::ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx};
|
use crate::ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx};
|
||||||
use crate::ty::query;
|
use crate::ty::query;
|
||||||
use crate::ty::steal::Steal;
|
use crate::ty::steal::Steal;
|
||||||
@ -416,11 +415,6 @@ pub struct TypeckTables<'tcx> {
|
|||||||
/// this field will be set to `true`.
|
/// this field will be set to `true`.
|
||||||
pub tainted_by_errors: bool,
|
pub tainted_by_errors: bool,
|
||||||
|
|
||||||
/// Stores the free-region relationships that were deduced from
|
|
||||||
/// its where-clauses and parameter types. These are then
|
|
||||||
/// read-again by borrowck.
|
|
||||||
pub free_region_map: FreeRegionMap<'tcx>,
|
|
||||||
|
|
||||||
/// All the opaque types that are restricted to concrete types
|
/// All the opaque types that are restricted to concrete types
|
||||||
/// by this function.
|
/// by this function.
|
||||||
pub concrete_opaque_types: FxHashMap<DefId, ResolvedOpaqueTy<'tcx>>,
|
pub concrete_opaque_types: FxHashMap<DefId, ResolvedOpaqueTy<'tcx>>,
|
||||||
@ -456,7 +450,6 @@ impl<'tcx> TypeckTables<'tcx> {
|
|||||||
coercion_casts: Default::default(),
|
coercion_casts: Default::default(),
|
||||||
used_trait_imports: Lrc::new(Default::default()),
|
used_trait_imports: Lrc::new(Default::default()),
|
||||||
tainted_by_errors: false,
|
tainted_by_errors: false,
|
||||||
free_region_map: Default::default(),
|
|
||||||
concrete_opaque_types: Default::default(),
|
concrete_opaque_types: Default::default(),
|
||||||
upvar_list: Default::default(),
|
upvar_list: Default::default(),
|
||||||
generator_interior_types: Default::default(),
|
generator_interior_types: Default::default(),
|
||||||
@ -719,7 +712,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
|
|||||||
|
|
||||||
ref used_trait_imports,
|
ref used_trait_imports,
|
||||||
tainted_by_errors,
|
tainted_by_errors,
|
||||||
ref free_region_map,
|
|
||||||
ref concrete_opaque_types,
|
ref concrete_opaque_types,
|
||||||
ref upvar_list,
|
ref upvar_list,
|
||||||
ref generator_interior_types,
|
ref generator_interior_types,
|
||||||
@ -757,7 +749,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
|
|||||||
coercion_casts.hash_stable(hcx, hasher);
|
coercion_casts.hash_stable(hcx, hasher);
|
||||||
used_trait_imports.hash_stable(hcx, hasher);
|
used_trait_imports.hash_stable(hcx, hasher);
|
||||||
tainted_by_errors.hash_stable(hcx, hasher);
|
tainted_by_errors.hash_stable(hcx, hasher);
|
||||||
free_region_map.hash_stable(hcx, hasher);
|
|
||||||
concrete_opaque_types.hash_stable(hcx, hasher);
|
concrete_opaque_types.hash_stable(hcx, hasher);
|
||||||
upvar_list.hash_stable(hcx, hasher);
|
upvar_list.hash_stable(hcx, hasher);
|
||||||
generator_interior_types.hash_stable(hcx, hasher);
|
generator_interior_types.hash_stable(hcx, hasher);
|
||||||
|
@ -49,7 +49,7 @@ use super::lexical_region_resolve::RegionResolutionError;
|
|||||||
use super::region_constraints::GenericKind;
|
use super::region_constraints::GenericKind;
|
||||||
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
|
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
|
||||||
|
|
||||||
use crate::infer::{self, SuppressRegionErrors};
|
use crate::infer;
|
||||||
use crate::traits::error_reporting::report_object_safety_error;
|
use crate::traits::error_reporting::report_object_safety_error;
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
|
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
|
||||||
@ -372,17 +372,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
region_scope_tree: ®ion::ScopeTree,
|
region_scope_tree: ®ion::ScopeTree,
|
||||||
errors: &Vec<RegionResolutionError<'tcx>>,
|
errors: &Vec<RegionResolutionError<'tcx>>,
|
||||||
suppress: SuppressRegionErrors,
|
|
||||||
) {
|
) {
|
||||||
debug!(
|
debug!("report_region_errors(): {} errors to start", errors.len());
|
||||||
"report_region_errors(): {} errors to start, suppress = {:?}",
|
|
||||||
errors.len(),
|
|
||||||
suppress
|
|
||||||
);
|
|
||||||
|
|
||||||
if suppress.suppressed() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to pre-process the errors, which will group some of them
|
// try to pre-process the errors, which will group some of them
|
||||||
// together into a `ProcessedErrors` group:
|
// together into a `ProcessedErrors` group:
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
|
use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
|
||||||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||||
|
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
||||||
|
use crate::infer::SubregionOrigin;
|
||||||
use rustc::util::common::ErrorReported;
|
use rustc::util::common::ErrorReported;
|
||||||
|
|
||||||
use rustc_errors::struct_span_err;
|
use rustc_errors::struct_span_err;
|
||||||
@ -47,6 +49,15 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||||||
pub(super) fn try_report_anon_anon_conflict(&self) -> Option<ErrorReported> {
|
pub(super) fn try_report_anon_anon_conflict(&self) -> Option<ErrorReported> {
|
||||||
let (span, sub, sup) = self.regions()?;
|
let (span, sub, sup) = self.regions()?;
|
||||||
|
|
||||||
|
if let Some(RegionResolutionError::ConcreteFailure(
|
||||||
|
SubregionOrigin::ReferenceOutlivesReferent(..),
|
||||||
|
..,
|
||||||
|
)) = self.error
|
||||||
|
{
|
||||||
|
// This error doesn't make much sense in this case.
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine whether the sub and sup consist of both anonymous (elided) regions.
|
// Determine whether the sub and sup consist of both anonymous (elided) regions.
|
||||||
let anon_reg_sup = self.tcx().is_suitable_region(sup)?;
|
let anon_reg_sup = self.tcx().is_suitable_region(sup)?;
|
||||||
|
|
||||||
|
@ -17,12 +17,7 @@ mod util;
|
|||||||
|
|
||||||
impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
|
impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
|
||||||
pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool {
|
pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool {
|
||||||
if let Some(tables) = self.in_progress_tables {
|
NiceRegionError::new(self, error.clone()).try_report().is_some()
|
||||||
let tables = tables.borrow();
|
|
||||||
NiceRegionError::new(self, error.clone(), Some(&tables)).try_report().is_some()
|
|
||||||
} else {
|
|
||||||
NiceRegionError::new(self, error.clone(), None).try_report().is_some()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,16 +25,11 @@ pub struct NiceRegionError<'cx, 'tcx> {
|
|||||||
infcx: &'cx InferCtxt<'cx, 'tcx>,
|
infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||||
error: Option<RegionResolutionError<'tcx>>,
|
error: Option<RegionResolutionError<'tcx>>,
|
||||||
regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>,
|
regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>,
|
||||||
tables: Option<&'cx ty::TypeckTables<'tcx>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
|
impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
|
||||||
pub fn new(
|
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>, error: RegionResolutionError<'tcx>) -> Self {
|
||||||
infcx: &'cx InferCtxt<'cx, 'tcx>,
|
Self { infcx, error: Some(error), regions: None }
|
||||||
error: RegionResolutionError<'tcx>,
|
|
||||||
tables: Option<&'cx ty::TypeckTables<'tcx>>,
|
|
||||||
) -> Self {
|
|
||||||
Self { infcx, error: Some(error), regions: None, tables }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_span(
|
pub fn new_from_span(
|
||||||
@ -47,9 +37,8 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
sub: ty::Region<'tcx>,
|
sub: ty::Region<'tcx>,
|
||||||
sup: ty::Region<'tcx>,
|
sup: ty::Region<'tcx>,
|
||||||
tables: Option<&'cx ty::TypeckTables<'tcx>>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { infcx, error: None, regions: Some((span, sub, sup)), tables }
|
Self { infcx, error: None, regions: Some((span, sub, sup)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
|
@ -51,52 +51,44 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let hir = &self.tcx().hir();
|
let hir = &self.tcx().hir();
|
||||||
if let Some(hir_id) = hir.as_local_hir_id(id) {
|
let hir_id = hir.as_local_hir_id(id)?;
|
||||||
if let Some(body_id) = hir.maybe_body_owned_by(hir_id) {
|
let body_id = hir.maybe_body_owned_by(hir_id)?;
|
||||||
let body = hir.body(body_id);
|
let body = hir.body(body_id);
|
||||||
let owner_id = hir.body_owner(body_id);
|
let owner_id = hir.body_owner(body_id);
|
||||||
let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap();
|
let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap();
|
||||||
if let Some(tables) = self.tables {
|
let poly_fn_sig = self.tcx().fn_sig(id);
|
||||||
body.params
|
let fn_sig = self.tcx().liberate_late_bound_regions(id, &poly_fn_sig);
|
||||||
.iter()
|
body.params
|
||||||
.enumerate()
|
.iter()
|
||||||
.filter_map(|(index, param)| {
|
.enumerate()
|
||||||
// May return None; sometimes the tables are not yet populated.
|
.filter_map(|(index, param)| {
|
||||||
let ty_hir_id = fn_decl.inputs[index].hir_id;
|
// May return None; sometimes the tables are not yet populated.
|
||||||
let param_ty_span = hir.span(ty_hir_id);
|
let ty = fn_sig.inputs()[index];
|
||||||
let ty = tables.node_type_opt(param.hir_id)?;
|
let mut found_anon_region = false;
|
||||||
let mut found_anon_region = false;
|
let new_param_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| {
|
||||||
let new_param_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| {
|
if *r == *anon_region {
|
||||||
if *r == *anon_region {
|
found_anon_region = true;
|
||||||
found_anon_region = true;
|
replace_region
|
||||||
replace_region
|
} else {
|
||||||
} else {
|
r
|
||||||
r
|
}
|
||||||
}
|
});
|
||||||
});
|
if found_anon_region {
|
||||||
if found_anon_region {
|
let ty_hir_id = fn_decl.inputs[index].hir_id;
|
||||||
let is_first = index == 0;
|
let param_ty_span = hir.span(ty_hir_id);
|
||||||
Some(AnonymousParamInfo {
|
let is_first = index == 0;
|
||||||
param,
|
Some(AnonymousParamInfo {
|
||||||
param_ty: new_param_ty,
|
param,
|
||||||
param_ty_span,
|
param_ty: new_param_ty,
|
||||||
bound_region,
|
param_ty_span,
|
||||||
is_first,
|
bound_region,
|
||||||
})
|
is_first,
|
||||||
} else {
|
})
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.next()
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
} else {
|
})
|
||||||
None
|
.next()
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here, we check for the case where the anonymous region
|
// Here, we check for the case where the anonymous region
|
||||||
|
@ -7,6 +7,7 @@ use crate::infer::region_constraints::RegionConstraintData;
|
|||||||
use crate::infer::region_constraints::VarInfos;
|
use crate::infer::region_constraints::VarInfos;
|
||||||
use crate::infer::region_constraints::VerifyBound;
|
use crate::infer::region_constraints::VerifyBound;
|
||||||
use crate::infer::RegionVariableOrigin;
|
use crate::infer::RegionVariableOrigin;
|
||||||
|
use crate::infer::RegionckMode;
|
||||||
use crate::infer::SubregionOrigin;
|
use crate::infer::SubregionOrigin;
|
||||||
use rustc::middle::free_region::RegionRelations;
|
use rustc::middle::free_region::RegionRelations;
|
||||||
use rustc::ty::fold::TypeFoldable;
|
use rustc::ty::fold::TypeFoldable;
|
||||||
@ -33,12 +34,29 @@ pub fn resolve<'tcx>(
|
|||||||
region_rels: &RegionRelations<'_, 'tcx>,
|
region_rels: &RegionRelations<'_, 'tcx>,
|
||||||
var_infos: VarInfos,
|
var_infos: VarInfos,
|
||||||
data: RegionConstraintData<'tcx>,
|
data: RegionConstraintData<'tcx>,
|
||||||
|
mode: RegionckMode,
|
||||||
) -> (LexicalRegionResolutions<'tcx>, Vec<RegionResolutionError<'tcx>>) {
|
) -> (LexicalRegionResolutions<'tcx>, Vec<RegionResolutionError<'tcx>>) {
|
||||||
debug!("RegionConstraintData: resolve_regions()");
|
debug!("RegionConstraintData: resolve_regions()");
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
let mut resolver = LexicalResolver { region_rels, var_infos, data };
|
let mut resolver = LexicalResolver { region_rels, var_infos, data };
|
||||||
let values = resolver.infer_variable_values(&mut errors);
|
match mode {
|
||||||
(values, errors)
|
RegionckMode::Solve => {
|
||||||
|
let values = resolver.infer_variable_values(&mut errors);
|
||||||
|
(values, errors)
|
||||||
|
}
|
||||||
|
RegionckMode::Erase { suppress_errors: false } => {
|
||||||
|
// Do real inference to get errors, then erase the results.
|
||||||
|
let mut values = resolver.infer_variable_values(&mut errors);
|
||||||
|
let re_erased = region_rels.tcx.lifetimes.re_erased;
|
||||||
|
|
||||||
|
values.values.iter_mut().for_each(|v| *v = VarValue::Value(re_erased));
|
||||||
|
(values, errors)
|
||||||
|
}
|
||||||
|
RegionckMode::Erase { suppress_errors: true } => {
|
||||||
|
// Skip region inference entirely.
|
||||||
|
(resolver.erased_data(region_rels.tcx), Vec::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contains the result of lexical region resolution. Offers methods
|
/// Contains the result of lexical region resolution. Offers methods
|
||||||
@ -163,6 +181,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An erased version of the lexical region resolutions. Used when we're
|
||||||
|
/// erasing regions and suppressing errors: in item bodies with
|
||||||
|
/// `-Zborrowck=mir`.
|
||||||
|
fn erased_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> {
|
||||||
|
LexicalRegionResolutions {
|
||||||
|
error_region: tcx.lifetimes.re_static,
|
||||||
|
values: IndexVec::from_elem_n(
|
||||||
|
VarValue::Value(tcx.lifetimes.re_erased),
|
||||||
|
self.num_vars(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn dump_constraints(&self, free_regions: &RegionRelations<'_, 'tcx>) {
|
fn dump_constraints(&self, free_regions: &RegionRelations<'_, 'tcx>) {
|
||||||
debug!("----() Start constraint listing (context={:?}) ()----", free_regions.context);
|
debug!("----() Start constraint listing (context={:?}) ()----", free_regions.context);
|
||||||
for (idx, (constraint, _)) in self.data.constraints.iter().enumerate() {
|
for (idx, (constraint, _)) in self.data.constraints.iter().enumerate() {
|
||||||
|
@ -79,31 +79,50 @@ pub type Bound<T> = Option<T>;
|
|||||||
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
|
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
|
||||||
pub type FixupResult<'tcx, T> = Result<T, FixupError<'tcx>>; // "fixup result"
|
pub type FixupResult<'tcx, T> = Result<T, FixupError<'tcx>>; // "fixup result"
|
||||||
|
|
||||||
/// A flag that is used to suppress region errors. This is normally
|
/// How we should handle region solving.
|
||||||
/// false, but sometimes -- when we are doing region checks that the
|
///
|
||||||
/// NLL borrow checker will also do -- it might be set to true.
|
/// This is used so that the region values inferred by HIR region solving are
|
||||||
#[derive(Copy, Clone, Default, Debug)]
|
/// not exposed, and so that we can avoid doing work in HIR typeck that MIR
|
||||||
pub struct SuppressRegionErrors {
|
/// typeck will also do.
|
||||||
suppressed: bool,
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub enum RegionckMode {
|
||||||
|
/// The default mode: report region errors, don't erase regions.
|
||||||
|
Solve,
|
||||||
|
/// Erase the results of region after solving.
|
||||||
|
Erase {
|
||||||
|
/// A flag that is used to suppress region errors, when we are doing
|
||||||
|
/// region checks that the NLL borrow checker will also do -- it might
|
||||||
|
/// be set to true.
|
||||||
|
suppress_errors: bool,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SuppressRegionErrors {
|
impl Default for RegionckMode {
|
||||||
|
fn default() -> Self {
|
||||||
|
RegionckMode::Solve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegionckMode {
|
||||||
pub fn suppressed(self) -> bool {
|
pub fn suppressed(self) -> bool {
|
||||||
self.suppressed
|
match self {
|
||||||
|
Self::Solve => false,
|
||||||
|
Self::Erase { suppress_errors } => suppress_errors,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates that the MIR borrowck will repeat these region
|
/// Indicates that the MIR borrowck will repeat these region
|
||||||
/// checks, so we should ignore errors if NLL is (unconditionally)
|
/// checks, so we should ignore errors if NLL is (unconditionally)
|
||||||
/// enabled.
|
/// enabled.
|
||||||
pub fn when_nll_is_enabled(tcx: TyCtxt<'_>) -> Self {
|
pub fn for_item_body(tcx: TyCtxt<'_>) -> Self {
|
||||||
// FIXME(Centril): Once we actually remove `::Migrate` also make
|
// FIXME(Centril): Once we actually remove `::Migrate` also make
|
||||||
// this always `true` and then proceed to eliminate the dead code.
|
// this always `true` and then proceed to eliminate the dead code.
|
||||||
match tcx.borrowck_mode() {
|
match tcx.borrowck_mode() {
|
||||||
// If we're on Migrate mode, report AST region errors
|
// If we're on Migrate mode, report AST region errors
|
||||||
BorrowckMode::Migrate => SuppressRegionErrors { suppressed: false },
|
BorrowckMode::Migrate => RegionckMode::Erase { suppress_errors: false },
|
||||||
|
|
||||||
// If we're on MIR, don't report AST region errors as they should be reported by NLL
|
// If we're on MIR, don't report AST region errors as they should be reported by NLL
|
||||||
BorrowckMode::Mir => SuppressRegionErrors { suppressed: true },
|
BorrowckMode::Mir => RegionckMode::Erase { suppress_errors: true },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1207,20 +1226,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
region_context: DefId,
|
region_context: DefId,
|
||||||
region_map: ®ion::ScopeTree,
|
region_map: ®ion::ScopeTree,
|
||||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||||
suppress: SuppressRegionErrors,
|
mode: RegionckMode,
|
||||||
) {
|
) {
|
||||||
assert!(
|
assert!(
|
||||||
self.is_tainted_by_errors() || self.inner.borrow().region_obligations.is_empty(),
|
self.is_tainted_by_errors() || self.inner.borrow().region_obligations.is_empty(),
|
||||||
"region_obligations not empty: {:#?}",
|
"region_obligations not empty: {:#?}",
|
||||||
self.inner.borrow().region_obligations
|
self.inner.borrow().region_obligations
|
||||||
);
|
);
|
||||||
|
|
||||||
let region_rels = &RegionRelations::new(
|
|
||||||
self.tcx,
|
|
||||||
region_context,
|
|
||||||
region_map,
|
|
||||||
outlives_env.free_region_map(),
|
|
||||||
);
|
|
||||||
let (var_infos, data) = self
|
let (var_infos, data) = self
|
||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
@ -1228,8 +1240,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
.take()
|
.take()
|
||||||
.expect("regions already resolved")
|
.expect("regions already resolved")
|
||||||
.into_infos_and_data();
|
.into_infos_and_data();
|
||||||
|
|
||||||
|
let region_rels = &RegionRelations::new(
|
||||||
|
self.tcx,
|
||||||
|
region_context,
|
||||||
|
region_map,
|
||||||
|
outlives_env.free_region_map(),
|
||||||
|
);
|
||||||
|
|
||||||
let (lexical_region_resolutions, errors) =
|
let (lexical_region_resolutions, errors) =
|
||||||
lexical_region_resolve::resolve(region_rels, var_infos, data);
|
lexical_region_resolve::resolve(region_rels, var_infos, data, mode);
|
||||||
|
|
||||||
let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
|
let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
|
||||||
assert!(old_value.is_none());
|
assert!(old_value.is_none());
|
||||||
@ -1240,7 +1260,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
// this infcx was in use. This is totally hokey but
|
// this infcx was in use. This is totally hokey but
|
||||||
// otherwise we have a hard time separating legit region
|
// otherwise we have a hard time separating legit region
|
||||||
// errors from silly ones.
|
// errors from silly ones.
|
||||||
self.report_region_errors(region_map, &errors, suppress);
|
self.report_region_errors(region_map, &errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,8 +284,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||||||
debug!("report_region_error: category={:?} {:?}", category, span);
|
debug!("report_region_error: category={:?} {:?}", category, span);
|
||||||
// Check if we can use one of the "nice region errors".
|
// Check if we can use one of the "nice region errors".
|
||||||
if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
|
if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
|
||||||
let tables = self.infcx.tcx.typeck_tables_of(self.mir_def_id);
|
let nice = NiceRegionError::new_from_span(self.infcx, span, o, f);
|
||||||
let nice = NiceRegionError::new_from_span(self.infcx, span, o, f, Some(tables));
|
|
||||||
if let Some(diag) = nice.try_report_from_nll() {
|
if let Some(diag) = nice.try_report_from_nll() {
|
||||||
diag.buffer(&mut self.errors_buffer);
|
diag.buffer(&mut self.errors_buffer);
|
||||||
return;
|
return;
|
||||||
|
@ -21,7 +21,7 @@ mod util;
|
|||||||
pub mod wf;
|
pub mod wf;
|
||||||
|
|
||||||
use crate::infer::outlives::env::OutlivesEnvironment;
|
use crate::infer::outlives::env::OutlivesEnvironment;
|
||||||
use crate::infer::{InferCtxt, SuppressRegionErrors, TyCtxtInferExt};
|
use crate::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
|
||||||
use crate::traits::error_reporting::InferCtxtExt as _;
|
use crate::traits::error_reporting::InferCtxtExt as _;
|
||||||
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||||
use rustc::middle::region;
|
use rustc::middle::region;
|
||||||
@ -244,7 +244,7 @@ fn do_normalize_predicates<'tcx>(
|
|||||||
region_context,
|
region_context,
|
||||||
®ion_scope_tree,
|
®ion_scope_tree,
|
||||||
&outlives_env,
|
&outlives_env,
|
||||||
SuppressRegionErrors::default(),
|
RegionckMode::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let predicates = match infcx.fully_resolve(&predicates) {
|
let predicates = match infcx.fully_resolve(&predicates) {
|
||||||
|
@ -9,7 +9,7 @@ use rustc::ty::subst::{Subst, SubstsRef};
|
|||||||
use rustc::ty::{self, Predicate, Ty, TyCtxt};
|
use rustc::ty::{self, Predicate, Ty, TyCtxt};
|
||||||
use rustc_errors::struct_span_err;
|
use rustc_errors::struct_span_err;
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{InferOk, SuppressRegionErrors, TyCtxtInferExt};
|
use rustc_infer::infer::{InferOk, RegionckMode, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::TraitEngineExt as _;
|
use rustc_infer::traits::TraitEngineExt as _;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
||||||
@ -139,7 +139,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
|
|||||||
drop_impl_did,
|
drop_impl_did,
|
||||||
®ion_scope_tree,
|
®ion_scope_tree,
|
||||||
&outlives_env,
|
&outlives_env,
|
||||||
SuppressRegionErrors::default(),
|
RegionckMode::default(),
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -85,7 +85,7 @@ use rustc_hir::def_id::DefId;
|
|||||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
use rustc_hir::PatKind;
|
use rustc_hir::PatKind;
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{self, RegionObligation, SuppressRegionErrors};
|
use rustc_infer::infer::{self, RegionObligation, RegionckMode};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::infer::OutlivesEnvironmentExt;
|
use rustc_trait_selection::infer::OutlivesEnvironmentExt;
|
||||||
use rustc_trait_selection::opaque_types::InferCtxtExt;
|
use rustc_trait_selection::opaque_types::InferCtxtExt;
|
||||||
@ -124,10 +124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
rcx.visit_body(body);
|
rcx.visit_body(body);
|
||||||
rcx.visit_region_obligations(id);
|
rcx.visit_region_obligations(id);
|
||||||
}
|
}
|
||||||
rcx.resolve_regions_and_report_errors(SuppressRegionErrors::when_nll_is_enabled(self.tcx));
|
rcx.resolve_regions_and_report_errors(RegionckMode::for_item_body(self.tcx));
|
||||||
|
|
||||||
assert!(self.tables.borrow().free_region_map.is_empty());
|
|
||||||
self.tables.borrow_mut().free_region_map = rcx.outlives_environment.into_free_region_map();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Region checking during the WF phase for items. `wf_tys` are the
|
/// Region checking during the WF phase for items. `wf_tys` are the
|
||||||
@ -145,7 +142,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
rcx.outlives_environment.add_implied_bounds(self, wf_tys, item_id, span);
|
rcx.outlives_environment.add_implied_bounds(self, wf_tys, item_id, span);
|
||||||
rcx.outlives_environment.save_implied_bounds(item_id);
|
rcx.outlives_environment.save_implied_bounds(item_id);
|
||||||
rcx.visit_region_obligations(item_id);
|
rcx.visit_region_obligations(item_id);
|
||||||
rcx.resolve_regions_and_report_errors(SuppressRegionErrors::default());
|
rcx.resolve_regions_and_report_errors(RegionckMode::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Region check a function body. Not invoked on closures, but
|
/// Region check a function body. Not invoked on closures, but
|
||||||
@ -168,13 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
rcx.visit_fn_body(fn_id, body, self.tcx.hir().span(fn_id));
|
rcx.visit_fn_body(fn_id, body, self.tcx.hir().span(fn_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
rcx.resolve_regions_and_report_errors(SuppressRegionErrors::when_nll_is_enabled(self.tcx));
|
rcx.resolve_regions_and_report_errors(RegionckMode::for_item_body(self.tcx));
|
||||||
|
|
||||||
// In this mode, we also copy the free-region-map into the
|
|
||||||
// tables of the enclosing fcx. In the other regionck modes
|
|
||||||
// (e.g., `regionck_item`), we don't have an enclosing tables.
|
|
||||||
assert!(self.tables.borrow().free_region_map.is_empty());
|
|
||||||
self.tables.borrow_mut().free_region_map = rcx.outlives_environment.into_free_region_map();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +346,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
|
|||||||
self.select_all_obligations_or_error();
|
self.select_all_obligations_or_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_regions_and_report_errors(&self, suppress: SuppressRegionErrors) {
|
fn resolve_regions_and_report_errors(&self, mode: RegionckMode) {
|
||||||
self.infcx.process_registered_region_obligations(
|
self.infcx.process_registered_region_obligations(
|
||||||
self.outlives_environment.region_bound_pairs_map(),
|
self.outlives_environment.region_bound_pairs_map(),
|
||||||
self.implicit_region_bound,
|
self.implicit_region_bound,
|
||||||
@ -366,7 +357,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
|
|||||||
self.subject_def_id,
|
self.subject_def_id,
|
||||||
&self.region_scope_tree,
|
&self.region_scope_tree,
|
||||||
&self.outlives_environment,
|
&self.outlives_environment,
|
||||||
suppress,
|
mode,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
wbcx.visit_fru_field_types();
|
wbcx.visit_fru_field_types();
|
||||||
wbcx.visit_opaque_types(body.value.span);
|
wbcx.visit_opaque_types(body.value.span);
|
||||||
wbcx.visit_coercion_casts();
|
wbcx.visit_coercion_casts();
|
||||||
wbcx.visit_free_region_map();
|
|
||||||
wbcx.visit_user_provided_tys();
|
wbcx.visit_user_provided_tys();
|
||||||
wbcx.visit_user_provided_sigs();
|
wbcx.visit_user_provided_sigs();
|
||||||
wbcx.visit_generator_interior_types();
|
wbcx.visit_generator_interior_types();
|
||||||
@ -125,7 +124,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
|
|
||||||
fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'tcx>) {
|
fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'tcx>) {
|
||||||
debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty);
|
debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty);
|
||||||
assert!(!ty.needs_infer() && !ty.has_placeholders());
|
assert!(!ty.needs_infer() && !ty.has_placeholders() && !ty.has_free_regions());
|
||||||
self.tables.node_types_mut().insert(hir_id, ty);
|
self.tables.node_types_mut().insert(hir_id, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,9 +326,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
let new_upvar_capture = match *upvar_capture {
|
let new_upvar_capture = match *upvar_capture {
|
||||||
ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
|
ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
|
||||||
ty::UpvarCapture::ByRef(ref upvar_borrow) => {
|
ty::UpvarCapture::ByRef(ref upvar_borrow) => {
|
||||||
let r = upvar_borrow.region;
|
ty::UpvarCapture::ByRef(ty::UpvarBorrow {
|
||||||
let r = self.resolve(&r, &upvar_id.var_path.hir_id);
|
kind: upvar_borrow.kind,
|
||||||
ty::UpvarCapture::ByRef(ty::UpvarBorrow { kind: upvar_borrow.kind, region: r })
|
region: self.tcx().lifetimes.re_erased,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
debug!("Upvar capture for {:?} resolved to {:?}", upvar_id, new_upvar_capture);
|
debug!("Upvar capture for {:?} resolved to {:?}", upvar_id, new_upvar_capture);
|
||||||
@ -358,11 +358,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_free_region_map(&mut self) {
|
|
||||||
self.tables.free_region_map = self.fcx.tables.borrow().free_region_map.clone();
|
|
||||||
debug_assert!(!self.tables.free_region_map.elements().any(|r| r.has_local_value()));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_user_provided_tys(&mut self) {
|
fn visit_user_provided_tys(&mut self) {
|
||||||
let fcx_tables = self.fcx.tables.borrow();
|
let fcx_tables = self.fcx.tables.borrow();
|
||||||
debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
|
debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
|
||||||
@ -427,8 +422,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
fn visit_opaque_types(&mut self, span: Span) {
|
fn visit_opaque_types(&mut self, span: Span) {
|
||||||
for (&def_id, opaque_defn) in self.fcx.opaque_types.borrow().iter() {
|
for (&def_id, opaque_defn) in self.fcx.opaque_types.borrow().iter() {
|
||||||
let hir_id = self.tcx().hir().as_local_hir_id(def_id).unwrap();
|
let hir_id = self.tcx().hir().as_local_hir_id(def_id).unwrap();
|
||||||
let instantiated_ty =
|
let instantiated_ty = self.resolve(&opaque_defn.concrete_ty, &hir_id);
|
||||||
self.tcx().erase_regions(&self.resolve(&opaque_defn.concrete_ty, &hir_id));
|
|
||||||
|
|
||||||
debug_assert!(!instantiated_ty.has_escaping_bound_vars());
|
debug_assert!(!instantiated_ty.has_escaping_bound_vars());
|
||||||
|
|
||||||
@ -617,10 +611,8 @@ impl Locatable for hir::HirId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
/// The Resolver. This is the type folding engine that detects
|
||||||
// The Resolver. This is the type folding engine that detects
|
/// unresolved types and so forth.
|
||||||
// unresolved types and so forth.
|
|
||||||
|
|
||||||
struct Resolver<'cx, 'tcx> {
|
struct Resolver<'cx, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
infcx: &'cx InferCtxt<'cx, 'tcx>,
|
infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||||
@ -653,7 +645,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
|||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match self.infcx.fully_resolve(&t) {
|
match self.infcx.fully_resolve(&t) {
|
||||||
Ok(t) => t,
|
Ok(t) => self.infcx.tcx.erase_regions(&t),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
|
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
|
||||||
self.report_error(t);
|
self.report_error(t);
|
||||||
@ -662,15 +654,14 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME This should be carefully checked
|
|
||||||
// We could use `self.report_error` but it doesn't accept a ty::Region, right now.
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
self.infcx.fully_resolve(&r).unwrap_or(self.tcx.lifetimes.re_static)
|
debug_assert!(!r.is_late_bound(), "Should not be resolving bound region.");
|
||||||
|
self.tcx.lifetimes.re_erased
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
match self.infcx.fully_resolve(&ct) {
|
match self.infcx.fully_resolve(&ct) {
|
||||||
Ok(ct) => ct,
|
Ok(ct) => self.infcx.tcx.erase_regions(&ct),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
|
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
|
||||||
// FIXME: we'd like to use `self.report_error`, but it doesn't yet
|
// FIXME: we'd like to use `self.report_error`, but it doesn't yet
|
||||||
|
@ -12,7 +12,7 @@ use rustc_hir::def_id::DefId;
|
|||||||
use rustc_hir::ItemKind;
|
use rustc_hir::ItemKind;
|
||||||
use rustc_infer::infer;
|
use rustc_infer::infer;
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{SuppressRegionErrors, TyCtxtInferExt};
|
use rustc_infer::infer::{RegionckMode, TyCtxtInferExt};
|
||||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::misc::{can_type_implement_copy, CopyImplementationError};
|
use rustc_trait_selection::traits::misc::{can_type_implement_copy, CopyImplementationError};
|
||||||
use rustc_trait_selection::traits::predicate_for_trait_def;
|
use rustc_trait_selection::traits::predicate_for_trait_def;
|
||||||
@ -307,7 +307,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: DefId) {
|
|||||||
impl_did,
|
impl_did,
|
||||||
®ion_scope_tree,
|
®ion_scope_tree,
|
||||||
&outlives_env,
|
&outlives_env,
|
||||||
SuppressRegionErrors::default(),
|
RegionckMode::default(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -568,7 +568,7 @@ pub fn coerce_unsized_info(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedI
|
|||||||
impl_did,
|
impl_did,
|
||||||
®ion_scope_tree,
|
®ion_scope_tree,
|
||||||
&outlives_env,
|
&outlives_env,
|
||||||
SuppressRegionErrors::default(),
|
RegionckMode::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
CoerceUnsizedInfo { custom_kind: kind }
|
CoerceUnsizedInfo { custom_kind: kind }
|
||||||
|
@ -75,7 +75,7 @@ use rustc_data_structures::fx::FxHashSet;
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{InferCtxt, SuppressRegionErrors, TyCtxtInferExt};
|
use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::specialization_graph::Node;
|
use rustc_infer::traits::specialization_graph::Node;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::{self, translate_substs, wf};
|
use rustc_trait_selection::traits::{self, translate_substs, wf};
|
||||||
@ -162,7 +162,7 @@ fn get_impl_substs<'tcx>(
|
|||||||
impl1_def_id,
|
impl1_def_id,
|
||||||
&ScopeTree::default(),
|
&ScopeTree::default(),
|
||||||
&outlives_env,
|
&outlives_env,
|
||||||
SuppressRegionErrors::default(),
|
RegionckMode::default(),
|
||||||
);
|
);
|
||||||
let impl2_substs = match infcx.fully_resolve(&impl2_substs) {
|
let impl2_substs = match infcx.fully_resolve(&impl2_substs) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
|
@ -84,8 +84,8 @@ pub fn add_type_ascription_to_parameter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(cfail1))]
|
#[cfg(not(cfail1))]
|
||||||
#[rustc_clean(cfg="cfail2", except="hir_owner_items, mir_built, typeck_tables_of")]
|
#[rustc_clean(cfg = "cfail2", except = "hir_owner_items, typeck_tables_of")]
|
||||||
#[rustc_clean(cfg="cfail3")]
|
#[rustc_clean(cfg = "cfail3")]
|
||||||
pub fn add_type_ascription_to_parameter() {
|
pub fn add_type_ascription_to_parameter() {
|
||||||
let closure = |x: u32| x + 1u32;
|
let closure = |x: u32| x + 1u32;
|
||||||
let _: u32 = closure(1);
|
let _: u32 = closure(1);
|
||||||
|
@ -360,7 +360,7 @@ impl Foo {
|
|||||||
impl Foo {
|
impl Foo {
|
||||||
#[rustc_clean(
|
#[rustc_clean(
|
||||||
cfg="cfail2",
|
cfg="cfail2",
|
||||||
except="hir_owner,hir_owner_items,generics_of,predicates_of,type_of,typeck_tables_of"
|
except="hir_owner,hir_owner_items,generics_of,predicates_of,type_of"
|
||||||
)]
|
)]
|
||||||
#[rustc_clean(cfg="cfail3")]
|
#[rustc_clean(cfg="cfail3")]
|
||||||
pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b: 'a>(&self) { }
|
pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b: 'a>(&self) { }
|
||||||
|
@ -81,7 +81,7 @@ pub fn var_deref(x: &i32, y: &i32) -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(cfail1))]
|
#[cfg(not(cfail1))]
|
||||||
#[rustc_clean(except="hir_owner_items,optimized_mir,mir_built,typeck_tables_of", cfg="cfail2")]
|
#[rustc_clean(except="hir_owner_items,optimized_mir,mir_built", cfg="cfail2")]
|
||||||
#[rustc_clean(cfg="cfail3")]
|
#[rustc_clean(cfg="cfail3")]
|
||||||
pub fn var_deref(x: &i32, y: &i32) -> i32 {
|
pub fn var_deref(x: &i32, y: &i32) -> i32 {
|
||||||
*y
|
*y
|
||||||
|
@ -4,9 +4,9 @@ extern "C" {
|
|||||||
|
|
||||||
static Y: i32 = 42;
|
static Y: i32 = 42;
|
||||||
|
|
||||||
static mut BAR: *const &'static i32 = [&Y].as_ptr();
|
static mut BAR: *const &i32 = [&Y].as_ptr();
|
||||||
|
|
||||||
static mut FOO: *const &'static i32 = [unsafe { &X }].as_ptr();
|
static mut FOO: *const &i32 = [unsafe { &X }].as_ptr();
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
@ -18,8 +18,8 @@ fn main() {}
|
|||||||
// _4 = &(*_5);
|
// _4 = &(*_5);
|
||||||
// _3 = [move _4];
|
// _3 = [move _4];
|
||||||
// _2 = &_3;
|
// _2 = &_3;
|
||||||
// _1 = move _2 as &[&'static i32] (Pointer(Unsize));
|
// _1 = move _2 as &[&i32] (Pointer(Unsize));
|
||||||
// _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
|
// _0 = const core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
|
||||||
// }
|
// }
|
||||||
// ...
|
// ...
|
||||||
// bb2: {
|
// bb2: {
|
||||||
@ -35,8 +35,8 @@ fn main() {}
|
|||||||
// _4 = &(*_5);
|
// _4 = &(*_5);
|
||||||
// _3 = [move _4];
|
// _3 = [move _4];
|
||||||
// _2 = &_3;
|
// _2 = &_3;
|
||||||
// _1 = move _2 as &[&'static i32] (Pointer(Unsize));
|
// _1 = move _2 as &[&i32] (Pointer(Unsize));
|
||||||
// _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
|
// _0 = const core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
|
||||||
// }
|
// }
|
||||||
// ...
|
// ...
|
||||||
// bb2: {
|
// bb2: {
|
||||||
@ -50,8 +50,8 @@ fn main() {}
|
|||||||
// ...
|
// ...
|
||||||
// _6 = const BAR::promoted[0];
|
// _6 = const BAR::promoted[0];
|
||||||
// _2 = &(*_6);
|
// _2 = &(*_6);
|
||||||
// _1 = move _2 as &[&'static i32] (Pointer(Unsize));
|
// _1 = move _2 as &[&i32] (Pointer(Unsize));
|
||||||
// _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
|
// _0 = const core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
|
||||||
// }
|
// }
|
||||||
// ...
|
// ...
|
||||||
// bb2: {
|
// bb2: {
|
||||||
@ -63,8 +63,8 @@ fn main() {}
|
|||||||
// ...
|
// ...
|
||||||
// _6 = const FOO::promoted[0];
|
// _6 = const FOO::promoted[0];
|
||||||
// _2 = &(*_6);
|
// _2 = &(*_6);
|
||||||
// _1 = move _2 as &[&'static i32] (Pointer(Unsize));
|
// _1 = move _2 as &[&i32] (Pointer(Unsize));
|
||||||
// _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
|
// _0 = const core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
|
||||||
// }
|
// }
|
||||||
// ...
|
// ...
|
||||||
// bb2: {
|
// bb2: {
|
||||||
|
@ -27,7 +27,7 @@ fn main() {
|
|||||||
// }
|
// }
|
||||||
// bb2: {
|
// bb2: {
|
||||||
// ...
|
// ...
|
||||||
// const std::rt::begin_panic::<&'static str>(const "explicit panic") -> bb5;
|
// const std::rt::begin_panic::<&str>(const "explicit panic") -> bb5;
|
||||||
// }
|
// }
|
||||||
// bb3: {
|
// bb3: {
|
||||||
// unreachable;
|
// unreachable;
|
||||||
|
@ -26,16 +26,16 @@ fn main() {
|
|||||||
// goto -> bb7;
|
// goto -> bb7;
|
||||||
// }
|
// }
|
||||||
// bb2: {
|
// bb2: {
|
||||||
// switchInt((*(*((_1 as Some).0: &'<empty> &'<empty> i32)))) -> [0i32: bb3, otherwise: bb1];
|
// switchInt((*(*((_1 as Some).0: &&i32)))) -> [0i32: bb3, otherwise: bb1];
|
||||||
// }
|
// }
|
||||||
// bb3: {
|
// bb3: {
|
||||||
// goto -> bb4;
|
// goto -> bb4;
|
||||||
// }
|
// }
|
||||||
// bb4: {
|
// bb4: {
|
||||||
// _4 = &shallow _1;
|
// _4 = &shallow _1;
|
||||||
// _5 = &shallow ((_1 as Some).0: &'<empty> &'<empty> i32);
|
// _5 = &shallow ((_1 as Some).0: &&i32);
|
||||||
// _6 = &shallow (*((_1 as Some).0: &'<empty> &'<empty> i32));
|
// _6 = &shallow (*((_1 as Some).0: &&i32));
|
||||||
// _7 = &shallow (*(*((_1 as Some).0: &'<empty> &'<empty> i32)));
|
// _7 = &shallow (*(*((_1 as Some).0: &&i32)));
|
||||||
// StorageLive(_8);
|
// StorageLive(_8);
|
||||||
// _8 = _2;
|
// _8 = _2;
|
||||||
// switchInt(move _8) -> [false: bb6, otherwise: bb5];
|
// switchInt(move _8) -> [false: bb6, otherwise: bb5];
|
||||||
@ -72,7 +72,7 @@ fn main() {
|
|||||||
// goto -> bb7;
|
// goto -> bb7;
|
||||||
// }
|
// }
|
||||||
// bb2: {
|
// bb2: {
|
||||||
// switchInt((*(*((_1 as Some).0: &'<empty> &'<empty> i32)))) -> [0i32: bb3, otherwise: bb1];
|
// switchInt((*(*((_1 as Some).0: &&i32)))) -> [0i32: bb3, otherwise: bb1];
|
||||||
// }
|
// }
|
||||||
// bb3: {
|
// bb3: {
|
||||||
// goto -> bb4;
|
// goto -> bb4;
|
||||||
|
@ -35,12 +35,12 @@ fn main() {
|
|||||||
|
|
||||||
// END RUST SOURCE
|
// END RUST SOURCE
|
||||||
// START rustc.XXX.mir_map.0.mir
|
// START rustc.XXX.mir_map.0.mir
|
||||||
// let mut _0: &'static Foo;
|
// let mut _0: &Foo;
|
||||||
// let _1: &'static Foo;
|
// let _1: &Foo;
|
||||||
// let _2: Foo;
|
// let _2: Foo;
|
||||||
// let mut _3: &'static [(u32, u32)];
|
// let mut _3: &[(u32, u32)];
|
||||||
// let mut _4: &'static [(u32, u32); 42];
|
// let mut _4: &[(u32, u32); 42];
|
||||||
// let _5: &'static [(u32, u32); 42];
|
// let _5: &[(u32, u32); 42];
|
||||||
// let _6: [(u32, u32); 42];
|
// let _6: [(u32, u32); 42];
|
||||||
// let mut _7: (u32, u32);
|
// let mut _7: (u32, u32);
|
||||||
// let mut _8: (u32, u32);
|
// let mut _8: (u32, u32);
|
||||||
@ -178,7 +178,7 @@ fn main() {
|
|||||||
// _6 = [move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46, move _47, move _48];
|
// _6 = [move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46, move _47, move _48];
|
||||||
// _5 = &_6;
|
// _5 = &_6;
|
||||||
// _4 = &(*_5);
|
// _4 = &(*_5);
|
||||||
// _3 = move _4 as &'static [(u32, u32)] (Pointer(Unsize));
|
// _3 = move _4 as &[(u32, u32)] (Pointer(Unsize));
|
||||||
// _2 = Foo { tup: const "hi", data: move _3 };
|
// _2 = Foo { tup: const "hi", data: move _3 };
|
||||||
// _1 = &_2;
|
// _1 = &_2;
|
||||||
// _0 = &(*_1);
|
// _0 = &(*_1);
|
||||||
|
@ -34,29 +34,29 @@ pub fn bar() ({
|
|||||||
((::alloc::fmt::format as
|
((::alloc::fmt::format as
|
||||||
for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((::core::fmt::Arguments::new_v1
|
for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((::core::fmt::Arguments::new_v1
|
||||||
as
|
as
|
||||||
fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments::<'_>::new_v1})((&([("test"
|
fn(&[&str], &[std::fmt::ArgumentV1]) -> std::fmt::Arguments {std::fmt::Arguments::new_v1})((&([("test"
|
||||||
as
|
as
|
||||||
&'static str)]
|
&str)]
|
||||||
as
|
as
|
||||||
[&str; 1])
|
[&str; 1])
|
||||||
as
|
as
|
||||||
&[&str; 1]),
|
&[&str; 1]),
|
||||||
(&(match (()
|
(&(match (()
|
||||||
as
|
as
|
||||||
())
|
())
|
||||||
{
|
{
|
||||||
()
|
()
|
||||||
=>
|
=>
|
||||||
([]
|
([]
|
||||||
as
|
as
|
||||||
[std::fmt::ArgumentV1<'_>; 0]),
|
[std::fmt::ArgumentV1; 0]),
|
||||||
}
|
}
|
||||||
as
|
as
|
||||||
[std::fmt::ArgumentV1<'_>; 0])
|
[std::fmt::ArgumentV1; 0])
|
||||||
as
|
as
|
||||||
&[std::fmt::ArgumentV1<'_>; 0]))
|
&[std::fmt::ArgumentV1; 0]))
|
||||||
as
|
as
|
||||||
std::fmt::Arguments<'_>))
|
std::fmt::Arguments))
|
||||||
as std::string::String);
|
as std::string::String);
|
||||||
(res as std::string::String)
|
(res as std::string::String)
|
||||||
} as std::string::String);
|
} as std::string::String);
|
||||||
|
@ -21,7 +21,7 @@ LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
|
|||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: source type: `usize` (word size)
|
= note: source type: `usize` (word size)
|
||||||
= note: target type: `&'static [u8]` (2 * word size)
|
= note: target type: `&[u8]` (2 * word size)
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
error: could not evaluate constant pattern
|
||||||
--> $DIR/transmute-size-mismatch-before-typeck.rs:10:9
|
--> $DIR/transmute-size-mismatch-before-typeck.rs:10:9
|
||||||
|
@ -14,7 +14,7 @@ LL | static BAR: _ = "test";
|
|||||||
| ^
|
| ^
|
||||||
| |
|
| |
|
||||||
| not allowed in type signatures
|
| not allowed in type signatures
|
||||||
| help: replace `_` with the correct type: `&'static str`
|
| help: replace `_` with the correct type: `&str`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
|
|||||||
LL | let new: T::B = unsafe { std::mem::transmute(value) };
|
LL | let new: T::B = unsafe { std::mem::transmute(value) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: source type: `<T as Trait<'a>>::A` (size can vary because of <T as Trait>::A)
|
= note: source type: `<T as Trait>::A` (this type does not have a fixed size)
|
||||||
= note: target type: `<T as Trait<'a>>::B` (size can vary because of <T as Trait>::B)
|
= note: target type: `<T as Trait>::B` (this type does not have a fixed size)
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: the type `&'static T` does not permit zero-initialization
|
error: the type `&T` does not permit zero-initialization
|
||||||
--> $DIR/uninitialized-zeroed.rs:29:32
|
--> $DIR/uninitialized-zeroed.rs:29:32
|
||||||
|
|
|
|
||||||
LL | let _val: &'static T = mem::zeroed();
|
LL | let _val: &'static T = mem::zeroed();
|
||||||
@ -14,7 +14,7 @@ LL | #![deny(invalid_value)]
|
|||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
= note: references must be non-null
|
= note: references must be non-null
|
||||||
|
|
||||||
error: the type `&'static T` does not permit being left uninitialized
|
error: the type `&T` does not permit being left uninitialized
|
||||||
--> $DIR/uninitialized-zeroed.rs:30:32
|
--> $DIR/uninitialized-zeroed.rs:30:32
|
||||||
|
|
|
|
||||||
LL | let _val: &'static T = mem::uninitialized();
|
LL | let _val: &'static T = mem::uninitialized();
|
||||||
@ -25,7 +25,7 @@ LL | let _val: &'static T = mem::uninitialized();
|
|||||||
|
|
|
|
||||||
= note: references must be non-null
|
= note: references must be non-null
|
||||||
|
|
||||||
error: the type `Wrap<&'static T>` does not permit zero-initialization
|
error: the type `Wrap<&T>` does not permit zero-initialization
|
||||||
--> $DIR/uninitialized-zeroed.rs:32:38
|
--> $DIR/uninitialized-zeroed.rs:32:38
|
||||||
|
|
|
|
||||||
LL | let _val: Wrap<&'static T> = mem::zeroed();
|
LL | let _val: Wrap<&'static T> = mem::zeroed();
|
||||||
@ -40,7 +40,7 @@ note: references must be non-null (in this struct field)
|
|||||||
LL | struct Wrap<T> { wrapped: T }
|
LL | struct Wrap<T> { wrapped: T }
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: the type `Wrap<&'static T>` does not permit being left uninitialized
|
error: the type `Wrap<&T>` does not permit being left uninitialized
|
||||||
--> $DIR/uninitialized-zeroed.rs:33:38
|
--> $DIR/uninitialized-zeroed.rs:33:38
|
||||||
|
|
|
|
||||||
LL | let _val: Wrap<&'static T> = mem::uninitialized();
|
LL | let _val: Wrap<&'static T> = mem::uninitialized();
|
||||||
@ -121,7 +121,7 @@ LL | let _val: Void = mem::uninitialized();
|
|||||||
|
|
|
|
||||||
= note: enums with no variants have no valid value
|
= note: enums with no variants have no valid value
|
||||||
|
|
||||||
error: the type `&'static i32` does not permit zero-initialization
|
error: the type `&i32` does not permit zero-initialization
|
||||||
--> $DIR/uninitialized-zeroed.rs:49:34
|
--> $DIR/uninitialized-zeroed.rs:49:34
|
||||||
|
|
|
|
||||||
LL | let _val: &'static i32 = mem::zeroed();
|
LL | let _val: &'static i32 = mem::zeroed();
|
||||||
@ -132,7 +132,7 @@ LL | let _val: &'static i32 = mem::zeroed();
|
|||||||
|
|
|
|
||||||
= note: references must be non-null
|
= note: references must be non-null
|
||||||
|
|
||||||
error: the type `&'static i32` does not permit being left uninitialized
|
error: the type `&i32` does not permit being left uninitialized
|
||||||
--> $DIR/uninitialized-zeroed.rs:50:34
|
--> $DIR/uninitialized-zeroed.rs:50:34
|
||||||
|
|
|
|
||||||
LL | let _val: &'static i32 = mem::uninitialized();
|
LL | let _val: &'static i32 = mem::uninitialized();
|
||||||
@ -366,7 +366,7 @@ LL | let _val: NonBig = mem::uninitialized();
|
|||||||
|
|
|
|
||||||
= note: `NonBig` must be initialized inside its custom valid range
|
= note: `NonBig` must be initialized inside its custom valid range
|
||||||
|
|
||||||
error: the type `&'static i32` does not permit zero-initialization
|
error: the type `&i32` does not permit zero-initialization
|
||||||
--> $DIR/uninitialized-zeroed.rs:84:34
|
--> $DIR/uninitialized-zeroed.rs:84:34
|
||||||
|
|
|
|
||||||
LL | let _val: &'static i32 = mem::transmute(0usize);
|
LL | let _val: &'static i32 = mem::transmute(0usize);
|
||||||
@ -377,7 +377,7 @@ LL | let _val: &'static i32 = mem::transmute(0usize);
|
|||||||
|
|
|
|
||||||
= note: references must be non-null
|
= note: references must be non-null
|
||||||
|
|
||||||
error: the type `&'static [i32]` does not permit zero-initialization
|
error: the type `&[i32]` does not permit zero-initialization
|
||||||
--> $DIR/uninitialized-zeroed.rs:85:36
|
--> $DIR/uninitialized-zeroed.rs:85:36
|
||||||
|
|
|
|
||||||
LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize));
|
LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize));
|
||||||
|
@ -21,7 +21,7 @@ fn uninhab_union() -> Foo {
|
|||||||
|
|
||||||
fn match_on_uninhab() {
|
fn match_on_uninhab() {
|
||||||
match uninhab_ref() {
|
match uninhab_ref() {
|
||||||
//~^ ERROR non-exhaustive patterns: type `&'static !` is non-empty
|
//~^ ERROR non-exhaustive patterns: type `&!` is non-empty
|
||||||
}
|
}
|
||||||
|
|
||||||
match uninhab_union() {
|
match uninhab_union() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error[E0004]: non-exhaustive patterns: type `&'static !` is non-empty
|
error[E0004]: non-exhaustive patterns: type `&!` is non-empty
|
||||||
--> $DIR/always-inhabited-union-ref.rs:23:11
|
--> $DIR/always-inhabited-union-ref.rs:23:11
|
||||||
|
|
|
|
||||||
LL | match uninhab_ref() {
|
LL | match uninhab_ref() {
|
||||||
|
@ -1,32 +1,54 @@
|
|||||||
error[E0623]: lifetime mismatch
|
error[E0491]: in type `&'b &'a usize`, reference has a longer lifetime than the data it references
|
||||||
--> $DIR/regions-free-region-ordering-caller.rs:11:12
|
--> $DIR/regions-free-region-ordering-caller.rs:11:12
|
||||||
|
|
|
|
||||||
LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
|
|
||||||
| --------- ---------
|
|
||||||
| |
|
|
||||||
| these two types are declared with different lifetimes...
|
|
||||||
LL | let z: Option<&'b &'a usize> = None;
|
LL | let z: Option<&'b &'a usize> = None;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: the pointer is valid for the lifetime `'b` as defined on the function body at 10:14
|
||||||
|
--> $DIR/regions-free-region-ordering-caller.rs:10:14
|
||||||
|
|
|
||||||
|
LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||||
|
| ^^
|
||||||
|
note: but the referenced data is only valid for the lifetime `'a` as defined on the function body at 10:10
|
||||||
|
--> $DIR/regions-free-region-ordering-caller.rs:10:10
|
||||||
|
|
|
||||||
|
LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||||
|
| ^^
|
||||||
|
|
||||||
error[E0623]: lifetime mismatch
|
error[E0491]: in type `&'b Paramd<'a>`, reference has a longer lifetime than the data it references
|
||||||
--> $DIR/regions-free-region-ordering-caller.rs:17:12
|
--> $DIR/regions-free-region-ordering-caller.rs:17:12
|
||||||
|
|
|
|
||||||
LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
|
|
||||||
| --------- ---------
|
|
||||||
| |
|
|
||||||
| these two types are declared with different lifetimes...
|
|
||||||
LL | let y: Paramd<'a> = Paramd { x: a };
|
|
||||||
LL | let z: Option<&'b Paramd<'a>> = None;
|
LL | let z: Option<&'b Paramd<'a>> = None;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: the pointer is valid for the lifetime `'b` as defined on the function body at 15:14
|
||||||
|
--> $DIR/regions-free-region-ordering-caller.rs:15:14
|
||||||
|
|
|
||||||
|
LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||||
|
| ^^
|
||||||
|
note: but the referenced data is only valid for the lifetime `'a` as defined on the function body at 15:10
|
||||||
|
--> $DIR/regions-free-region-ordering-caller.rs:15:10
|
||||||
|
|
|
||||||
|
LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||||
|
| ^^
|
||||||
|
|
||||||
error[E0623]: lifetime mismatch
|
error[E0491]: in type `&'a &'b usize`, reference has a longer lifetime than the data it references
|
||||||
--> $DIR/regions-free-region-ordering-caller.rs:22:12
|
--> $DIR/regions-free-region-ordering-caller.rs:22:12
|
||||||
|
|
|
|
||||||
LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
|
|
||||||
| --------- --------- these two types are declared with different lifetimes...
|
|
||||||
LL | let z: Option<&'a &'b usize> = None;
|
LL | let z: Option<&'a &'b usize> = None;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ ...but data from `b` flows into `a` here
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: the pointer is valid for the lifetime `'a` as defined on the function body at 21:10
|
||||||
|
--> $DIR/regions-free-region-ordering-caller.rs:21:10
|
||||||
|
|
|
||||||
|
LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||||
|
| ^^
|
||||||
|
note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 21:14
|
||||||
|
--> $DIR/regions-free-region-ordering-caller.rs:21:14
|
||||||
|
|
|
||||||
|
LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||||
|
| ^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0623`.
|
For more information about this error, try `rustc --explain E0491`.
|
||||||
|
@ -8,18 +8,18 @@
|
|||||||
struct Paramd<'a> { x: &'a usize }
|
struct Paramd<'a> { x: &'a usize }
|
||||||
|
|
||||||
fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
|
fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||||
let z: Option<&'b &'a usize> = None;//[migrate]~ ERROR E0623
|
let z: Option<&'b &'a usize> = None;//[migrate]~ ERROR E0491
|
||||||
//[nll]~^ ERROR lifetime may not live long enough
|
//[nll]~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
|
fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||||
let y: Paramd<'a> = Paramd { x: a };
|
let y: Paramd<'a> = Paramd { x: a };
|
||||||
let z: Option<&'b Paramd<'a>> = None;//[migrate]~ ERROR E0623
|
let z: Option<&'b Paramd<'a>> = None;//[migrate]~ ERROR E0491
|
||||||
//[nll]~^ ERROR lifetime may not live long enough
|
//[nll]~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
|
fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||||
let z: Option<&'a &'b usize> = None;//[migrate]~ ERROR E0623
|
let z: Option<&'a &'b usize> = None;//[migrate]~ ERROR E0491
|
||||||
//[nll]~^ ERROR lifetime may not live long enough
|
//[nll]~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,4 +43,4 @@ static S = Vec::<String>::new();
|
|||||||
static mut SM = "abc";
|
static mut SM = "abc";
|
||||||
//~^ ERROR missing type for `static mut` item
|
//~^ ERROR missing type for `static mut` item
|
||||||
//~| HELP provide a type for the item
|
//~| HELP provide a type for the item
|
||||||
//~| SUGGESTION &'static str
|
//~| SUGGESTION &str
|
||||||
|
@ -14,7 +14,7 @@ error: missing type for `static mut` item
|
|||||||
--> $DIR/const-no-type.rs:43:12
|
--> $DIR/const-no-type.rs:43:12
|
||||||
|
|
|
|
||||||
LL | static mut SM = "abc";
|
LL | static mut SM = "abc";
|
||||||
| ^^ help: provide a type for the item: `SM: &'static str`
|
| ^^ help: provide a type for the item: `SM: &str`
|
||||||
|
|
||||||
error: missing type for `const` item
|
error: missing type for `const` item
|
||||||
--> $DIR/const-no-type.rs:14:7
|
--> $DIR/const-no-type.rs:14:7
|
||||||
|
@ -4,8 +4,7 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
|
|||||||
LL | transmute(x)
|
LL | transmute(x)
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: source type: `<C as TypeConstructor<'a>>::T` (size can vary because of <C as TypeConstructor>::T)
|
= note: `<C as TypeConstructor>::T` does not have a fixed size
|
||||||
= note: target type: `<C as TypeConstructor<'b>>::T` (size can vary because of <C as TypeConstructor>::T)
|
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/main.rs:20:17
|
--> $DIR/main.rs:20:17
|
||||||
|
@ -70,7 +70,7 @@ LL | static TEST3: _ = "test";
|
|||||||
| ^
|
| ^
|
||||||
| |
|
| |
|
||||||
| not allowed in type signatures
|
| not allowed in type signatures
|
||||||
| help: replace `_` with the correct type: `&'static str`
|
| help: replace `_` with the correct type: `&str`
|
||||||
|
|
||||||
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:15:15
|
--> $DIR/typeck_type_placeholder_item.rs:15:15
|
||||||
@ -232,7 +232,7 @@ LL | static FN_TEST3: _ = "test";
|
|||||||
| ^
|
| ^
|
||||||
| |
|
| |
|
||||||
| not allowed in type signatures
|
| not allowed in type signatures
|
||||||
| help: replace `_` with the correct type: `&'static str`
|
| help: replace `_` with the correct type: `&str`
|
||||||
|
|
||||||
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:88:22
|
--> $DIR/typeck_type_placeholder_item.rs:88:22
|
||||||
|
Loading…
Reference in New Issue
Block a user