mirror of https://github.com/rust-lang/rust.git
don't normalize in astconv
We delay projection normalization to further stages in order to register user type annotations before normalization in HIR typeck. There are two consumers of astconv: ItemCtxt and FnCtxt. The former already expects unnormalized types from astconv, see its AstConv trait impl. The latter needs `RawTy` for a cleaner interface. Unfortunately astconv still needs the normalization machinery in order to resolve enum variants that have projections in the self type, e.g. `<<T as Trait>::Assoc>::StructVariant {}`. This is why `AstConv::normalize_ty_2` is necessary.
This commit is contained in:
parent
93bf84c902
commit
d227506683
|
@ -106,11 +106,9 @@ pub trait AstConv<'tcx> {
|
|||
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
) -> Ty<'tcx>;
|
||||
|
||||
/// Normalize an associated type coming from the user.
|
||||
///
|
||||
/// This should only be used by astconv. Use `FnCtxt::normalize`
|
||||
/// or `ObligationCtxt::normalize` in downstream crates.
|
||||
fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
|
||||
fn normalize_ty_2(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
ty
|
||||
}
|
||||
|
||||
/// Invoked when we encounter an error from some prior pass
|
||||
/// (e.g., resolve) that is translated into a ty-error. This is
|
||||
|
@ -485,14 +483,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// Avoid ICE #86756 when type error recovery goes awry.
|
||||
return tcx.ty_error().into();
|
||||
}
|
||||
self.astconv
|
||||
.normalize_ty(
|
||||
self.span,
|
||||
tcx.at(self.span)
|
||||
.bound_type_of(param.def_id)
|
||||
.subst(tcx, substs),
|
||||
)
|
||||
.into()
|
||||
tcx.at(self.span).bound_type_of(param.def_id).subst(tcx, substs).into()
|
||||
} else if infer_args {
|
||||
self.astconv.ty_infer(Some(param), self.span).into()
|
||||
} else {
|
||||
|
@ -1254,7 +1245,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
item_segment: &hir::PathSegment<'_>,
|
||||
) -> Ty<'tcx> {
|
||||
let substs = self.ast_path_substs_for_ty(span, did, item_segment);
|
||||
self.normalize_ty(span, self.tcx().at(span).bound_type_of(did).subst(self.tcx(), substs))
|
||||
self.tcx().at(span).bound_type_of(did).subst(self.tcx(), substs)
|
||||
}
|
||||
|
||||
fn conv_object_ty_poly_trait_ref(
|
||||
|
@ -1786,7 +1777,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
Ok(bound)
|
||||
}
|
||||
|
||||
// Create a type from a path to an associated type.
|
||||
// Create a type from a path to an associated type or to an enum variant.
|
||||
// For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C`
|
||||
// and item_segment is the path segment for `D`. We return a type and a def for
|
||||
// the whole path.
|
||||
|
@ -1814,7 +1805,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
// Check if we have an enum variant.
|
||||
let mut variant_resolution = None;
|
||||
if let ty::Adt(adt_def, adt_substs) = qself_ty.kind() {
|
||||
if let ty::Adt(adt_def, adt_substs) = self.normalize_ty_2(span, qself_ty).kind() {
|
||||
if adt_def.is_enum() {
|
||||
let variant_def = adt_def
|
||||
.variants()
|
||||
|
@ -1923,7 +1914,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
adt_substs,
|
||||
);
|
||||
let ty = tcx.bound_type_of(assoc_ty_did).subst(tcx, item_substs);
|
||||
let ty = self.normalize_ty(span, ty);
|
||||
return Ok((ty, DefKind::AssocTy, assoc_ty_did));
|
||||
}
|
||||
}
|
||||
|
@ -2020,7 +2010,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
};
|
||||
|
||||
let ty = self.projected_ty_from_poly_trait_ref(span, assoc_ty_did, assoc_segment, bound);
|
||||
let ty = self.normalize_ty(span, ty);
|
||||
|
||||
if let Some(variant_def_id) = variant_resolution {
|
||||
tcx.struct_span_lint_hir(
|
||||
|
@ -2156,7 +2145,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
|
||||
|
||||
self.normalize_ty(span, tcx.mk_projection(item_def_id, item_substs))
|
||||
tcx.mk_projection(item_def_id, item_substs)
|
||||
}
|
||||
|
||||
pub fn prohibit_generics<'a>(
|
||||
|
@ -2417,7 +2406,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
err.note("`impl Trait` types can't have type parameters");
|
||||
});
|
||||
let substs = self.ast_path_substs_for_ty(span, did, item_segment.0);
|
||||
self.normalize_ty(span, tcx.mk_opaque(did, substs))
|
||||
tcx.mk_opaque(did, substs)
|
||||
}
|
||||
Res::Def(
|
||||
DefKind::Enum
|
||||
|
@ -2577,7 +2566,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
tcx.ty_error_with_guaranteed(err.emit())
|
||||
} else {
|
||||
self.normalize_ty(span, ty)
|
||||
ty
|
||||
}
|
||||
}
|
||||
Res::Def(DefKind::AssocTy, def_id) => {
|
||||
|
@ -2720,8 +2709,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
None,
|
||||
ty::BoundConstness::NotConst,
|
||||
);
|
||||
EarlyBinder(self.normalize_ty(span, tcx.at(span).type_of(def_id)))
|
||||
.subst(tcx, substs)
|
||||
EarlyBinder(tcx.at(span).type_of(def_id)).subst(tcx, substs)
|
||||
}
|
||||
hir::TyKind::Array(ref ty, ref length) => {
|
||||
let length = match length {
|
||||
|
@ -2731,8 +2719,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
};
|
||||
|
||||
let array_ty = tcx.mk_ty(ty::Array(self.ast_ty_to_ty(ty), length));
|
||||
self.normalize_ty(ast_ty.span, array_ty)
|
||||
tcx.mk_ty(ty::Array(self.ast_ty_to_ty(ty), length))
|
||||
}
|
||||
hir::TyKind::Typeof(ref e) => {
|
||||
let ty_erased = tcx.type_of(e.def_id);
|
||||
|
|
|
@ -505,11 +505,6 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn normalize_ty(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
// Types in item signatures are not normalized to avoid undue dependencies.
|
||||
ty
|
||||
}
|
||||
|
||||
fn set_tainted_by_errors(&self, _: ErrorGuaranteed) {
|
||||
// There's no obvious place to track this, so just let it go.
|
||||
}
|
||||
|
|
|
@ -647,14 +647,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
),
|
||||
bound_vars,
|
||||
);
|
||||
// Astconv can't normalize inputs or outputs with escaping bound vars,
|
||||
// so normalize them here, after we've wrapped them in a binder.
|
||||
let result = self.normalize(self.tcx.hir().span(hir_id), result);
|
||||
|
||||
let c_result = self.inh.infcx.canonicalize_response(result);
|
||||
self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result);
|
||||
|
||||
result
|
||||
// Normalize only after registering in `user_provided_sigs`.
|
||||
self.normalize(self.tcx.hir().span(hir_id), result)
|
||||
}
|
||||
|
||||
/// Invoked when we are translating the generator that results
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::callee::{self, DeferredCallResolution};
|
||||
use crate::method::{self, MethodCallee, SelfSource};
|
||||
use crate::rvalue_scopes;
|
||||
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy};
|
||||
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, RawTy};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
|
||||
|
@ -410,23 +410,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
|
||||
pub fn create_raw_ty(&self, span: Span, ty: Ty<'tcx>) -> RawTy<'tcx> {
|
||||
RawTy { raw: ty, normalized: self.normalize(span, ty) }
|
||||
}
|
||||
|
||||
pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> RawTy<'tcx> {
|
||||
let t = <dyn AstConv<'_>>::ast_ty_to_ty(self, ast_t);
|
||||
self.register_wf_obligation(t.into(), ast_t.span, traits::WellFormed(None));
|
||||
t
|
||||
self.create_raw_ty(ast_t.span, t)
|
||||
}
|
||||
|
||||
pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
|
||||
let ty = self.to_ty(ast_ty);
|
||||
debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
|
||||
|
||||
if Self::can_contain_user_lifetime_bounds(ty) {
|
||||
let c_ty = self.canonicalize_response(UserType::Ty(ty));
|
||||
if Self::can_contain_user_lifetime_bounds(ty.raw) {
|
||||
let c_ty = self.canonicalize_response(UserType::Ty(ty.raw));
|
||||
debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
|
||||
self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
|
||||
}
|
||||
|
||||
ty
|
||||
ty.normalized
|
||||
}
|
||||
|
||||
pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> ty::Const<'tcx> {
|
||||
|
@ -780,7 +784,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
qpath: &'tcx QPath<'tcx>,
|
||||
hir_id: hir::HirId,
|
||||
span: Span,
|
||||
) -> (Res, Option<Ty<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
|
||||
) -> (Res, Option<RawTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
|
||||
debug!(
|
||||
"resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}",
|
||||
qpath, hir_id, span
|
||||
|
@ -803,7 +807,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// to be object-safe.
|
||||
// We manually call `register_wf_obligation` in the success path
|
||||
// below.
|
||||
(<dyn AstConv<'_>>::ast_ty_to_ty_in_path(self, qself), qself, segment)
|
||||
let ty = <dyn AstConv<'_>>::ast_ty_to_ty_in_path(self, qself);
|
||||
(self.create_raw_ty(span, ty), qself, segment)
|
||||
}
|
||||
QPath::LangItem(..) => {
|
||||
bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
|
||||
|
@ -811,7 +816,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
};
|
||||
if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
|
||||
{
|
||||
self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
|
||||
self.register_wf_obligation(ty.raw.into(), qself.span, traits::WellFormed(None));
|
||||
// Return directly on cache hit. This is useful to avoid doubly reporting
|
||||
// errors with default match binding modes. See #44614.
|
||||
let def = cached_result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id));
|
||||
|
@ -819,7 +824,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
let item_name = item_segment.ident;
|
||||
let result = self
|
||||
.resolve_fully_qualified_call(span, item_name, ty, qself.span, hir_id)
|
||||
.resolve_fully_qualified_call(span, item_name, ty.normalized, qself.span, hir_id)
|
||||
.or_else(|error| {
|
||||
let result = match error {
|
||||
method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
|
||||
|
@ -830,13 +835,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// a WF obligation for `dyn MyTrait` when method lookup fails. Otherwise,
|
||||
// register a WF obligation so that we can detect any additional
|
||||
// errors in the self type.
|
||||
if !(matches!(error, method::MethodError::NoMatch(_)) && ty.is_trait()) {
|
||||
self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
|
||||
if !(matches!(error, method::MethodError::NoMatch(_)) && ty.normalized.is_trait()) {
|
||||
self.register_wf_obligation(
|
||||
ty.raw.into(),
|
||||
qself.span,
|
||||
traits::WellFormed(None),
|
||||
);
|
||||
}
|
||||
if item_name.name != kw::Empty {
|
||||
if let Some(mut e) = self.report_method_error(
|
||||
span,
|
||||
ty,
|
||||
ty.normalized,
|
||||
item_name,
|
||||
SelfSource::QPath(qself),
|
||||
error,
|
||||
|
@ -849,7 +858,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
});
|
||||
|
||||
if result.is_ok() {
|
||||
self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
|
||||
self.register_wf_obligation(ty.raw.into(), qself.span, traits::WellFormed(None));
|
||||
}
|
||||
|
||||
// Write back the new resolution.
|
||||
|
@ -986,7 +995,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
pub fn instantiate_value_path(
|
||||
&self,
|
||||
segments: &[hir::PathSegment<'_>],
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
self_ty: Option<RawTy<'tcx>>,
|
||||
res: Res,
|
||||
span: Span,
|
||||
hir_id: hir::HirId,
|
||||
|
@ -996,7 +1005,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let path_segs = match res {
|
||||
Res::Local(_) | Res::SelfCtor(_) => vec![],
|
||||
Res::Def(kind, def_id) => <dyn AstConv<'_>>::def_ids_for_value_path_segments(
|
||||
self, segments, self_ty, kind, def_id,
|
||||
self,
|
||||
segments,
|
||||
self_ty.map(|ty| ty.normalized),
|
||||
kind,
|
||||
def_id,
|
||||
),
|
||||
_ => bug!("instantiate_value_path on {:?}", res),
|
||||
};
|
||||
|
@ -1007,8 +1020,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
Res::Def(DefKind::Ctor(CtorOf::Variant, _), _)
|
||||
if let Some(self_ty) = self_ty =>
|
||||
{
|
||||
let adt_def = self_ty.ty_adt_def().unwrap();
|
||||
user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did(), self_ty });
|
||||
let adt_def = self_ty.normalized.ty_adt_def().unwrap();
|
||||
user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did(), self_ty: self_ty.raw });
|
||||
is_alias_variant_ctor = true;
|
||||
}
|
||||
Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
|
||||
|
@ -1027,7 +1040,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// inherent impl, we need to record the
|
||||
// `T` for posterity (see `UserSelfTy` for
|
||||
// details).
|
||||
let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
|
||||
let self_ty = self_ty.expect("UFCS sugared assoc missing Self").raw;
|
||||
user_self_ty = Some(UserSelfTy { impl_def_id: container_id, self_ty });
|
||||
}
|
||||
}
|
||||
|
@ -1109,7 +1122,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.unwrap_or(false);
|
||||
|
||||
let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
|
||||
let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
|
||||
let ty = self.normalize_ty_2(span, tcx.at(span).type_of(impl_def_id));
|
||||
match *ty.kind() {
|
||||
ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
|
||||
let variant = adt_def.non_enum_variant();
|
||||
|
@ -1193,7 +1206,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
<dyn AstConv<'_>>::ast_region_to_region(self.fcx, lt, Some(param)).into()
|
||||
}
|
||||
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
|
||||
self.fcx.to_ty(ty).into()
|
||||
self.fcx.to_ty(ty).raw.into()
|
||||
}
|
||||
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
|
||||
self.fcx.const_arg_to_const(&ct.value, param.def_id).into()
|
||||
|
@ -1227,7 +1240,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// is missing.
|
||||
let default = tcx.bound_type_of(param.def_id);
|
||||
self.fcx
|
||||
.normalize_ty(self.span, default.subst(tcx, substs.unwrap()))
|
||||
.normalize_ty_2(self.span, default.subst(tcx, substs.unwrap()))
|
||||
.into()
|
||||
} else {
|
||||
// If no type arguments were provided, we have to infer them.
|
||||
|
@ -1250,13 +1263,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let substs = self_ctor_substs.unwrap_or_else(|| {
|
||||
let substs_raw = self_ctor_substs.unwrap_or_else(|| {
|
||||
<dyn AstConv<'_>>::create_substs_for_generic_args(
|
||||
tcx,
|
||||
def_id,
|
||||
&[],
|
||||
has_self,
|
||||
self_ty,
|
||||
self_ty.map(|s| s.raw),
|
||||
&arg_count,
|
||||
&mut CreateCtorSubstsContext {
|
||||
fcx: self,
|
||||
|
@ -1269,7 +1282,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
});
|
||||
|
||||
// First, store the "user substs" for later.
|
||||
self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
|
||||
self.write_user_type_annotation_from_substs(hir_id, def_id, substs_raw, user_self_ty);
|
||||
|
||||
// Normalize only after registering type annotations.
|
||||
let substs = self.normalize(span, substs_raw);
|
||||
|
||||
self.add_required_obligations_for_hir(span, def_id, &substs, hir_id);
|
||||
|
||||
|
@ -1287,6 +1303,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// with the substituted impl type.
|
||||
// This also occurs for an enum variant on a type alias.
|
||||
let impl_ty = self.normalize(span, tcx.bound_type_of(impl_def_id).subst(tcx, substs));
|
||||
let self_ty = self.normalize(span, self_ty);
|
||||
match self.at(&self.misc(span), self.param_env).eq(impl_ty, self_ty) {
|
||||
Ok(ok) => self.register_infer_ok_obligations(ok),
|
||||
Err(_) => {
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::method::MethodCallee;
|
|||
use crate::Expectation::*;
|
||||
use crate::TupleArgumentsFlag::*;
|
||||
use crate::{
|
||||
struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, Needs,
|
||||
struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, Needs, RawTy,
|
||||
TupleArgumentsFlag,
|
||||
};
|
||||
use rustc_ast as ast;
|
||||
|
@ -1231,13 +1231,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
);
|
||||
return None;
|
||||
}
|
||||
Res::Def(DefKind::Variant, _) => match ty.kind() {
|
||||
Res::Def(DefKind::Variant, _) => match ty.normalized.kind() {
|
||||
ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did(), substs)),
|
||||
_ => bug!("unexpected type: {:?}", ty),
|
||||
_ => bug!("unexpected type: {:?}", ty.normalized),
|
||||
},
|
||||
Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
|
||||
| Res::SelfTyParam { .. }
|
||||
| Res::SelfTyAlias { .. } => match ty.kind() {
|
||||
| Res::SelfTyAlias { .. } => match ty.normalized.kind() {
|
||||
ty::Adt(adt, substs) if !adt.is_enum() => {
|
||||
Some((adt.non_enum_variant(), adt.did(), substs))
|
||||
}
|
||||
|
@ -1248,14 +1248,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
if let Some((variant, did, substs)) = variant {
|
||||
debug!("check_struct_path: did={:?} substs={:?}", did, substs);
|
||||
self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
|
||||
|
||||
// FIXME(aliemjay): We're using UserSelfTy unconditionally here because it is the only
|
||||
// way to register the raw user ty, because `substs` is normalized.
|
||||
let self_ty = ty::UserSelfTy { impl_def_id: did, self_ty: ty.raw };
|
||||
self.write_user_type_annotation_from_substs(hir_id, did, substs, Some(self_ty));
|
||||
|
||||
// Check bounds on type arguments used in the path.
|
||||
self.add_required_obligations_for_hir(path_span, did, substs, hir_id);
|
||||
|
||||
Some((variant, ty))
|
||||
Some((variant, ty.normalized))
|
||||
} else {
|
||||
match ty.kind() {
|
||||
match ty.normalized.kind() {
|
||||
ty::Error(_) => {
|
||||
// E0071 might be caused by a spelling error, which will have
|
||||
// already caused an error message and probably a suggestion
|
||||
|
@ -1268,7 +1272,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
path_span,
|
||||
E0071,
|
||||
"expected struct, variant or union type, found {}",
|
||||
ty.sort_string(self.tcx)
|
||||
ty.normalized.sort_string(self.tcx)
|
||||
)
|
||||
.span_label(path_span, "not a struct")
|
||||
.emit();
|
||||
|
@ -1656,20 +1660,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
qpath: &QPath<'_>,
|
||||
path_span: Span,
|
||||
hir_id: hir::HirId,
|
||||
) -> (Res, Ty<'tcx>) {
|
||||
) -> (Res, RawTy<'tcx>) {
|
||||
match *qpath {
|
||||
QPath::Resolved(ref maybe_qself, ref path) => {
|
||||
let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
|
||||
let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself).raw);
|
||||
let ty = <dyn AstConv<'_>>::res_to_ty(self, self_ty, path, true);
|
||||
(path.res, ty)
|
||||
(path.res, self.create_raw_ty(path_span, ty))
|
||||
}
|
||||
QPath::TypeRelative(ref qself, ref segment) => {
|
||||
let ty = self.to_ty(qself);
|
||||
|
||||
let result = <dyn AstConv<'_>>::associated_path_to_ty(
|
||||
self, hir_id, path_span, ty, qself, segment, true,
|
||||
self, hir_id, path_span, ty.raw, qself, segment, true,
|
||||
);
|
||||
let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
|
||||
let ty = self.create_raw_ty(path_span, ty);
|
||||
let result = result.map(|(_, kind, def_id)| (kind, def_id));
|
||||
|
||||
// Write back the new resolution.
|
||||
|
@ -1678,7 +1683,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
(result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty)
|
||||
}
|
||||
QPath::LangItem(lang_item, span, id) => {
|
||||
self.resolve_lang_item_path(lang_item, span, hir_id, id)
|
||||
let (res, ty) = self.resolve_lang_item_path(lang_item, span, hir_id, id);
|
||||
(res, self.create_raw_ty(path_span, ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,7 @@ use rustc_infer::infer::error_reporting::TypeErrCtxt;
|
|||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{self, Span};
|
||||
|
@ -298,7 +297,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
|||
self.tcx().mk_projection(item_def_id, item_substs)
|
||||
}
|
||||
|
||||
fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn normalize_ty_2(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if ty.has_escaping_bound_vars() {
|
||||
ty // FIXME: normalization and escaping regions
|
||||
} else {
|
||||
|
@ -310,7 +309,19 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
|||
self.infcx.set_tainted_by_errors(e)
|
||||
}
|
||||
|
||||
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
|
||||
self.write_ty(hir_id, ty)
|
||||
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
|
||||
self.write_ty(hir_id, self.normalize_ty_2(span, ty))
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a user-provided type in the raw form (never normalized).
|
||||
///
|
||||
/// This is a bridge between the interface of `AstConv`, which outputs a raw `Ty`,
|
||||
/// and the API in this module, which expect `Ty` to be fully normalized.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct RawTy<'tcx> {
|
||||
pub raw: Ty<'tcx>,
|
||||
|
||||
/// The normalized form of `raw`, stored here for efficiency.
|
||||
pub normalized: Ty<'tcx>,
|
||||
}
|
||||
|
|
|
@ -77,7 +77,8 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
|
|||
Some(ref ty) => {
|
||||
let o_ty = self.fcx.to_ty(&ty);
|
||||
|
||||
let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty));
|
||||
let c_ty =
|
||||
self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty.raw));
|
||||
debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty);
|
||||
self.fcx
|
||||
.typeck_results
|
||||
|
@ -85,7 +86,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
|
|||
.user_provided_types_mut()
|
||||
.insert(ty.hir_id, c_ty);
|
||||
|
||||
Some(LocalTy { decl_ty: o_ty, revealed_ty: o_ty })
|
||||
Some(LocalTy { decl_ty: o_ty.normalized, revealed_ty: o_ty.normalized })
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
|
|
@ -297,7 +297,7 @@ fn typeck_with_fallback<'tcx>(
|
|||
fcx.resolve_generator_interiors(def_id.to_def_id());
|
||||
|
||||
for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
|
||||
let ty = fcx.normalize_ty(span, ty);
|
||||
let ty = fcx.normalize(span, ty);
|
||||
fcx.require_type_is_sized(ty, span, code);
|
||||
}
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
.into()
|
||||
}
|
||||
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
|
||||
self.cfcx.to_ty(ty).into()
|
||||
self.cfcx.to_ty(ty).raw.into()
|
||||
}
|
||||
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
|
||||
self.cfcx.const_arg_to_const(&ct.value, param.def_id).into()
|
||||
|
@ -397,7 +397,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
self.cfcx.var_for_def(self.cfcx.span, param)
|
||||
}
|
||||
}
|
||||
<dyn AstConv<'_>>::create_substs_for_generic_args(
|
||||
let substs = <dyn AstConv<'_>>::create_substs_for_generic_args(
|
||||
self.tcx,
|
||||
pick.item.def_id,
|
||||
parent_substs,
|
||||
|
@ -405,7 +405,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
None,
|
||||
&arg_count_correct,
|
||||
&mut MethodSubstsCtxt { cfcx: self, pick, seg },
|
||||
)
|
||||
);
|
||||
// FIXME(aliemjay): Type annotation should be registered before normalization.
|
||||
self.normalize(self.span, substs)
|
||||
}
|
||||
|
||||
fn unify_receivers(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::FnCtxt;
|
||||
use crate::{FnCtxt, RawTy};
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{
|
||||
|
@ -842,7 +842,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&self,
|
||||
pat: &Pat<'tcx>,
|
||||
qpath: &hir::QPath<'_>,
|
||||
path_resolution: (Res, Option<Ty<'tcx>>, &'tcx [hir::PathSegment<'tcx>]),
|
||||
path_resolution: (Res, Option<RawTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]),
|
||||
expected: Ty<'tcx>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
|
|
|
@ -91,6 +91,7 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>(
|
|||
}
|
||||
|
||||
if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
|
||||
let self_ty = ocx.normalize(&cause, param_env, self_ty);
|
||||
let impl_self_ty = tcx.bound_type_of(impl_def_id).subst(tcx, substs);
|
||||
let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty);
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
// check-pass
|
||||
//~ ERROR broken MIR
|
||||
|
||||
// known-bug
|
||||
// failure-status: 101
|
||||
// rustc-env: RUSTC_BACKTRACE=0
|
||||
|
||||
#![feature(adt_const_params, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
|
|
@ -14,14 +14,6 @@ fn foo<T>() {
|
|||
let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
|
||||
//~^ ERROR `T` does not live long enough
|
||||
//~| ERROR `T` does not live long enough
|
||||
//~| ERROR `T` does not live long enough
|
||||
//~| ERROR `T` does not live long enough
|
||||
//~| ERROR `T` does not live long enough
|
||||
//~| ERROR `T` does not live long enough
|
||||
//~| ERROR `T` does not live long enough
|
||||
//~| ERROR `T` does not live long enough
|
||||
//~| ERROR `T` may not live long enough
|
||||
//~| ERROR `T` may not live long enough
|
||||
//
|
||||
// FIXME: This error is bogus, but it arises because we try to validate
|
||||
// that `<() as Foo<T>>::Type<'a>` is valid, which requires proving
|
||||
|
|
|
@ -10,64 +10,5 @@ error: `T` does not live long enough
|
|||
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `T` does not live long enough
|
||||
--> $DIR/issue-91139.rs:14:12
|
||||
|
|
||||
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: `T` does not live long enough
|
||||
--> $DIR/issue-91139.rs:14:12
|
||||
|
|
||||
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0310]: the parameter type `T` may not live long enough
|
||||
--> $DIR/issue-91139.rs:14:58
|
||||
|
|
||||
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
|
||||
| ^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
||||
|
|
||||
help: consider adding an explicit lifetime bound...
|
||||
|
|
||||
LL | fn foo<T: 'static>() {
|
||||
| +++++++++
|
||||
|
||||
error: `T` does not live long enough
|
||||
--> $DIR/issue-91139.rs:14:58
|
||||
|
|
||||
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: `T` does not live long enough
|
||||
--> $DIR/issue-91139.rs:14:58
|
||||
|
|
||||
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0310]: the parameter type `T` may not live long enough
|
||||
--> $DIR/issue-91139.rs:14:58
|
||||
|
|
||||
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
|
||||
| ^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
||||
|
|
||||
help: consider adding an explicit lifetime bound...
|
||||
|
|
||||
LL | fn foo<T: 'static>() {
|
||||
| +++++++++
|
||||
|
||||
error: `T` does not live long enough
|
||||
--> $DIR/issue-91139.rs:14:58
|
||||
|
|
||||
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: `T` does not live long enough
|
||||
--> $DIR/issue-91139.rs:14:58
|
||||
|
|
||||
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0310`.
|
||||
|
|
|
@ -7,6 +7,7 @@ trait SomeTrait<'a> {
|
|||
fn give_me_ice<T>() {
|
||||
callee::<fn(&()) -> <T as SomeTrait<'_>>::Associated>();
|
||||
//~^ ERROR the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied [E0277]
|
||||
//~| ERROR the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied [E0277]
|
||||
}
|
||||
|
||||
fn callee<T: Fn<(&'static (),)>>() {
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
error[E0277]: the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied
|
||||
--> $DIR/issue-85455.rs:8:14
|
||||
|
|
||||
LL | callee::<fn(&()) -> <T as SomeTrait<'_>>::Associated>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> SomeTrait<'a>` is not implemented for `T`
|
||||
|
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | fn give_me_ice<T: for<'a> SomeTrait<'a>>() {
|
||||
| +++++++++++++++++++++++
|
||||
|
||||
error[E0277]: the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied
|
||||
--> $DIR/issue-85455.rs:8:5
|
||||
|
|
||||
|
@ -9,6 +20,6 @@ help: consider restricting type parameter `T`
|
|||
LL | fn give_me_ice<T: for<'a> SomeTrait<'a>>() {
|
||||
| +++++++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
@ -16,16 +16,6 @@ impl Trait for &'static () {
|
|||
|
||||
fn main() {
|
||||
let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
//~| ERROR higher-ranked subtype error
|
||||
//~| ERROR higher-ranked subtype error
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~^ ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
}
|
||||
|
|
|
@ -1,33 +1,3 @@
|
|||
error: lifetime may not live long enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^-^
|
||||
| ||
|
||||
| |has type `<&'1 () as Trait>::Ty`
|
||||
| requires that `'1` must outlive `'static`
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:12
|
||||
|
|
||||
|
@ -46,59 +16,5 @@ LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
|||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:12
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:12
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// check-pass
|
||||
// known-bug: #101350
|
||||
// Regression test for #101350.
|
||||
// check-fail
|
||||
|
||||
trait Trait {
|
||||
type Ty;
|
||||
|
@ -11,6 +11,7 @@ impl Trait for &'static () {
|
|||
|
||||
fn extend<'a>() {
|
||||
None::<<&'a () as Trait>::Ty>;
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
error: lifetime may not live long enough
|
||||
--> $DIR/ascribed-type-wf.rs:13:5
|
||||
|
|
||||
LL | fn extend<'a>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | None::<<&'a () as Trait>::Ty>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -11,8 +11,10 @@ struct SomeStruct<T> { t: T }
|
|||
#[rustc_dump_user_substs]
|
||||
fn main() {
|
||||
SomeStruct { t: 22 }; // Nothing given, no annotation.
|
||||
//~^ ERROR SomeStruct<^0>
|
||||
|
||||
SomeStruct::<_> { t: 22 }; // Nothing interesting given, no annotation.
|
||||
//~^ ERROR SomeStruct<^0>
|
||||
|
||||
SomeStruct::<u32> { t: 22 }; // No lifetime bounds given.
|
||||
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
error: user substs: UserSubsts { substs: [&ReStatic u32], user_self_ty: None }
|
||||
--> $DIR/dump-adt-brace-struct.rs:19:5
|
||||
error: user substs: UserSubsts { substs: [^0], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(0:3 ~ dump_adt_brace_struct[4679]::SomeStruct), self_ty: SomeStruct<^0> }) }
|
||||
--> $DIR/dump-adt-brace-struct.rs:13:5
|
||||
|
|
||||
LL | SomeStruct { t: 22 }; // Nothing given, no annotation.
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: user substs: UserSubsts { substs: [^0], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(0:3 ~ dump_adt_brace_struct[4679]::SomeStruct), self_ty: SomeStruct<^0> }) }
|
||||
--> $DIR/dump-adt-brace-struct.rs:16:5
|
||||
|
|
||||
LL | SomeStruct::<_> { t: 22 }; // Nothing interesting given, no annotation.
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: user substs: UserSubsts { substs: [&ReStatic u32], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(0:3 ~ dump_adt_brace_struct[4679]::SomeStruct), self_ty: SomeStruct<&ReStatic u32> }) }
|
||||
--> $DIR/dump-adt-brace-struct.rs:21:5
|
||||
|
|
||||
LL | SomeStruct::<&'static u32> { t: &22 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
// Make sure we honor region constraints when normalizing type annotations.
|
||||
|
||||
// check-fail
|
||||
|
||||
#![feature(more_qualified_paths)]
|
||||
|
||||
trait Trait {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
impl<T> Trait for T
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
type Assoc = MyTy<()>;
|
||||
}
|
||||
|
||||
enum MyTy<T> {
|
||||
Unit,
|
||||
Tuple(),
|
||||
Struct {},
|
||||
Dumb(T),
|
||||
}
|
||||
|
||||
impl<T> MyTy<T> {
|
||||
fn method<X>() {}
|
||||
}
|
||||
|
||||
type Ty<'a> = <&'a () as Trait>::Assoc;
|
||||
|
||||
fn test_local<'a>() {
|
||||
let _: Ty<'a> = MyTy::Unit;
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn test_closure_sig<'a, 'b>() {
|
||||
|_: Ty<'a>| {};
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
|| -> Option<Ty<'b>> { None };
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn test_path<'a, 'b, 'c, 'd>() {
|
||||
<Ty<'a>>::method::<Ty<'static>>;
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
<Ty<'static>>::method::<Ty<'b>>;
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn test_call<'a, 'b, 'c>() {
|
||||
<Ty<'a>>::method::<Ty<'static>>();
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
<Ty<'static>>::method::<Ty<'b>>();
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn test_variants<'a, 'b, 'c>() {
|
||||
<Ty<'a>>::Struct {}; //TODO
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
<Ty<'b>>::Tuple();
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
<Ty<'c>>::Unit;
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn test_pattern<'a, 'b, 'c>() {
|
||||
use MyTy::*;
|
||||
match MyTy::Unit {
|
||||
Struct::<Ty<'a>> {..} => {},
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
Tuple::<Ty<'b>> (..) => {},
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
Unit::<Ty<'c>> => {},
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
Dumb(_) => {},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,141 @@
|
|||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:32:12
|
||||
|
|
||||
LL | fn test_local<'a>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | let _: Ty<'a> = MyTy::Unit;
|
||||
| ^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:37:6
|
||||
|
|
||||
LL | fn test_closure_sig<'a, 'b>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | |_: Ty<'a>| {};
|
||||
| ^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:39:11
|
||||
|
|
||||
LL | fn test_closure_sig<'a, 'b>() {
|
||||
| -- lifetime `'b` defined here
|
||||
...
|
||||
LL | || -> Option<Ty<'b>> { None };
|
||||
| ^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
= help: replace `'b` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:44:5
|
||||
|
|
||||
LL | fn test_path<'a, 'b, 'c, 'd>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | <Ty<'a>>::method::<Ty<'static>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:46:5
|
||||
|
|
||||
LL | fn test_path<'a, 'b, 'c, 'd>() {
|
||||
| -- lifetime `'b` defined here
|
||||
...
|
||||
LL | <Ty<'static>>::method::<Ty<'b>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
= help: replace `'b` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:51:5
|
||||
|
|
||||
LL | fn test_call<'a, 'b, 'c>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | <Ty<'a>>::method::<Ty<'static>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:53:5
|
||||
|
|
||||
LL | fn test_call<'a, 'b, 'c>() {
|
||||
| -- lifetime `'b` defined here
|
||||
...
|
||||
LL | <Ty<'static>>::method::<Ty<'b>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
= help: replace `'b` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:58:5
|
||||
|
|
||||
LL | fn test_variants<'a, 'b, 'c>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | <Ty<'a>>::Struct {}; //TODO
|
||||
| ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:60:5
|
||||
|
|
||||
LL | fn test_variants<'a, 'b, 'c>() {
|
||||
| -- lifetime `'b` defined here
|
||||
...
|
||||
LL | <Ty<'b>>::Tuple();
|
||||
| ^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:62:5
|
||||
|
|
||||
LL | fn test_variants<'a, 'b, 'c>() {
|
||||
| -- lifetime `'c` defined here
|
||||
...
|
||||
LL | <Ty<'c>>::Unit;
|
||||
| ^^^^^^^^^^^^^^ requires that `'c` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
= help: replace `'b` with `'static`
|
||||
= help: replace `'c` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:69:9
|
||||
|
|
||||
LL | fn test_pattern<'a, 'b, 'c>() {
|
||||
| -- lifetime `'a` defined here
|
||||
...
|
||||
LL | Struct::<Ty<'a>> {..} => {},
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:71:9
|
||||
|
|
||||
LL | fn test_pattern<'a, 'b, 'c>() {
|
||||
| -- lifetime `'b` defined here
|
||||
...
|
||||
LL | Tuple::<Ty<'b>> (..) => {},
|
||||
| ^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/normalization-2.rs:73:9
|
||||
|
|
||||
LL | fn test_pattern<'a, 'b, 'c>() {
|
||||
| -- lifetime `'c` defined here
|
||||
...
|
||||
LL | Unit::<Ty<'c>> => {},
|
||||
| ^^^^^^^^^^^^^^ requires that `'c` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
= help: replace `'b` with `'static`
|
||||
= help: replace `'c` with `'static`
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
|
@ -205,7 +205,7 @@ error[E0223]: ambiguous associated type
|
|||
--> $DIR/ufcs-partially-resolved.rs:36:12
|
||||
|
|
||||
LL | let _: <u8 as Tr>::Y::NN;
|
||||
| ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u16 as Trait>::NN`
|
||||
| ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<<u8 as Tr>::Y as Trait>::NN`
|
||||
|
||||
error[E0599]: no associated item named `NN` found for type `u16` in the current scope
|
||||
--> $DIR/ufcs-partially-resolved.rs:38:20
|
||||
|
|
Loading…
Reference in New Issue