Stability annotations on generic trait parameters
This commit is contained in:
parent
6d3acf5129
commit
a7a2086053
@ -1756,6 +1756,9 @@ impl EncodeContext<'a, 'tcx> {
|
|||||||
EntryKind::TypeParam,
|
EntryKind::TypeParam,
|
||||||
default.is_some(),
|
default.is_some(),
|
||||||
);
|
);
|
||||||
|
if default.is_some() {
|
||||||
|
self.encode_stability(def_id.to_def_id());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
GenericParamKind::Const { .. } => {
|
GenericParamKind::Const { .. } => {
|
||||||
self.encode_info_for_generic_param(
|
self.encode_info_for_generic_param(
|
||||||
@ -1763,6 +1766,7 @@ impl EncodeContext<'a, 'tcx> {
|
|||||||
EntryKind::ConstParam,
|
EntryKind::ConstParam,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
// FIXME(const_generics:defaults)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,9 +293,15 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
/// If `id` is `Some(_)`, this function will also check if the item at `def_id` has been
|
/// If `id` is `Some(_)`, this function will also check if the item at `def_id` has been
|
||||||
/// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
|
/// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
|
||||||
/// `id`.
|
/// `id`.
|
||||||
pub fn eval_stability(self, def_id: DefId, id: Option<HirId>, span: Span) -> EvalResult {
|
pub fn eval_stability(
|
||||||
|
self,
|
||||||
|
def_id: DefId,
|
||||||
|
id: Option<HirId>,
|
||||||
|
span: Span,
|
||||||
|
check_deprecation: bool,
|
||||||
|
) -> EvalResult {
|
||||||
// Deprecated attributes apply in-crate and cross-crate.
|
// Deprecated attributes apply in-crate and cross-crate.
|
||||||
if let Some(id) = id {
|
if let (Some(id), true) = (id, check_deprecation) {
|
||||||
if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
|
if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
|
||||||
let parent_def_id = self.hir().local_def_id(self.hir().get_parent_item(id));
|
let parent_def_id = self.hir().local_def_id(self.hir().get_parent_item(id));
|
||||||
let skip = self
|
let skip = self
|
||||||
@ -395,21 +401,39 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
/// Additionally, this function will also check if the item is deprecated. If so, and `id` is
|
/// Additionally, this function will also check if the item is deprecated. If so, and `id` is
|
||||||
/// not `None`, a deprecated lint attached to `id` will be emitted.
|
/// not `None`, a deprecated lint attached to `id` will be emitted.
|
||||||
pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
|
pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
|
||||||
|
self.check_stability_internal(def_id, id, span, true, |span, def_id| {
|
||||||
|
// The API could be uncallable for other reasons, for example when a private module
|
||||||
|
// was referenced.
|
||||||
|
self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if an item is stable or error out.
|
||||||
|
///
|
||||||
|
/// If the item defined by `def_id` is unstable and the corresponding `#![feature]` does not
|
||||||
|
/// exist, emits an error.
|
||||||
|
///
|
||||||
|
/// Additionally when `inherit_dep` is `true`, this function will also check if the item is deprecated. If so, and `id` is
|
||||||
|
/// not `None`, a deprecated lint attached to `id` will be emitted.
|
||||||
|
pub fn check_stability_internal(
|
||||||
|
self,
|
||||||
|
def_id: DefId,
|
||||||
|
id: Option<HirId>,
|
||||||
|
span: Span,
|
||||||
|
check_deprecation: bool,
|
||||||
|
unmarked: impl FnOnce(Span, DefId) -> (),
|
||||||
|
) {
|
||||||
let soft_handler = |lint, span, msg: &_| {
|
let soft_handler = |lint, span, msg: &_| {
|
||||||
self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
|
self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
|
||||||
lint.build(msg).emit()
|
lint.build(msg).emit()
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
match self.eval_stability(def_id, id, span) {
|
match self.eval_stability(def_id, id, span, check_deprecation) {
|
||||||
EvalResult::Allow => {}
|
EvalResult::Allow => {}
|
||||||
EvalResult::Deny { feature, reason, issue, is_soft } => {
|
EvalResult::Deny { feature, reason, issue, is_soft } => {
|
||||||
report_unstable(self.sess, feature, reason, issue, is_soft, span, soft_handler)
|
report_unstable(self.sess, feature, reason, issue, is_soft, span, soft_handler)
|
||||||
}
|
}
|
||||||
EvalResult::Unmarked => {
|
EvalResult::Unmarked => unmarked(span, def_id),
|
||||||
// The API could be uncallable for other reasons, for example when a private module
|
|
||||||
// was referenced.
|
|
||||||
self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
|||||||
attrs: &[Attribute],
|
attrs: &[Attribute],
|
||||||
item_sp: Span,
|
item_sp: Span,
|
||||||
kind: AnnotationKind,
|
kind: AnnotationKind,
|
||||||
|
inherit_deprecation: bool,
|
||||||
visit_children: F,
|
visit_children: F,
|
||||||
) where
|
) where
|
||||||
F: FnOnce(&mut Self),
|
F: FnOnce(&mut Self),
|
||||||
@ -63,7 +64,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
|||||||
debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
|
debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
|
||||||
let mut did_error = false;
|
let mut did_error = false;
|
||||||
if !self.tcx.features().staged_api {
|
if !self.tcx.features().staged_api {
|
||||||
did_error = self.forbid_staged_api_attrs(hir_id, attrs);
|
did_error = self.forbid_staged_api_attrs(hir_id, attrs, inherit_deprecation);
|
||||||
}
|
}
|
||||||
|
|
||||||
let depr =
|
let depr =
|
||||||
@ -80,9 +81,11 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
|||||||
let depr_entry = DeprecationEntry::local(depr.clone(), hir_id);
|
let depr_entry = DeprecationEntry::local(depr.clone(), hir_id);
|
||||||
self.index.depr_map.insert(hir_id, depr_entry);
|
self.index.depr_map.insert(hir_id, depr_entry);
|
||||||
} else if let Some(parent_depr) = self.parent_depr.clone() {
|
} else if let Some(parent_depr) = self.parent_depr.clone() {
|
||||||
is_deprecated = true;
|
if inherit_deprecation {
|
||||||
info!("tagging child {:?} as deprecated from parent", hir_id);
|
is_deprecated = true;
|
||||||
self.index.depr_map.insert(hir_id, parent_depr);
|
info!("tagging child {:?} as deprecated from parent", hir_id);
|
||||||
|
self.index.depr_map.insert(hir_id, parent_depr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.tcx.features().staged_api {
|
if self.tcx.features().staged_api {
|
||||||
@ -186,7 +189,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
|||||||
if stab.is_none() {
|
if stab.is_none() {
|
||||||
debug!("annotate: stab not found, parent = {:?}", self.parent_stab);
|
debug!("annotate: stab not found, parent = {:?}", self.parent_stab);
|
||||||
if let Some(stab) = self.parent_stab {
|
if let Some(stab) = self.parent_stab {
|
||||||
if stab.level.is_unstable() {
|
if inherit_deprecation && stab.level.is_unstable() {
|
||||||
self.index.stab_map.insert(hir_id, stab);
|
self.index.stab_map.insert(hir_id, stab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +240,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns true if an error occurred, used to suppress some spurious errors
|
// returns true if an error occurred, used to suppress some spurious errors
|
||||||
fn forbid_staged_api_attrs(&mut self, hir_id: HirId, attrs: &[Attribute]) -> bool {
|
fn forbid_staged_api_attrs(&mut self, hir_id: HirId, attrs: &[Attribute], inherit_deprecation: bool) -> bool {
|
||||||
// Emit errors for non-staged-api crates.
|
// Emit errors for non-staged-api crates.
|
||||||
let unstable_attrs = [
|
let unstable_attrs = [
|
||||||
sym::unstable,
|
sym::unstable,
|
||||||
@ -265,7 +268,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
|||||||
// Propagate unstability. This can happen even for non-staged-api crates in case
|
// Propagate unstability. This can happen even for non-staged-api crates in case
|
||||||
// -Zforce-unstable-if-unmarked is set.
|
// -Zforce-unstable-if-unmarked is set.
|
||||||
if let Some(stab) = self.parent_stab {
|
if let Some(stab) = self.parent_stab {
|
||||||
if stab.level.is_unstable() {
|
if inherit_deprecation && stab.level.is_unstable() {
|
||||||
self.index.stab_map.insert(hir_id, stab);
|
self.index.stab_map.insert(hir_id, stab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,18 +304,25 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
hir::ItemKind::Struct(ref sd, _) => {
|
hir::ItemKind::Struct(ref sd, _) => {
|
||||||
if let Some(ctor_hir_id) = sd.ctor_hir_id() {
|
if let Some(ctor_hir_id) = sd.ctor_hir_id() {
|
||||||
self.annotate(ctor_hir_id, &i.attrs, i.span, AnnotationKind::Required, |_| {})
|
self.annotate(
|
||||||
|
ctor_hir_id,
|
||||||
|
&i.attrs,
|
||||||
|
i.span,
|
||||||
|
AnnotationKind::Required,
|
||||||
|
true,
|
||||||
|
|_| {},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.annotate(i.hir_id, &i.attrs, i.span, kind, |v| intravisit::walk_item(v, i));
|
self.annotate(i.hir_id, &i.attrs, i.span, kind, true, |v| intravisit::walk_item(v, i));
|
||||||
self.in_trait_impl = orig_in_trait_impl;
|
self.in_trait_impl = orig_in_trait_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
|
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
|
||||||
self.annotate(ti.hir_id, &ti.attrs, ti.span, AnnotationKind::Required, |v| {
|
self.annotate(ti.hir_id, &ti.attrs, ti.span, AnnotationKind::Required, true, |v| {
|
||||||
intravisit::walk_trait_item(v, ti);
|
intravisit::walk_trait_item(v, ti);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -320,15 +330,22 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
|||||||
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
|
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
|
||||||
let kind =
|
let kind =
|
||||||
if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required };
|
if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required };
|
||||||
self.annotate(ii.hir_id, &ii.attrs, ii.span, kind, |v| {
|
self.annotate(ii.hir_id, &ii.attrs, ii.span, kind, true, |v| {
|
||||||
intravisit::walk_impl_item(v, ii);
|
intravisit::walk_impl_item(v, ii);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
|
fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
|
||||||
self.annotate(var.id, &var.attrs, var.span, AnnotationKind::Required, |v| {
|
self.annotate(var.id, &var.attrs, var.span, AnnotationKind::Required, true, |v| {
|
||||||
if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
|
if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
|
||||||
v.annotate(ctor_hir_id, &var.attrs, var.span, AnnotationKind::Required, |_| {});
|
v.annotate(
|
||||||
|
ctor_hir_id,
|
||||||
|
&var.attrs,
|
||||||
|
var.span,
|
||||||
|
AnnotationKind::Required,
|
||||||
|
true,
|
||||||
|
|_| {},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
intravisit::walk_variant(v, var, g, item_id)
|
intravisit::walk_variant(v, var, g, item_id)
|
||||||
@ -336,19 +353,33 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_struct_field(&mut self, s: &'tcx StructField<'tcx>) {
|
fn visit_struct_field(&mut self, s: &'tcx StructField<'tcx>) {
|
||||||
self.annotate(s.hir_id, &s.attrs, s.span, AnnotationKind::Required, |v| {
|
self.annotate(s.hir_id, &s.attrs, s.span, AnnotationKind::Required, true, |v| {
|
||||||
intravisit::walk_struct_field(v, s);
|
intravisit::walk_struct_field(v, s);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) {
|
fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) {
|
||||||
self.annotate(i.hir_id, &i.attrs, i.span, AnnotationKind::Required, |v| {
|
self.annotate(i.hir_id, &i.attrs, i.span, AnnotationKind::Required, true, |v| {
|
||||||
intravisit::walk_foreign_item(v, i);
|
intravisit::walk_foreign_item(v, i);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
|
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
|
||||||
self.annotate(md.hir_id, &md.attrs, md.span, AnnotationKind::Required, |_| {});
|
self.annotate(md.hir_id, &md.attrs, md.span, AnnotationKind::Required, true, |_| {});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
|
||||||
|
let kind = match &p.kind {
|
||||||
|
// FIXME(const_generics:defaults)
|
||||||
|
hir::GenericParamKind::Type { default, .. } if default.is_some() => {
|
||||||
|
AnnotationKind::Container
|
||||||
|
}
|
||||||
|
_ => AnnotationKind::Prohibited,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.annotate(p.hir_id, &p.attrs, p.span, kind, false, |v| {
|
||||||
|
intravisit::walk_generic_param(v, p);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,6 +453,10 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
|
|||||||
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
|
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
|
||||||
self.check_missing_stability(md.hir_id, md.span);
|
self.check_missing_stability(md.hir_id, md.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that we don't need to `check_missing_stability` for default generic parameters,
|
||||||
|
// as we assume that any default generic parameters without attributes are automatically
|
||||||
|
// stable (assuming they have not inherited instability from their parent).
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
|
fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
|
||||||
@ -484,6 +519,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
|
|||||||
&krate.item.attrs,
|
&krate.item.attrs,
|
||||||
krate.item.span,
|
krate.item.span,
|
||||||
AnnotationKind::Required,
|
AnnotationKind::Required,
|
||||||
|
true,
|
||||||
|v| intravisit::walk_crate(v, krate),
|
|v| intravisit::walk_crate(v, krate),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
||||||
self.ast_region_to_region(<, Some(param)).into()
|
self.ast_region_to_region(<, Some(param)).into()
|
||||||
}
|
}
|
||||||
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
|
(GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
|
||||||
|
if *has_default {
|
||||||
|
tcx.check_stability_internal(
|
||||||
|
param.def_id,
|
||||||
|
Some(arg.id()),
|
||||||
|
arg.span(),
|
||||||
|
false,
|
||||||
|
|_, _| (),
|
||||||
|
)
|
||||||
|
}
|
||||||
if let (hir::TyKind::Infer, false) = (&ty.kind, self.allow_ty_infer()) {
|
if let (hir::TyKind::Infer, false) = (&ty.kind, self.allow_ty_infer()) {
|
||||||
inferred_params.push(ty.span);
|
inferred_params.push(ty.span);
|
||||||
tcx.ty_error().into()
|
tcx.ty_error().into()
|
||||||
|
@ -1227,7 +1227,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
if let Some(uc) = unstable_candidates {
|
if let Some(uc) = unstable_candidates {
|
||||||
applicable_candidates.retain(|&(p, _)| {
|
applicable_candidates.retain(|&(p, _)| {
|
||||||
if let stability::EvalResult::Deny { feature, .. } =
|
if let stability::EvalResult::Deny { feature, .. } =
|
||||||
self.tcx.eval_stability(p.item.def_id, None, self.span)
|
self.tcx.eval_stability(p.item.def_id, None, self.span, true)
|
||||||
{
|
{
|
||||||
uc.push((p, feature));
|
uc.push((p, feature));
|
||||||
return false;
|
return false;
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(staged_api)]
|
||||||
|
|
||||||
|
#![stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
pub trait Trait1<#[unstable(feature = "unstable_default", issue = "none")] T = ()> {
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
fn foo() -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
pub trait Trait2<#[unstable(feature = "unstable_default", issue = "none")] T = usize> {
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
fn foo() -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
pub trait Trait3<T = ()> {
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
fn foo() -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
pub struct Struct1<#[unstable(feature = "unstable_default", issue = "none")] T = usize> {
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
pub field: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
pub struct Struct2<T = usize> {
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
pub field: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
pub const STRUCT1: Struct1 = Struct1 { field: 1 };
|
||||||
|
|
||||||
|
#[stable(feature = "stable_test_feature", since = "1.0.0")]
|
||||||
|
pub const STRUCT2: Struct2 = Struct2 { field: 1 };
|
@ -0,0 +1,59 @@
|
|||||||
|
// aux-build:unstable_generic_param.rs
|
||||||
|
|
||||||
|
extern crate unstable_generic_param;
|
||||||
|
|
||||||
|
use unstable_generic_param::*;
|
||||||
|
|
||||||
|
struct R;
|
||||||
|
|
||||||
|
impl Trait1 for S {
|
||||||
|
fn foo() -> () { () } // ok
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl Trait1<usize> for S { //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
fn foo() -> usize { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait1<isize> for S { //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
fn foo() -> isize { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait2<usize> for S { //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
fn foo() -> usize { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait3<usize> for S {
|
||||||
|
fn foo() -> usize { 0 } // ok
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// let _ = S;
|
||||||
|
|
||||||
|
// let _ = Struct1 { field: 1 }; //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
// let _: Struct1 = Struct1 { field: 1 }; //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
// let _: Struct1<isize> = Struct1 { field: 1 }; //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
|
||||||
|
// let _ = STRUCT1; // ok
|
||||||
|
// let _: Struct1 = STRUCT1; // ok
|
||||||
|
// let _: Struct1<usize> = STRUCT1; //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
// let _: Struct1<usize> = STRUCT1; //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
// let _ = STRUCT1.field; // ok
|
||||||
|
// let _: usize = STRUCT1.field; //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
// let _ = STRUCT1.field + 1; //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
// let _ = STRUCT1.field + 1usize; //~ ERROR use of unstable library feature 'unstable_default'
|
||||||
|
|
||||||
|
// let _ = Struct2 { field: 1 }; // ok
|
||||||
|
// let _: Struct2 = Struct2 { field: 1 }; // ok
|
||||||
|
// let _: Struct2<usize> = Struct2 { field: 1 }; // ok
|
||||||
|
|
||||||
|
// let _ = STRUCT2;
|
||||||
|
// let _: Struct2 = STRUCT2; // ok
|
||||||
|
// let _: Struct2<usize> = STRUCT2; // ok
|
||||||
|
// let _: Struct2<usize> = STRUCT2; // ok
|
||||||
|
// let _ = STRUCT2.field; // ok
|
||||||
|
// let _: usize = STRUCT2.field; // ok
|
||||||
|
// let _ = STRUCT2.field + 1; // ok
|
||||||
|
// let _ = STRUCT2.field + 1usize; // ok
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
error[E0658]: use of unstable library feature 'unstable_default'
|
||||||
|
--> $DIR/generics-default-stability.rs:15:13
|
||||||
|
|
|
||||||
|
LL | impl Trait1<usize> for S {
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
= help: add `#![feature(unstable_default)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0658]: use of unstable library feature 'unstable_default'
|
||||||
|
--> $DIR/generics-default-stability.rs:19:13
|
||||||
|
|
|
||||||
|
LL | impl Trait1<isize> for S {
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
= help: add `#![feature(unstable_default)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0658]: use of unstable library feature 'unstable_default'
|
||||||
|
--> $DIR/generics-default-stability.rs:23:13
|
||||||
|
|
|
||||||
|
LL | impl Trait2<usize> for S {
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
= help: add `#![feature(unstable_default)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
Loading…
x
Reference in New Issue
Block a user