Skip to content

Commit

Permalink
Add safe_suggestion attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Dec 20, 2016
1 parent 601bbf2 commit 164f010
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#![cfg_attr(test, allow(deprecated))] // rand
#![cfg_attr(not(stage0), deny(warnings))]
#![cfg_attr(not(stage0), feature(safe_suggestion))]

#![feature(alloc)]
#![feature(allow_internal_unstable)]
Expand Down
1 change: 1 addition & 0 deletions src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,7 @@ impl String {
/// assert_eq!(a.len(), 3);
/// ```
#[inline]
#[cfg_attr(not(stage0), safe_suggestion)]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn len(&self) -> usize {
self.vec.len()
Expand Down
29 changes: 24 additions & 5 deletions src/librustc/infer/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,19 +587,29 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// look for expected with found id
self.tcx.populate_inherent_implementations_for_type_if_necessary(found);
if let Some(impl_infos) = self.tcx.inherent_impls.borrow().get(&found) {
let mut methods = Vec::new();
let mut methods: Vec<(Option<ast::Attribute>, DefId, ImplOrTraitItem<'tcx>)> = Vec::new();
for impl_ in impl_infos {
methods.append(&mut self.tcx
.impl_or_trait_items(*impl_)
.iter()
.map(|&did| self.tcx.impl_or_trait_item(did))
.filter(|x| {
.map(|&did| (None, did, self.tcx.impl_or_trait_item(did)))
.filter(|&(_, _, ref x)| {
self.matches_return_type(x, &expected_ty)
})
.collect());
}
for method in methods {
println!("==> {:?}", method.name());
let safe_suggestions: Vec<_> = methods.iter()
.map(|&(_, ref id, ref x)| (self.find_attr(*id, "safe_suggestion"), id, x))
.filter(|&(ref res, _, _)| res.is_some())
.collect();
if safe_suggestions.len() > 0 {
for (_, _, method) in safe_suggestions {
println!("safe ==> {:?}", method.name());
}
} else {
for &(_, _, ref method) in methods.iter() {
println!("not safe ==> {:?}", method.name());
}
}
}
}
Expand All @@ -615,6 +625,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.tcx.note_and_explain_type_err(diag, terr, span);
}

fn find_attr(&self, def_id: DefId, attr_name: &str) -> Option<ast::Attribute> {
for item in self.tcx.get_attrs(def_id).iter() {
if item.check_name(attr_name) {
return Some(item.clone());
}
}
None
}

pub fn report_and_explain_type_error(&self,
trace: TypeTrace<'tcx>,
terr: &TypeError<'tcx>)
Expand Down
9 changes: 9 additions & 0 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ declare_features! (
// Allows using `Self` and associated types in struct expressions and patterns.
(active, more_struct_aliases, "1.14.0", Some(37544)),


// Allows #[link(..., cfg(..))]
(active, link_cfg, "1.14.0", Some(37406)),

Expand All @@ -314,6 +315,9 @@ declare_features! (

// Allows #[target_feature(...)]
(active, target_feature, "1.15.0", None),

// Allow safe suggestions for potential type conversions.
(active, safe_suggestion, "1.0.0", Some(37384)),
);

declare_features! (
Expand Down Expand Up @@ -648,6 +652,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
"internal implementation detail",
cfg_fn!(rustc_attrs))),

("safe_suggestion", Whitelisted, Gated("safe_suggestion",
"the `#[safe_suggestion]` attribute \
is an experimental feature",
cfg_fn!(safe_suggestion))),

// FIXME: #14408 whitelist docs since rustdoc looks at them
("doc", Whitelisted, Ungated),

Expand Down

0 comments on commit 164f010

Please sign in to comment.