1
Fork 0

Auto merge of #64160 - Centril:rollup-vrfj1pt, r=Centril

Rollup of 15 pull requests

Successful merges:

 - #62860 (Stabilize checked_duration_since for 1.38.0)
 - #63549 (Rev::rposition counts from the wrong end)
 - #63985 (Stabilize pin_into_inner in 1.39.0)
 - #64005 (Add a `Place::is_indirect` method to determine whether a `Place` contains a `Deref` projection)
 - #64031 (Harden `param_attrs` test wrt. usage of a proc macro `#[attr]`)
 - #64038 (Check impl trait substs when checking for recursive types)
 - #64043 (Add some more tests for underscore imports)
 - #64092 (Update xLTO compatibility table in rustc book.)
 - #64110 (Refer to "`self` type" instead of "receiver type")
 - #64120 (Move path parsing earlier)
 - #64123 (Added warning around code with reference to uninit bytes)
 - #64128 (unused_parens: account for or-patterns and `&(mut x)`)
 - #64141 (Minimize uses of `LocalInternedString`)
 - #64142 (Fix doc links in `std::cmp` module)
 - #64148 (fix a few typos in comments)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-09-05 02:11:06 +00:00
commit a24f636e60
102 changed files with 1182 additions and 433 deletions

View file

@ -105,5 +105,6 @@ The following table shows known good combinations of toolchain versions.
| Rust 1.34 | ✗ | ✓ | | Rust 1.34 | ✗ | ✓ |
| Rust 1.35 | ✗ | ✓ | | Rust 1.35 | ✗ | ✓ |
| Rust 1.36 | ✗ | ✓ | | Rust 1.36 | ✗ | ✓ |
| Rust 1.37 | ✗ | ✓ |
Note that the compatibility policy for this feature might change in the future. Note that the compatibility policy for this feature might change in the future.

View file

@ -9,14 +9,22 @@
//! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and //! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
//! partial orderings between values, respectively. Implementing them overloads //! partial orderings between values, respectively. Implementing them overloads
//! the `<`, `<=`, `>`, and `>=` operators. //! the `<`, `<=`, `>`, and `>=` operators.
//! * [`Ordering`][cmp::Ordering] is an enum returned by the //! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and
//! main functions of [`Ord`] and [`PartialOrd`], and describes an ordering. //! [`PartialOrd`], and describes an ordering.
//! * [`Reverse`][cmp::Reverse] is a struct that allows you to easily reverse //! * [`Reverse`] is a struct that allows you to easily reverse an ordering.
//! an ordering. //! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you
//! * [`max`][cmp::max] and [`min`][cmp::min] are functions that build off of //! to find the maximum or minimum of two values.
//! [`Ord`] and allow you to find the maximum or minimum of two values.
//! //!
//! For more details, see the respective documentation of each item in the list. //! For more details, see the respective documentation of each item in the list.
//!
//! [`Eq`]: trait.Eq.html
//! [`PartialEq`]: trait.PartialEq.html
//! [`Ord`]: trait.Ord.html
//! [`PartialOrd`]: trait.PartialOrd.html
//! [`Ordering`]: enum.Ordering.html
//! [`Reverse`]: struct.Reverse.html
//! [`max`]: fn.max.html
//! [`min`]: fn.min.html
#![stable(feature = "rust1", since = "1.0.0")] #![stable(feature = "rust1", since = "1.0.0")]

View file

@ -66,13 +66,6 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
{ {
self.iter.rfind(predicate) self.iter.rfind(predicate)
} }
#[inline]
fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool
{
self.iter.position(predicate)
}
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]

View file

@ -462,7 +462,7 @@ impl<P: Deref<Target: Unpin>> Pin<P> {
/// can ignore the pinning invariants when unwrapping it. /// can ignore the pinning invariants when unwrapping it.
/// ///
/// [`Unpin`]: ../../std/marker/trait.Unpin.html /// [`Unpin`]: ../../std/marker/trait.Unpin.html
#[unstable(feature = "pin_into_inner", issue = "60245")] #[stable(feature = "pin_into_inner", since = "1.39.0")]
#[inline(always)] #[inline(always)]
pub fn into_inner(pin: Pin<P>) -> P { pub fn into_inner(pin: Pin<P>) -> P {
pin.pointer pin.pointer
@ -569,7 +569,7 @@ impl<P: Deref> Pin<P> {
/// ///
/// [`Unpin`]: ../../std/marker/trait.Unpin.html /// [`Unpin`]: ../../std/marker/trait.Unpin.html
/// [`Pin::into_inner`]: #method.into_inner /// [`Pin::into_inner`]: #method.into_inner
#[unstable(feature = "pin_into_inner", issue = "60245")] #[stable(feature = "pin_into_inner", since = "1.39.0")]
#[inline(always)] #[inline(always)]
pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P { pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
pin.pointer pin.pointer

View file

@ -1688,6 +1688,12 @@ fn test_rposition() {
assert!(v.iter().rposition(g).is_none()); assert!(v.iter().rposition(g).is_none());
} }
#[test]
fn test_rev_rposition() {
let v = [0, 0, 1, 1];
assert_eq!(v.iter().rev().rposition(|&x| x == 1), Some(1));
}
#[test] #[test]
#[should_panic] #[should_panic]
fn test_rposition_panic() { fn test_rposition_panic() {

View file

@ -39,7 +39,7 @@ Generally, `Self: Sized` is used to indicate that the trait should not be used
as a trait object. If the trait comes from your own crate, consider removing as a trait object. If the trait comes from your own crate, consider removing
this restriction. this restriction.
### Method references the `Self` type in its arguments or return type ### Method references the `Self` type in its parameters or return type
This happens when a trait has a method like the following: This happens when a trait has a method like the following:

View file

@ -186,7 +186,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
}); });
let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| { let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| {
let name = cstore.crate_name_untracked(cnum).as_str(); let name = cstore.crate_name_untracked(cnum).as_interned_str();
let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint(); let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
let hash = cstore.crate_hash_untracked(cnum); let hash = cstore.crate_hash_untracked(cnum);
(name, disambiguator, hash) (name, disambiguator, hash)

View file

@ -9,7 +9,7 @@ use std::mem;
use syntax::ast; use syntax::ast;
use syntax::feature_gate; use syntax::feature_gate;
use syntax::parse::token; use syntax::parse::token;
use syntax::symbol::{InternedString, LocalInternedString}; use syntax::symbol::InternedString;
use syntax::tokenstream; use syntax::tokenstream;
use syntax_pos::SourceFile; use syntax_pos::SourceFile;
@ -39,27 +39,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString {
} }
} }
impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let s: &str = &**self;
s.hash_stable(hcx, hasher);
}
}
impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
type KeyType = LocalInternedString;
#[inline]
fn to_stable_hash_key(&self,
_: &StableHashingContext<'a>)
-> LocalInternedString {
self.clone()
}
}
impl<'a> HashStable<StableHashingContext<'a>> for ast::Name { impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
#[inline] #[inline]
fn hash_stable<W: StableHasherResult>(&self, fn hash_stable<W: StableHasherResult>(&self,

View file

@ -1627,7 +1627,7 @@ impl<'tcx> ObligationCause<'tcx> {
MainFunctionType => Error0580("main function has wrong type"), MainFunctionType => Error0580("main function has wrong type"),
StartFunctionType => Error0308("start function has wrong type"), StartFunctionType => Error0308("start function has wrong type"),
IntrinsicType => Error0308("intrinsic has wrong type"), IntrinsicType => Error0308("intrinsic has wrong type"),
MethodReceiver => Error0308("mismatched method receiver"), MethodReceiver => Error0308("mismatched `self` parameter type"),
// In the case where we have no more specific thing to // In the case where we have no more specific thing to
// say, also take a look at the error code, maybe we can // say, also take a look at the error code, maybe we can

View file

@ -33,7 +33,7 @@ use crate::util::common::time;
use std::default::Default as StdDefault; use std::default::Default as StdDefault;
use syntax::ast; use syntax::ast;
use syntax::edition; use syntax::edition;
use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}}; use syntax_pos::{MultiSpan, Span, symbol::Symbol};
use errors::DiagnosticBuilder; use errors::DiagnosticBuilder;
use crate::hir; use crate::hir;
use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@ -405,7 +405,7 @@ impl LintStore {
pub fn check_lint_name( pub fn check_lint_name(
&self, &self,
lint_name: &str, lint_name: &str,
tool_name: Option<LocalInternedString>, tool_name: Option<Symbol>,
) -> CheckLintNameResult<'_> { ) -> CheckLintNameResult<'_> {
let complete_name = if let Some(tool_name) = tool_name { let complete_name = if let Some(tool_name) = tool_name {
format!("{}::{}", tool_name, lint_name) format!("{}::{}", tool_name, lint_name)

View file

@ -291,7 +291,7 @@ impl<'a> LintLevelsBuilder<'a> {
continue; continue;
} }
Some(tool_ident.as_str()) Some(tool_ident.name)
} else { } else {
None None
}; };

View file

@ -1808,6 +1808,23 @@ pub enum ProjectionElem<V, T> {
Downcast(Option<Symbol>, VariantIdx), Downcast(Option<Symbol>, VariantIdx),
} }
impl<V, T> ProjectionElem<V, T> {
/// Returns `true` if the target of this projection may refer to a different region of memory
/// than the base.
fn is_indirect(&self) -> bool {
match self {
Self::Deref => true,
| Self::Field(_, _)
| Self::Index(_)
| Self::ConstantIndex { .. }
| Self::Subslice { .. }
| Self::Downcast(_, _)
=> false
}
}
}
/// Alias for projections as they appear in places, where the base is a place /// Alias for projections as they appear in places, where the base is a place
/// and the index is a local. /// and the index is a local.
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>; pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
@ -1869,6 +1886,14 @@ impl<'tcx> Place<'tcx> {
} }
} }
/// Returns `true` if this `Place` contains a `Deref` projection.
///
/// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
/// same region of memory as its base.
pub fn is_indirect(&self) -> bool {
self.iterate(|_, mut projections| projections.any(|proj| proj.elem.is_indirect()))
}
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
/// a single deref of a local. /// a single deref of a local.
// //

View file

@ -1384,7 +1384,10 @@ impl<'tcx> TyCtxt<'tcx> {
let mut reported_violations = FxHashSet::default(); let mut reported_violations = FxHashSet::default();
for violation in violations { for violation in violations {
if reported_violations.insert(violation.clone()) { if reported_violations.insert(violation.clone()) {
err.note(&violation.error_msg()); match violation.span() {
Some(span) => err.span_label(span, violation.error_msg()),
None => err.note(&violation.error_msg()),
};
} }
} }
Some(err) Some(err)

View file

@ -20,7 +20,7 @@ use std::borrow::Cow;
use std::iter::{self}; use std::iter::{self};
use syntax::ast::{self}; use syntax::ast::{self};
use syntax::symbol::InternedString; use syntax::symbol::InternedString;
use syntax_pos::Span; use syntax_pos::{Span, DUMMY_SP};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ObjectSafetyViolation { pub enum ObjectSafetyViolation {
@ -32,10 +32,10 @@ pub enum ObjectSafetyViolation {
SupertraitSelf, SupertraitSelf,
/// Method has something illegal. /// Method has something illegal.
Method(ast::Name, MethodViolationCode), Method(ast::Name, MethodViolationCode, Span),
/// Associated const. /// Associated const.
AssocConst(ast::Name), AssocConst(ast::Name, Span),
} }
impl ObjectSafetyViolation { impl ObjectSafetyViolation {
@ -46,22 +46,35 @@ impl ObjectSafetyViolation {
ObjectSafetyViolation::SupertraitSelf => ObjectSafetyViolation::SupertraitSelf =>
"the trait cannot use `Self` as a type parameter \ "the trait cannot use `Self` as a type parameter \
in the supertraits or where-clauses".into(), in the supertraits or where-clauses".into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) => ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) =>
format!("method `{}` has no receiver", name).into(), format!("associated function `{}` has no `self` parameter", name).into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) => ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!(
format!("method `{}` references the `Self` type \ "method `{}` references the `Self` type in its parameters or return type",
in its arguments or return type", name).into(), name,
ObjectSafetyViolation::Method(name, ).into(),
MethodViolationCode::WhereClauseReferencesSelf(_)) => ObjectSafetyViolation::Method(
format!("method `{}` references the `Self` type in where clauses", name).into(), name,
ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) => MethodViolationCode::WhereClauseReferencesSelf,
_,
) => format!("method `{}` references the `Self` type in where clauses", name).into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) =>
format!("method `{}` has generic type parameters", name).into(), format!("method `{}` has generic type parameters", name).into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) => ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) =>
format!("method `{}`'s receiver cannot be dispatched on", name).into(), format!("method `{}`'s `self` parameter cannot be dispatched on", name).into(),
ObjectSafetyViolation::AssocConst(name) => ObjectSafetyViolation::AssocConst(name, _) =>
format!("the trait cannot contain associated consts like `{}`", name).into(), format!("the trait cannot contain associated consts like `{}`", name).into(),
} }
} }
pub fn span(&self) -> Option<Span> {
// When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so
// diagnostics use a `note` instead of a `span_label`.
match *self {
ObjectSafetyViolation::AssocConst(_, span) |
ObjectSafetyViolation::Method(_, _, span) if span != DUMMY_SP => Some(span),
_ => None,
}
}
} }
/// Reasons a method might not be object-safe. /// Reasons a method might not be object-safe.
@ -74,7 +87,7 @@ pub enum MethodViolationCode {
ReferencesSelf, ReferencesSelf,
/// e.g., `fn foo(&self) where Self: Clone` /// e.g., `fn foo(&self) where Self: Clone`
WhereClauseReferencesSelf(Span), WhereClauseReferencesSelf,
/// e.g., `fn foo<A>()` /// e.g., `fn foo<A>()`
Generic, Generic,
@ -88,9 +101,10 @@ impl<'tcx> TyCtxt<'tcx> {
/// astconv -- currently, `Self` in supertraits. This is needed /// astconv -- currently, `Self` in supertraits. This is needed
/// because `object_safety_violations` can't be used during /// because `object_safety_violations` can't be used during
/// type collection. /// type collection.
pub fn astconv_object_safety_violations(self, trait_def_id: DefId) pub fn astconv_object_safety_violations(
-> Vec<ObjectSafetyViolation> self,
{ trait_def_id: DefId,
) -> Vec<ObjectSafetyViolation> {
debug_assert!(self.generics_of(trait_def_id).has_self); debug_assert!(self.generics_of(trait_def_id).has_self);
let violations = traits::supertrait_def_ids(self, trait_def_id) let violations = traits::supertrait_def_ids(self, trait_def_id)
.filter(|&def_id| self.predicates_reference_self(def_id, true)) .filter(|&def_id| self.predicates_reference_self(def_id, true))
@ -128,7 +142,7 @@ impl<'tcx> TyCtxt<'tcx> {
} }
match self.virtual_call_violation_for_method(trait_def_id, method) { match self.virtual_call_violation_for_method(trait_def_id, method) {
None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true, None | Some(MethodViolationCode::WhereClauseReferencesSelf) => true,
Some(_) => false, Some(_) => false,
} }
} }
@ -138,12 +152,15 @@ impl<'tcx> TyCtxt<'tcx> {
let mut violations: Vec<_> = self.associated_items(trait_def_id) let mut violations: Vec<_> = self.associated_items(trait_def_id)
.filter(|item| item.kind == ty::AssocKind::Method) .filter(|item| item.kind == ty::AssocKind::Method)
.filter_map(|item| .filter_map(|item|
self.object_safety_violation_for_method(trait_def_id, &item) self.object_safety_violation_for_method(trait_def_id, &item).map(|code| {
.map(|code| ObjectSafetyViolation::Method(item.ident.name, code)) ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span)
})
).filter(|violation| { ).filter(|violation| {
if let ObjectSafetyViolation::Method(_, if let ObjectSafetyViolation::Method(
MethodViolationCode::WhereClauseReferencesSelf(span)) = violation _,
{ MethodViolationCode::WhereClauseReferencesSelf,
span,
) = violation {
// Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
// It's also hard to get a use site span, so we use the method definition span. // It's also hard to get a use site span, so we use the method definition span.
self.lint_node_note( self.lint_node_note(
@ -169,7 +186,7 @@ impl<'tcx> TyCtxt<'tcx> {
violations.extend(self.associated_items(trait_def_id) violations.extend(self.associated_items(trait_def_id)
.filter(|item| item.kind == ty::AssocKind::Const) .filter(|item| item.kind == ty::AssocKind::Const)
.map(|item| ObjectSafetyViolation::AssocConst(item.ident.name))); .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)));
debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}", debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
trait_def_id, trait_def_id,
@ -325,8 +342,7 @@ impl<'tcx> TyCtxt<'tcx> {
.visit_tys_shallow(|t| { .visit_tys_shallow(|t| {
self.contains_illegal_self_type_reference(trait_def_id, t) self.contains_illegal_self_type_reference(trait_def_id, t)
}) { }) {
let span = self.def_span(method.def_id); return Some(MethodViolationCode::WhereClauseReferencesSelf);
return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
} }
let receiver_ty = self.liberate_late_bound_regions( let receiver_ty = self.liberate_late_bound_regions(

View file

@ -9,10 +9,9 @@ use syntax::ast::{MetaItem, NestedMetaItem};
use syntax::attr; use syntax::attr;
use syntax::symbol::{Symbol, kw, sym}; use syntax::symbol::{Symbol, kw, sym};
use syntax_pos::Span; use syntax_pos::Span;
use syntax_pos::symbol::LocalInternedString;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct OnUnimplementedFormatString(LocalInternedString); pub struct OnUnimplementedFormatString(Symbol);
#[derive(Debug)] #[derive(Debug)]
pub struct OnUnimplementedDirective { pub struct OnUnimplementedDirective {
@ -89,19 +88,19 @@ impl<'tcx> OnUnimplementedDirective {
if item.check_name(sym::message) && message.is_none() { if item.check_name(sym::message) && message.is_none() {
if let Some(message_) = item.value_str() { if let Some(message_) = item.value_str() {
message = Some(OnUnimplementedFormatString::try_parse( message = Some(OnUnimplementedFormatString::try_parse(
tcx, trait_def_id, message_.as_str(), span)?); tcx, trait_def_id, message_, span)?);
continue; continue;
} }
} else if item.check_name(sym::label) && label.is_none() { } else if item.check_name(sym::label) && label.is_none() {
if let Some(label_) = item.value_str() { if let Some(label_) = item.value_str() {
label = Some(OnUnimplementedFormatString::try_parse( label = Some(OnUnimplementedFormatString::try_parse(
tcx, trait_def_id, label_.as_str(), span)?); tcx, trait_def_id, label_, span)?);
continue; continue;
} }
} else if item.check_name(sym::note) && note.is_none() { } else if item.check_name(sym::note) && note.is_none() {
if let Some(note_) = item.value_str() { if let Some(note_) = item.value_str() {
note = Some(OnUnimplementedFormatString::try_parse( note = Some(OnUnimplementedFormatString::try_parse(
tcx, trait_def_id, note_.as_str(), span)?); tcx, trait_def_id, note_, span)?);
continue; continue;
} }
} else if item.check_name(sym::on) && is_root && } else if item.check_name(sym::on) && is_root &&
@ -154,7 +153,7 @@ impl<'tcx> OnUnimplementedDirective {
message: None, message: None,
subcommands: vec![], subcommands: vec![],
label: Some(OnUnimplementedFormatString::try_parse( label: Some(OnUnimplementedFormatString::try_parse(
tcx, trait_def_id, value.as_str(), attr.span)?), tcx, trait_def_id, value, attr.span)?),
note: None, note: None,
})) }))
} else { } else {
@ -218,7 +217,7 @@ impl<'tcx> OnUnimplementedFormatString {
fn try_parse( fn try_parse(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
trait_def_id: DefId, trait_def_id: DefId,
from: LocalInternedString, from: Symbol,
err_sp: Span, err_sp: Span,
) -> Result<Self, ErrorReported> { ) -> Result<Self, ErrorReported> {
let result = OnUnimplementedFormatString(from); let result = OnUnimplementedFormatString(from);
@ -234,7 +233,8 @@ impl<'tcx> OnUnimplementedFormatString {
) -> Result<(), ErrorReported> { ) -> Result<(), ErrorReported> {
let name = tcx.item_name(trait_def_id); let name = tcx.item_name(trait_def_id);
let generics = tcx.generics_of(trait_def_id); let generics = tcx.generics_of(trait_def_id);
let parser = Parser::new(&self.0, None, vec![], false); let s = self.0.as_str();
let parser = Parser::new(&s, None, vec![], false);
let mut result = Ok(()); let mut result = Ok(());
for token in parser { for token in parser {
match token { match token {
@ -294,7 +294,8 @@ impl<'tcx> OnUnimplementedFormatString {
}).collect::<FxHashMap<Symbol, String>>(); }).collect::<FxHashMap<Symbol, String>>();
let empty_string = String::new(); let empty_string = String::new();
let parser = Parser::new(&self.0, None, vec![], false); let s = self.0.as_str();
let parser = Parser::new(&s, None, vec![], false);
parser.map(|p| parser.map(|p|
match p { match p {
Piece::String(s) => s, Piece::String(s) => s,

View file

@ -46,7 +46,7 @@ use std::ops::Range;
use syntax::ast::{self, Name, Ident, NodeId}; use syntax::ast::{self, Name, Ident, NodeId};
use syntax::attr; use syntax::attr;
use syntax::ext::hygiene::ExpnId; use syntax::ext::hygiene::ExpnId;
use syntax::symbol::{kw, sym, Symbol, LocalInternedString, InternedString}; use syntax::symbol::{kw, sym, Symbol, InternedString};
use syntax_pos::Span; use syntax_pos::Span;
use smallvec; use smallvec;
@ -3386,10 +3386,6 @@ impl SymbolName {
name: InternedString::intern(name) name: InternedString::intern(name)
} }
} }
pub fn as_str(&self) -> LocalInternedString {
self.name.as_str()
}
} }
impl fmt::Display for SymbolName { impl fmt::Display for SymbolName {

View file

@ -709,8 +709,10 @@ impl<'tcx> TyCtxt<'tcx> {
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
) -> Option<Ty<'tcx>> { ) -> Option<Ty<'tcx>> {
if self.found_recursion { if self.found_recursion {
None return None;
} else if self.seen_opaque_tys.insert(def_id) { }
let substs = substs.fold_with(self);
if self.seen_opaque_tys.insert(def_id) {
let generic_ty = self.tcx.type_of(def_id); let generic_ty = self.tcx.type_of(def_id);
let concrete_ty = generic_ty.subst(self.tcx, substs); let concrete_ty = generic_ty.subst(self.tcx, substs);
let expanded_ty = self.fold_ty(concrete_ty); let expanded_ty = self.fold_ty(concrete_ty);

View file

@ -5,7 +5,6 @@ use crate::context::CodegenCx;
use crate::type_::Type; use crate::type_::Type;
use crate::type_of::LayoutLlvmExt; use crate::type_of::LayoutLlvmExt;
use crate::value::Value; use crate::value::Value;
use syntax::symbol::LocalInternedString;
use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate};
use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::MemFlags;
use libc::{c_uint, c_char}; use libc::{c_uint, c_char};
@ -24,6 +23,7 @@ use std::ffi::CStr;
use std::ops::{Deref, Range}; use std::ops::{Deref, Range};
use std::ptr; use std::ptr;
use std::iter::TrustedLen; use std::iter::TrustedLen;
use syntax::symbol::Symbol;
// All Builders must have an llfn associated with them // All Builders must have an llfn associated with them
#[must_use] #[must_use]
@ -1082,8 +1082,8 @@ impl StaticBuilderMethods for Builder<'a, 'll, 'tcx> {
fn static_panic_msg( fn static_panic_msg(
&mut self, &mut self,
msg: Option<LocalInternedString>, msg: Option<Symbol>,
filename: LocalInternedString, filename: Symbol,
line: Self::Value, line: Self::Value,
col: Self::Value, col: Self::Value,
kind: &str, kind: &str,

View file

@ -37,7 +37,7 @@ pub fn get_fn(
return llfn; return llfn;
} }
let sym = tcx.symbol_name(instance).as_str(); let sym = tcx.symbol_name(instance).name.as_str();
debug!("get_fn({:?}: {:?}) => {}", instance, sig, sym); debug!("get_fn({:?}: {:?}) => {}", instance, sig, sym);
// Create a fn pointer with the substituted signature. // Create a fn pointer with the substituted signature.

View file

@ -17,7 +17,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
use libc::{c_uint, c_char}; use libc::{c_uint, c_char};
use syntax::symbol::LocalInternedString; use syntax::symbol::Symbol;
use syntax::ast::Mutability; use syntax::ast::Mutability;
pub use crate::context::CodegenCx; pub use crate::context::CodegenCx;
@ -122,7 +122,7 @@ impl CodegenCx<'ll, 'tcx> {
fn const_cstr( fn const_cstr(
&self, &self,
s: LocalInternedString, s: Symbol,
null_terminated: bool, null_terminated: bool,
) -> &'ll Value { ) -> &'ll Value {
unsafe { unsafe {
@ -130,9 +130,10 @@ impl CodegenCx<'ll, 'tcx> {
return llval; return llval;
} }
let s_str = s.as_str();
let sc = llvm::LLVMConstStringInContext(self.llcx, let sc = llvm::LLVMConstStringInContext(self.llcx,
s.as_ptr() as *const c_char, s_str.as_ptr() as *const c_char,
s.len() as c_uint, s_str.len() as c_uint,
!null_terminated as Bool); !null_terminated as Bool);
let sym = self.generate_local_symbol_name("str"); let sym = self.generate_local_symbol_name("str");
let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{ let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{
@ -147,8 +148,8 @@ impl CodegenCx<'ll, 'tcx> {
} }
} }
pub fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value { pub fn const_str_slice(&self, s: Symbol) -> &'ll Value {
let len = s.len(); let len = s.as_str().len();
let cs = consts::ptrcast(self.const_cstr(s, false), let cs = consts::ptrcast(self.const_cstr(s, false),
self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self))); self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)));
self.const_fat_ptr(cs, self.const_usize(len as u64)) self.const_fat_ptr(cs, self.const_usize(len as u64))

View file

@ -11,12 +11,11 @@ use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint,
Pointer, ErrorHandled, GlobalId}; Pointer, ErrorHandled, GlobalId};
use rustc::mir::mono::MonoItem; use rustc::mir::mono::MonoItem;
use rustc::hir::Node; use rustc::hir::Node;
use syntax_pos::Span;
use rustc_target::abi::HasDataLayout; use rustc_target::abi::HasDataLayout;
use syntax::symbol::sym;
use syntax_pos::symbol::LocalInternedString;
use rustc::ty::{self, Ty, Instance}; use rustc::ty::{self, Ty, Instance};
use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::traits::*;
use syntax::symbol::{Symbol, sym};
use syntax_pos::Span;
use rustc::ty::layout::{self, Size, Align, LayoutOf}; use rustc::ty::layout::{self, Size, Align, LayoutOf};
@ -122,10 +121,11 @@ fn check_and_apply_linkage(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
attrs: &CodegenFnAttrs, attrs: &CodegenFnAttrs,
ty: Ty<'tcx>, ty: Ty<'tcx>,
sym: LocalInternedString, sym: Symbol,
span: Span span: Span
) -> &'ll Value { ) -> &'ll Value {
let llty = cx.layout_of(ty).llvm_type(cx); let llty = cx.layout_of(ty).llvm_type(cx);
let sym = sym.as_str();
if let Some(linkage) = attrs.linkage { if let Some(linkage) = attrs.linkage {
debug!("get_static: sym={} linkage={:?}", sym, linkage); debug!("get_static: sym={} linkage={:?}", sym, linkage);
@ -221,7 +221,7 @@ impl CodegenCx<'ll, 'tcx> {
def_id); def_id);
let ty = instance.ty(self.tcx); let ty = instance.ty(self.tcx);
let sym = self.tcx.symbol_name(instance).as_str(); let sym = self.tcx.symbol_name(instance).name.as_symbol();
debug!("get_static: sym={} instance={:?}", sym, instance); debug!("get_static: sym={} instance={:?}", sym, instance);
@ -232,11 +232,12 @@ impl CodegenCx<'ll, 'tcx> {
Node::Item(&hir::Item { Node::Item(&hir::Item {
ref attrs, span, node: hir::ItemKind::Static(..), .. ref attrs, span, node: hir::ItemKind::Static(..), ..
}) => { }) => {
if self.get_declared_value(&sym[..]).is_some() { let sym_str = sym.as_str();
if self.get_declared_value(&sym_str).is_some() {
span_bug!(span, "Conflicting symbol names for static?"); span_bug!(span, "Conflicting symbol names for static?");
} }
let g = self.define_global(&sym[..], llty).unwrap(); let g = self.define_global(&sym_str, llty).unwrap();
if !self.tcx.is_reachable_non_generic(def_id) { if !self.tcx.is_reachable_non_generic(def_id) {
unsafe { unsafe {

View file

@ -29,7 +29,7 @@ use std::cell::{Cell, RefCell};
use std::iter; use std::iter;
use std::str; use std::str;
use std::sync::Arc; use std::sync::Arc;
use syntax::symbol::LocalInternedString; use syntax::symbol::Symbol;
use syntax::source_map::{DUMMY_SP, Span}; use syntax::source_map::{DUMMY_SP, Span};
use crate::abi::Abi; use crate::abi::Abi;
@ -52,7 +52,7 @@ pub struct CodegenCx<'ll, 'tcx> {
pub vtables: pub vtables:
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>, RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>,
/// Cache of constant strings, /// Cache of constant strings,
pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'ll Value>>, pub const_cstr_cache: RefCell<FxHashMap<Symbol, &'ll Value>>,
/// Reverse-direction for const ptrs cast from globals. /// Reverse-direction for const ptrs cast from globals.
/// Key is a Value holding a *T, /// Key is a Value holding a *T,

View file

@ -2251,7 +2251,7 @@ pub fn create_global_var_metadata(
None None
} else { } else {
let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id)); let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
Some(SmallCStr::new(&linkage_name.as_str())) Some(SmallCStr::new(&linkage_name.name.as_str()))
}; };
let global_align = cx.align_of(variable_type); let global_align = cx.align_of(variable_type);

View file

@ -290,7 +290,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let scope_line = span_start(self, span).line; let scope_line = span_start(self, span).line;
let function_name = CString::new(name).unwrap(); let function_name = CString::new(name).unwrap();
let linkage_name = SmallCStr::new(&linkage_name.as_str()); let linkage_name = SmallCStr::new(&linkage_name.name.as_str());
let mut flags = DIFlags::FlagPrototyped; let mut flags = DIFlags::FlagPrototyped;

View file

@ -121,7 +121,7 @@ fn reachable_non_generics_provider(
}) })
.map(|def_id| { .map(|def_id| {
let export_level = if special_runtime_crate { let export_level = if special_runtime_crate {
let name = tcx.symbol_name(Instance::mono(tcx, def_id)).as_str(); let name = tcx.symbol_name(Instance::mono(tcx, def_id)).name.as_str();
// We can probably do better here by just ensuring that // We can probably do better here by just ensuring that
// it has hidden visibility rather than public // it has hidden visibility rather than public
// visibility, as this is primarily here to ensure it's // visibility, as this is primarily here to ensure it's

View file

@ -14,7 +14,7 @@ use crate::traits::*;
use std::borrow::Cow; use std::borrow::Cow;
use syntax::symbol::LocalInternedString; use syntax::symbol::Symbol;
use syntax_pos::Pos; use syntax_pos::Pos;
use super::{FunctionCx, LocalRef}; use super::{FunctionCx, LocalRef};
@ -397,7 +397,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// Get the location information. // Get the location information.
let loc = bx.sess().source_map().lookup_char_pos(span.lo()); let loc = bx.sess().source_map().lookup_char_pos(span.lo());
let filename = LocalInternedString::intern(&loc.file.name.to_string()); let filename = Symbol::intern(&loc.file.name.to_string());
let line = bx.const_u32(loc.line as u32); let line = bx.const_u32(loc.line as u32);
let col = bx.const_u32(loc.col.to_usize() as u32 + 1); let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
@ -418,8 +418,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
vec![file_line_col, index, len]) vec![file_line_col, index, len])
} }
_ => { _ => {
let str = msg.description(); let msg_str = Symbol::intern(msg.description());
let msg_str = LocalInternedString::intern(str);
let msg_file_line_col = bx.static_panic_msg( let msg_file_line_col = bx.static_panic_msg(
Some(msg_str), Some(msg_str),
filename, filename,
@ -531,7 +530,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let layout = bx.layout_of(ty); let layout = bx.layout_of(ty);
if layout.abi.is_uninhabited() { if layout.abi.is_uninhabited() {
let loc = bx.sess().source_map().lookup_char_pos(span.lo()); let loc = bx.sess().source_map().lookup_char_pos(span.lo());
let filename = LocalInternedString::intern(&loc.file.name.to_string()); let filename = Symbol::intern(&loc.file.name.to_string());
let line = bx.const_u32(loc.line as u32); let line = bx.const_u32(loc.line as u32);
let col = bx.const_u32(loc.col.to_usize() as u32 + 1); let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
@ -539,7 +538,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
"Attempted to instantiate uninhabited type {}", "Attempted to instantiate uninhabited type {}",
ty ty
); );
let msg_str = LocalInternedString::intern(&str); let msg_str = Symbol::intern(&str);
let msg_file_line_col = bx.static_panic_msg( let msg_file_line_col = bx.static_panic_msg(
Some(msg_str), Some(msg_str),
filename, filename,

View file

@ -58,7 +58,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
self.to_raw_string(), self.to_raw_string(),
cx.codegen_unit().name()); cx.codegen_unit().name());
let symbol_name = self.symbol_name(cx.tcx()).as_str(); let symbol_name = self.symbol_name(cx.tcx()).name.as_str();
debug!("symbol {}", &symbol_name); debug!("symbol {}", &symbol_name);

View file

@ -1,5 +1,5 @@
use super::BackendTypes; use super::BackendTypes;
use syntax_pos::symbol::LocalInternedString; use syntax_pos::symbol::Symbol;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::ty::layout::Align; use rustc::ty::layout::Align;
@ -12,8 +12,8 @@ pub trait StaticBuilderMethods: BackendTypes {
fn get_static(&mut self, def_id: DefId) -> Self::Value; fn get_static(&mut self, def_id: DefId) -> Self::Value;
fn static_panic_msg( fn static_panic_msg(
&mut self, &mut self,
msg: Option<LocalInternedString>, msg: Option<Symbol>,
filename: LocalInternedString, filename: Symbol,
line: Self::Value, line: Self::Value,
col: Self::Value, col: Self::Value,
kind: &str, kind: &str,

View file

@ -40,7 +40,7 @@ impl SymbolNamesTest<'tcx> {
let instance = Instance::mono(tcx, def_id); let instance = Instance::mono(tcx, def_id);
let mangled = self.tcx.symbol_name(instance); let mangled = self.tcx.symbol_name(instance);
tcx.sess.span_err(attr.span, &format!("symbol-name({})", mangled)); tcx.sess.span_err(attr.span, &format!("symbol-name({})", mangled));
if let Ok(demangling) = rustc_demangle::try_demangle(&mangled.as_str()) { if let Ok(demangling) = rustc_demangle::try_demangle(&mangled.name.as_str()) {
tcx.sess.span_err(attr.span, &format!("demangling({})", demangling)); tcx.sess.span_err(attr.span, &format!("demangling({})", demangling));
tcx.sess.span_err(attr.span, &format!("demangling-alt({:#})", demangling)); tcx.sess.span_err(attr.span, &format!("demangling-alt({:#})", demangling));
} }

View file

@ -398,18 +398,37 @@ impl UnusedParens {
} }
} }
fn check_unused_parens_pat(&self, fn check_unused_parens_pat(
&self,
cx: &EarlyContext<'_>, cx: &EarlyContext<'_>,
value: &ast::Pat, value: &ast::Pat,
msg: &str) { avoid_or: bool,
if let ast::PatKind::Paren(_) = value.node { avoid_mut: bool,
) {
use ast::{PatKind, BindingMode::ByValue, Mutability::Mutable};
if let PatKind::Paren(inner) = &value.node {
match inner.node {
// The lint visitor will visit each subpattern of `p`. We do not want to lint
// any range pattern no matter where it occurs in the pattern. For something like
// `&(a..=b)`, there is a recursive `check_pat` on `a` and `b`, but we will assume
// that if there are unnecessary parens they serve a purpose of readability.
PatKind::Range(..) => return,
// Avoid `p0 | .. | pn` if we should.
PatKind::Or(..) if avoid_or => return,
// Avoid `mut x` and `mut x @ p` if we should:
PatKind::Ident(ByValue(Mutable), ..) if avoid_mut => return,
// Otherwise proceed with linting.
_ => {}
}
let pattern_text = if let Ok(snippet) = cx.sess().source_map() let pattern_text = if let Ok(snippet) = cx.sess().source_map()
.span_to_snippet(value.span) { .span_to_snippet(value.span) {
snippet snippet
} else { } else {
pprust::pat_to_string(value) pprust::pat_to_string(value)
}; };
Self::remove_outer_parens(cx, value.span, &pattern_text, msg, (false, false)); Self::remove_outer_parens(cx, value.span, &pattern_text, "pattern", (false, false));
} }
} }
@ -474,6 +493,13 @@ impl EarlyLintPass for UnusedParens {
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
use syntax::ast::ExprKind::*; use syntax::ast::ExprKind::*;
let (value, msg, followed_by_block, left_pos, right_pos) = match e.node { let (value, msg, followed_by_block, left_pos, right_pos) = match e.node {
Let(ref pats, ..) => {
for p in pats {
self.check_unused_parens_pat(cx, p, false, false);
}
return;
}
If(ref cond, ref block, ..) => { If(ref cond, ref block, ..) => {
let left = e.span.lo() + syntax_pos::BytePos(2); let left = e.span.lo() + syntax_pos::BytePos(2);
let right = block.span.lo(); let right = block.span.lo();
@ -486,7 +512,8 @@ impl EarlyLintPass for UnusedParens {
(cond, "`while` condition", true, Some(left), Some(right)) (cond, "`while` condition", true, Some(left), Some(right))
}, },
ForLoop(_, ref cond, ref block, ..) => { ForLoop(ref pat, ref cond, ref block, ..) => {
self.check_unused_parens_pat(cx, pat, false, false);
(cond, "`for` head expression", true, None, Some(block.span.lo())) (cond, "`for` head expression", true, None, Some(block.span.lo()))
} }
@ -531,26 +558,46 @@ impl EarlyLintPass for UnusedParens {
} }
fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) { fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
use ast::PatKind::{Paren, Range}; use ast::{PatKind::*, Mutability};
// The lint visitor will visit each subpattern of `p`. We do not want to lint any range match &p.node {
// pattern no matter where it occurs in the pattern. For something like `&(a..=b)`, there // Do not lint on `(..)` as that will result in the other arms being useless.
// is a recursive `check_pat` on `a` and `b`, but we will assume that if there are Paren(_)
// unnecessary parens they serve a purpose of readability. // The other cases do not contain sub-patterns.
if let Paren(ref pat) = p.node { | Wild | Rest | Lit(..) | Mac(..) | Range(..) | Ident(.., None) | Path(..) => return,
match pat.node { // These are list-like patterns; parens can always be removed.
Range(..) => {} TupleStruct(_, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
_ => self.check_unused_parens_pat(cx, &p, "pattern") self.check_unused_parens_pat(cx, p, false, false);
} },
Struct(_, fps, _) => for f in fps {
self.check_unused_parens_pat(cx, &f.pat, false, false);
},
// Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false),
// Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
// Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Immutable),
} }
} }
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) { fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
if let ast::StmtKind::Local(ref local) = s.node { if let ast::StmtKind::Local(ref local) = s.node {
self.check_unused_parens_pat(cx, &local.pat, false, false);
if let Some(ref value) = local.init { if let Some(ref value) = local.init {
self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None); self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None);
} }
} }
} }
fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) {
self.check_unused_parens_pat(cx, &param.pat, true, false);
}
fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
for p in &arm.pats {
self.check_unused_parens_pat(cx, p, false, false);
}
}
} }
declare_lint! { declare_lint! {

View file

@ -54,7 +54,7 @@ fn main() {
// LLVM are compiled the same way, but for us that's typically the case. // LLVM are compiled the same way, but for us that's typically the case.
// //
// We *want* detect this cross compiling situation by asking llvm-config // We *want* detect this cross compiling situation by asking llvm-config
// what it's host-target is. If that's not the TARGET, then we're cross // what its host-target is. If that's not the TARGET, then we're cross
// compiling. Unfortunately `llvm-config` seems either be buggy, or we're // compiling. Unfortunately `llvm-config` seems either be buggy, or we're
// misconfiguring it, because the `i686-pc-windows-gnu` build of LLVM will // misconfiguring it, because the `i686-pc-windows-gnu` build of LLVM will
// report itself with a `--host-target` of `x86_64-pc-windows-gnu`. This // report itself with a `--host-target` of `x86_64-pc-windows-gnu`. This
@ -62,7 +62,7 @@ fn main() {
// havoc ensues. // havoc ensues.
// //
// In any case, if we're cross compiling, this generally just means that we // In any case, if we're cross compiling, this generally just means that we
// can't trust all the output of llvm-config becaues it might be targeted // can't trust all the output of llvm-config because it might be targeted
// for the host rather than the target. As a result a bunch of blocks below // for the host rather than the target. As a result a bunch of blocks below
// are gated on `if !is_crossed` // are gated on `if !is_crossed`
let target = env::var("TARGET").expect("TARGET was not set"); let target = env::var("TARGET").expect("TARGET was not set");
@ -166,7 +166,7 @@ fn main() {
let (llvm_kind, llvm_link_arg) = detect_llvm_link(); let (llvm_kind, llvm_link_arg) = detect_llvm_link();
// Link in all LLVM libraries, if we're uwring the "wrong" llvm-config then // Link in all LLVM libraries, if we're using the "wrong" llvm-config then
// we don't pick up system libs because unfortunately they're for the host // we don't pick up system libs because unfortunately they're for the host
// of llvm-config, not the target that we're attempting to link. // of llvm-config, not the target that we're attempting to link.
let mut cmd = Command::new(&llvm_config); let mut cmd = Command::new(&llvm_config);

View file

@ -336,7 +336,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let local = &self.body.local_decls[local_index]; let local = &self.body.local_decls[local_index];
match local.name { match local.name {
Some(name) if !local.from_compiler_desugaring() => { Some(name) if !local.from_compiler_desugaring() => {
buf.push_str(name.as_str().get()); buf.push_str(&name.as_str());
Ok(()) Ok(())
} }
_ => Err(()), _ => Err(()),

View file

@ -3,7 +3,7 @@ use crate::borrow_check::places_conflict;
use crate::borrow_check::AccessDepth; use crate::borrow_check::AccessDepth;
use crate::dataflow::indexes::BorrowIndex; use crate::dataflow::indexes::BorrowIndex;
use rustc::mir::{BasicBlock, Location, Body, Place, PlaceBase}; use rustc::mir::{BasicBlock, Location, Body, Place, PlaceBase};
use rustc::mir::{ProjectionElem, BorrowKind}; use rustc::mir::BorrowKind;
use rustc::ty::{self, TyCtxt}; use rustc::ty::{self, TyCtxt};
use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::graph::dominators::Dominators;
@ -133,20 +133,11 @@ pub(super) fn is_active<'tcx>(
/// Determines if a given borrow is borrowing local data /// Determines if a given borrow is borrowing local data
/// This is called for all Yield statements on movable generators /// This is called for all Yield statements on movable generators
pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool { pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
place.iterate(|place_base, place_projection| { match place.base {
match place_base { PlaceBase::Static(_) => false,
PlaceBase::Static(..) => return false,
PlaceBase::Local(..) => {},
}
for proj in place_projection {
// Reborrow of already borrowed data is ignored // Reborrow of already borrowed data is ignored
// Any errors will be caught on the initial borrow // Any errors will be caught on the initial borrow
if proj.elem == ProjectionElem::Deref { PlaceBase::Local(_) => !place.is_indirect(),
return false;
} }
} }
true
})
}

View file

@ -93,21 +93,12 @@ struct BorrowedLocalsVisitor<'gk> {
} }
fn find_local(place: &Place<'_>) -> Option<Local> { fn find_local(place: &Place<'_>) -> Option<Local> {
place.iterate(|place_base, place_projection| { match place.base {
for proj in place_projection { PlaceBase::Local(local) if !place.is_indirect() => Some(local),
if proj.elem == ProjectionElem::Deref { _ => None,
return None;
} }
} }
if let PlaceBase::Local(local) = place_base {
Some(*local)
} else {
None
}
})
}
impl<'tcx> Visitor<'tcx> for BorrowedLocalsVisitor<'_> { impl<'tcx> Visitor<'tcx> for BorrowedLocalsVisitor<'_> {
fn visit_rvalue(&mut self, fn visit_rvalue(&mut self,
rvalue: &Rvalue<'tcx>, rvalue: &Rvalue<'tcx>,

View file

@ -777,7 +777,7 @@ where
debug!("CodegenUnit {}:", cgu.name()); debug!("CodegenUnit {}:", cgu.name());
for (mono_item, linkage) in cgu.items() { for (mono_item, linkage) in cgu.items() {
let symbol_name = mono_item.symbol_name(tcx).as_str(); let symbol_name = mono_item.symbol_name(tcx).name.as_str();
let symbol_hash_start = symbol_name.rfind('h'); let symbol_hash_start = symbol_name.rfind('h');
let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..]) let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..])
.unwrap_or("<no hash>"); .unwrap_or("<no hash>");

View file

@ -19,7 +19,7 @@ use crate::astconv::AstConv as _;
use errors::{Applicability, DiagnosticBuilder}; use errors::{Applicability, DiagnosticBuilder};
use syntax::ast; use syntax::ast;
use syntax::symbol::{Symbol, LocalInternedString, kw, sym}; use syntax::symbol::{Symbol, kw, sym};
use syntax::source_map::Span; use syntax::source_map::Span;
use syntax::util::lev_distance::find_best_match_for_name; use syntax::util::lev_distance::find_best_match_for_name;
use rustc::hir; use rustc::hir;
@ -1244,7 +1244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
_ => { _ => {
// prevent all specified fields from being suggested // prevent all specified fields from being suggested
let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str()); let skip_fields = skip_fields.iter().map(|ref x| x.ident.name);
if let Some(field_name) = Self::suggest_field_name( if let Some(field_name) = Self::suggest_field_name(
variant, variant,
&field.ident.as_str(), &field.ident.as_str(),
@ -1288,11 +1288,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Return an hint about the closest match in field names // Return an hint about the closest match in field names
fn suggest_field_name(variant: &'tcx ty::VariantDef, fn suggest_field_name(variant: &'tcx ty::VariantDef,
field: &str, field: &str,
skip: Vec<LocalInternedString>) skip: Vec<Symbol>)
-> Option<Symbol> { -> Option<Symbol> {
let names = variant.fields.iter().filter_map(|field| { let names = variant.fields.iter().filter_map(|field| {
// ignore already set fields and private fields from non-local crates // ignore already set fields and private fields from non-local crates
if skip.iter().any(|x| *x == field.ident.as_str()) || if skip.iter().any(|&x| x == field.ident.name) ||
(!variant.def_id.is_local() && field.vis != Visibility::Public) (!variant.def_id.is_local() && field.vis != Visibility::Public)
{ {
None None

View file

@ -1420,8 +1420,8 @@ fn check_opaque_for_cycles<'tcx>(
tcx.sess, span, E0733, tcx.sess, span, E0733,
"recursion in an `async fn` requires boxing", "recursion in an `async fn` requires boxing",
) )
.span_label(span, "an `async fn` cannot invoke itself directly") .span_label(span, "recursive `async fn`")
.note("a recursive `async fn` must be rewritten to return a boxed future.") .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
.emit(); .emit();
} else { } else {
let mut err = struct_span_err!( let mut err = struct_span_err!(

View file

@ -762,19 +762,19 @@ fn check_opaque_types<'fcx, 'tcx>(
substituted_predicates substituted_predicates
} }
const HELP_FOR_SELF_TYPE: &str =
"consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
`self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
of the previous types except `Self`)";
fn check_method_receiver<'fcx, 'tcx>( fn check_method_receiver<'fcx, 'tcx>(
fcx: &FnCtxt<'fcx, 'tcx>, fcx: &FnCtxt<'fcx, 'tcx>,
method_sig: &hir::MethodSig, method_sig: &hir::MethodSig,
method: &ty::AssocItem, method: &ty::AssocItem,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
) { ) {
const HELP_FOR_SELF_TYPE: &str =
"consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
`self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
of the previous types except `Self`)";
// Check that the method has a valid receiver type, given the type `Self`. // Check that the method has a valid receiver type, given the type `Self`.
debug!("check_method_receiver({:?}, self_ty={:?})", debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty);
method, self_ty);
if !method.method_has_self_argument { if !method.method_has_self_argument {
return; return;
@ -805,12 +805,7 @@ fn check_method_receiver<'fcx, 'tcx>(
if fcx.tcx.features().arbitrary_self_types { if fcx.tcx.features().arbitrary_self_types {
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) { if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
// Report error; `arbitrary_self_types` was enabled. // Report error; `arbitrary_self_types` was enabled.
fcx.tcx.sess.diagnostic().mut_span_err( e0307(fcx, span, receiver_ty);
span, &format!("invalid method receiver type: {:?}", receiver_ty)
).note("type of `self` must be `Self` or a type that dereferences to it")
.help(HELP_FOR_SELF_TYPE)
.code(DiagnosticId::Error("E0307".into()))
.emit();
} }
} else { } else {
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) { if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) {
@ -830,16 +825,21 @@ fn check_method_receiver<'fcx, 'tcx>(
.emit(); .emit();
} else { } else {
// Report error; would not have worked with `arbitrary_self_types`. // Report error; would not have worked with `arbitrary_self_types`.
e0307(fcx, span, receiver_ty);
}
}
}
}
fn e0307(fcx: &FnCtxt<'fcx, 'tcx>, span: Span, receiver_ty: Ty<'_>) {
fcx.tcx.sess.diagnostic().mut_span_err( fcx.tcx.sess.diagnostic().mut_span_err(
span, &format!("invalid method receiver type: {:?}", receiver_ty) span,
).note("type must be `Self` or a type that dereferences to it") &format!("invalid `self` parameter type: {:?}", receiver_ty)
).note("type of `self` must be `Self` or a type that dereferences to it")
.help(HELP_FOR_SELF_TYPE) .help(HELP_FOR_SELF_TYPE)
.code(DiagnosticId::Error("E0307".into())) .code(DiagnosticId::Error("E0307".into()))
.emit(); .emit();
} }
}
}
}
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
/// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly

View file

@ -212,7 +212,7 @@ match string {
E0033: r##" E0033: r##"
This error indicates that a pointer to a trait type cannot be implicitly This error indicates that a pointer to a trait type cannot be implicitly
dereferenced by a pattern. Every trait defines a type, but because the dereferenced by a pattern. Every trait defines a type, but because the
size of trait implementors isn't fixed, this type has no compile-time size. size of trait implementers isn't fixed, this type has no compile-time size.
Therefore, all accesses to trait types must be through pointers. If you Therefore, all accesses to trait types must be through pointers. If you
encounter this error you should try to avoid dereferencing the pointer. encounter this error you should try to avoid dereferencing the pointer.
@ -2425,6 +2425,87 @@ struct Bar<S, T> { x: Foo<S, T> }
``` ```
"##, "##,
E0307: r##"
This error indicates that the `self` parameter in a method has an invalid
"reciever type".
Methods take a special first parameter, of which there are three variants:
`self`, `&self`, and `&mut self`. These are syntactic sugar for
`self: Self`, `self: &Self`, and `self: &mut Self` respectively.
```
# struct Foo;
trait Trait {
fn foo(&self);
// ^^^^^ `self` here is a reference to the receiver object
}
impl Trait for Foo {
fn foo(&self) {}
// ^^^^^ the receiver type is `&Foo`
}
```
The type `Self` acts as an alias to the type of the current trait
implementer, or "receiver type". Besides the already mentioned `Self`,
`&Self` and `&mut Self` valid receiver types, the following are also valid:
`self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, and `self: Pin<P>`
(where P is one of the previous types except `Self`). Note that `Self` can
also be the underlying implementing type, like `Foo` in the following
example:
```
# struct Foo;
# trait Trait {
# fn foo(&self);
# }
impl Trait for Foo {
fn foo(self: &Foo) {}
}
```
E0307 will be emitted by the compiler when using an invalid reciver type,
like in the following example:
```compile_fail,E0307
# struct Foo;
# struct Bar;
# trait Trait {
# fn foo(&self);
# }
impl Trait for Foo {
fn foo(self: &Bar) {}
}
```
The nightly feature [Arbintrary self types][AST] extends the accepted
set of receiver types to also include any type that can dereference to
`Self`:
```
#![feature(arbitrary_self_types)]
struct Foo;
struct Bar;
// Because you can dereference `Bar` into `Foo`...
impl std::ops::Deref for Bar {
type Target = Foo;
fn deref(&self) -> &Foo {
&Foo
}
}
impl Foo {
fn foo(self: Bar) {}
// ^^^^^^^^^ ...it can be used as the receiver type
}
```
[AST]: https://doc.rust-lang.org/unstable-book/language-features/arbitrary-self-types.html
"##,
E0321: r##" E0321: r##"
A cross-crate opt-out trait was implemented on something which wasn't a struct A cross-crate opt-out trait was implemented on something which wasn't a struct
or enum type. Erroneous code example: or enum type. Erroneous code example:
@ -4851,7 +4932,6 @@ register_diagnostics! {
// E0247, // E0247,
// E0248, // value used as a type, now reported earlier during resolution as E0412 // E0248, // value used as a type, now reported earlier during resolution as E0412
// E0249, // E0249,
E0307, // invalid method `self` type
// E0319, // trait impls for defaulted traits allowed just for structs/enums // E0319, // trait impls for defaulted traits allowed just for structs/enums
// E0372, // coherence not object safe // E0372, // coherence not object safe
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion E0377, // the trait `CoerceUnsized` may only be implemented for a coercion

View file

@ -371,6 +371,14 @@ where
loop { loop {
if g.len == g.buf.len() { if g.len == g.buf.len() {
unsafe { unsafe {
// FIXME(danielhenrymantilla): #42788
//
// - This creates a (mut) reference to a slice of
// _uninitialized_ integers, which is **undefined behavior**
//
// - Only the standard library gets to soundly "ignore" this,
// based on its privileged knowledge of unstable rustc
// internals;
g.buf.reserve(reservation_size(r)); g.buf.reserve(reservation_size(r));
let capacity = g.buf.capacity(); let capacity = g.buf.capacity();
g.buf.set_len(capacity); g.buf.set_len(capacity);

View file

@ -244,7 +244,6 @@
#![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic)]
#![feature(cfg_target_thread_local)] #![feature(cfg_target_thread_local)]
#![feature(char_error_internals)] #![feature(char_error_internals)]
#![feature(checked_duration_since)]
#![feature(clamp)] #![feature(clamp)]
#![feature(compiler_builtins_lib)] #![feature(compiler_builtins_lib)]
#![feature(concat_idents)] #![feature(concat_idents)]

View file

@ -221,7 +221,6 @@ impl Instant {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// #![feature(checked_duration_since)]
/// use std::time::{Duration, Instant}; /// use std::time::{Duration, Instant};
/// use std::thread::sleep; /// use std::thread::sleep;
/// ///
@ -231,7 +230,7 @@ impl Instant {
/// println!("{:?}", new_now.checked_duration_since(now)); /// println!("{:?}", new_now.checked_duration_since(now));
/// println!("{:?}", now.checked_duration_since(new_now)); // None /// println!("{:?}", now.checked_duration_since(new_now)); // None
/// ``` /// ```
#[unstable(feature = "checked_duration_since", issue = "58402")] #[stable(feature = "checked_duration_since", since = "1.39.0")]
pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> { pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
self.0.checked_sub_instant(&earlier.0) self.0.checked_sub_instant(&earlier.0)
} }
@ -242,7 +241,6 @@ impl Instant {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// #![feature(checked_duration_since)]
/// use std::time::{Duration, Instant}; /// use std::time::{Duration, Instant};
/// use std::thread::sleep; /// use std::thread::sleep;
/// ///
@ -252,7 +250,7 @@ impl Instant {
/// println!("{:?}", new_now.saturating_duration_since(now)); /// println!("{:?}", new_now.saturating_duration_since(now));
/// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns /// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns
/// ``` /// ```
#[unstable(feature = "checked_duration_since", issue = "58402")] #[stable(feature = "checked_duration_since", since = "1.39.0")]
pub fn saturating_duration_since(&self, earlier: Instant) -> Duration { pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
self.checked_duration_since(earlier).unwrap_or(Duration::new(0, 0)) self.checked_duration_since(earlier).unwrap_or(Duration::new(0, 0))
} }

View file

@ -889,6 +889,36 @@ impl<'a> Parser<'a> {
hi = path.span; hi = path.span;
return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs)); return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs));
} }
if self.token.is_path_start() {
let path = self.parse_path(PathStyle::Expr)?;
// `!`, as an operator, is prefix, so we know this isn't that
if self.eat(&token::Not) {
// MACRO INVOCATION expression
let (delim, tts) = self.expect_delimited_token_tree()?;
hi = self.prev_span;
ex = ExprKind::Mac(Mac {
path,
tts,
delim,
span: lo.to(hi),
prior_type_ascription: self.last_type_ascription,
});
} else if self.check(&token::OpenDelim(token::Brace)) {
if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
return expr;
} else {
hi = path.span;
ex = ExprKind::Path(None, path);
}
} else {
hi = path.span;
ex = ExprKind::Path(None, path);
}
let expr = self.mk_expr(lo.to(hi), ex, attrs);
return self.maybe_recover_from_bad_qpath(expr, true);
}
if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) { if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
return self.parse_lambda_expr(attrs); return self.parse_lambda_expr(attrs);
} }
@ -1007,32 +1037,6 @@ impl<'a> Parser<'a> {
let (await_hi, e_kind) = self.parse_incorrect_await_syntax(lo, self.prev_span)?; let (await_hi, e_kind) = self.parse_incorrect_await_syntax(lo, self.prev_span)?;
hi = await_hi; hi = await_hi;
ex = e_kind; ex = e_kind;
} else if self.token.is_path_start() {
let path = self.parse_path(PathStyle::Expr)?;
// `!`, as an operator, is prefix, so we know this isn't that
if self.eat(&token::Not) {
// MACRO INVOCATION expression
let (delim, tts) = self.expect_delimited_token_tree()?;
hi = self.prev_span;
ex = ExprKind::Mac(Mac {
path,
tts,
delim,
span: lo.to(hi),
prior_type_ascription: self.last_type_ascription,
});
} else if self.check(&token::OpenDelim(token::Brace)) {
if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
return expr;
} else {
hi = path.span;
ex = ExprKind::Path(None, path);
}
} else {
hi = path.span;
ex = ExprKind::Path(None, path);
}
} else { } else {
if !self.unclosed_delims.is_empty() && self.check(&token::Semi) { if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
// Don't complain about bare semicolons after unclosed braces // Don't complain about bare semicolons after unclosed braces

View file

@ -818,10 +818,14 @@ impl Ident {
with_interner(|interner| interner.is_gensymed(self.name)) with_interner(|interner| interner.is_gensymed(self.name))
} }
/// Convert the name to a `LocalInternedString`. This is a slowish
/// operation because it requires locking the symbol interner.
pub fn as_str(self) -> LocalInternedString { pub fn as_str(self) -> LocalInternedString {
self.name.as_str() self.name.as_str()
} }
/// Convert the name to an `InternedString`. This is a slowish operation
/// because it requires locking the symbol interner.
pub fn as_interned_str(self) -> InternedString { pub fn as_interned_str(self) -> InternedString {
self.name.as_interned_str() self.name.as_interned_str()
} }
@ -916,6 +920,25 @@ impl Symbol {
with_interner(|interner| interner.intern(string)) with_interner(|interner| interner.intern(string))
} }
/// Access the symbol's chars. This is a slowish operation because it
/// requires locking the symbol interner.
pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
with_interner(|interner| {
f(interner.get(self))
})
}
/// Access two symbols' chars. This is a slowish operation because it
/// requires locking the symbol interner, but it is faster than calling
/// `with()` twice.
fn with2<F: FnOnce(&str, &str) -> R, R>(self, other: Symbol, f: F) -> R {
with_interner(|interner| {
f(interner.get(self), interner.get(other))
})
}
/// Convert to a `LocalInternedString`. This is a slowish operation because
/// it requires locking the symbol interner.
pub fn as_str(self) -> LocalInternedString { pub fn as_str(self) -> LocalInternedString {
with_interner(|interner| unsafe { with_interner(|interner| unsafe {
LocalInternedString { LocalInternedString {
@ -924,6 +947,8 @@ impl Symbol {
}) })
} }
/// Convert to an `InternedString`. This is a slowish operation because it
/// requires locking the symbol interner.
pub fn as_interned_str(self) -> InternedString { pub fn as_interned_str(self) -> InternedString {
with_interner(|interner| InternedString { with_interner(|interner| InternedString {
symbol: interner.interned(self) symbol: interner.interned(self)
@ -1152,39 +1177,11 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
// FIXME: ensure that the interner outlives any thread which uses // FIXME: ensure that the interner outlives any thread which uses
// `LocalInternedString`, by creating a new thread right after constructing the // `LocalInternedString`, by creating a new thread right after constructing the
// interner. // interner.
#[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)] #[derive(Clone, Copy, Eq, PartialOrd, Ord)]
pub struct LocalInternedString { pub struct LocalInternedString {
string: &'static str, string: &'static str,
} }
impl LocalInternedString {
/// Maps a string to its interned representation.
pub fn intern(string: &str) -> Self {
let string = with_interner(|interner| {
let symbol = interner.intern(string);
interner.strings[symbol.0.as_usize()]
});
LocalInternedString {
string: unsafe { std::mem::transmute::<&str, &str>(string) }
}
}
pub fn as_interned_str(self) -> InternedString {
InternedString {
symbol: Symbol::intern(self.string)
}
}
#[inline]
pub fn get(&self) -> &str {
// This returns a valid string since we ensure that `self` outlives the interner
// by creating the interner on a thread which outlives threads which can access it.
// This type cannot move to a thread which outlives the interner since it does
// not implement Send.
self.string
}
}
impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString
where where
str: std::convert::AsRef<U> str: std::convert::AsRef<U>
@ -1246,18 +1243,6 @@ impl fmt::Display for LocalInternedString {
} }
} }
impl Decodable for LocalInternedString {
fn decode<D: Decoder>(d: &mut D) -> Result<LocalInternedString, D::Error> {
Ok(LocalInternedString::intern(&d.read_str()?))
}
}
impl Encodable for LocalInternedString {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_str(self.string)
}
}
/// An alternative to `Symbol` that is focused on string contents. It has two /// An alternative to `Symbol` that is focused on string contents. It has two
/// main differences to `Symbol`. /// main differences to `Symbol`.
/// ///
@ -1285,28 +1270,19 @@ impl InternedString {
} }
pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R { pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
let str = with_interner(|interner| { self.symbol.with(f)
interner.get(self.symbol) as *const str
});
// This is safe because the interner keeps string alive until it is dropped.
// We can access it because we know the interner is still alive since we use a
// scoped thread local to access it, and it was alive at the beginning of this scope
unsafe { f(&*str) }
} }
fn with2<F: FnOnce(&str, &str) -> R, R>(self, other: &InternedString, f: F) -> R { fn with2<F: FnOnce(&str, &str) -> R, R>(self, other: &InternedString, f: F) -> R {
let (self_str, other_str) = with_interner(|interner| { self.symbol.with2(other.symbol, f)
(interner.get(self.symbol) as *const str,
interner.get(other.symbol) as *const str)
});
// This is safe for the same reason that `with` is safe.
unsafe { f(&*self_str, &*other_str) }
} }
pub fn as_symbol(self) -> Symbol { pub fn as_symbol(self) -> Symbol {
self.symbol self.symbol
} }
/// Convert to a `LocalInternedString`. This is a slowish operation because it
/// requires locking the symbol interner.
pub fn as_str(self) -> LocalInternedString { pub fn as_str(self) -> LocalInternedString {
self.symbol.as_str() self.symbol.as_str()
} }

View file

@ -1,10 +1,11 @@
error[E0038]: the trait `Trait` cannot be made into an object error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/associated-const-in-trait.rs:9:6 --> $DIR/associated-const-in-trait.rs:9:6
| |
LL | const N: usize;
| - the trait cannot contain associated consts like `N`
...
LL | impl dyn Trait { LL | impl dyn Trait {
| ^^^^^^^^^ the trait `Trait` cannot be made into an object | ^^^^^^^^^ the trait `Trait` cannot be made into an object
|
= note: the trait cannot contain associated consts like `N`
error: aborting due to previous error error: aborting due to previous error

View file

@ -0,0 +1,13 @@
// edition:2018
// Test that impl trait does not allow creating recursive types that are
// otherwise forbidden when using `async` and `await`.
async fn rec_1() { //~ ERROR recursion in an `async fn`
rec_2().await;
}
async fn rec_2() { //~ ERROR recursion in an `async fn`
rec_1().await;
}
fn main() {}

View file

@ -0,0 +1,19 @@
error[E0733]: recursion in an `async fn` requires boxing
--> $DIR/mutually-recursive-async-impl-trait-type.rs:5:18
|
LL | async fn rec_1() {
| ^ recursive `async fn`
|
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
error[E0733]: recursion in an `async fn` requires boxing
--> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18
|
LL | async fn rec_2() {
| ^ recursive `async fn`
|
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0733`.

View file

@ -2,9 +2,9 @@ error[E0733]: recursion in an `async fn` requires boxing
--> $DIR/recursive-async-impl-trait-type.rs:5:40 --> $DIR/recursive-async-impl-trait-type.rs:5:40
| |
LL | async fn recursive_async_function() -> () { LL | async fn recursive_async_function() -> () {
| ^^ an `async fn` cannot invoke itself directly | ^^ recursive `async fn`
| |
= note: a recursive `async fn` must be rewritten to return a boxed future. = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,10 +1,10 @@
error[E0038]: the trait `NotObjectSafe` cannot be made into an object error[E0038]: the trait `NotObjectSafe` cannot be made into an object
--> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6 --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
| |
LL | trait NotObjectSafe { fn eq(&self, other: Self); }
| -- method `eq` references the `Self` type in its parameters or return type
LL | impl NotObjectSafe for dyn NotObjectSafe { } LL | impl NotObjectSafe for dyn NotObjectSafe { }
| ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object | ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
|
= note: method `eq` references the `Self` type in its arguments or return type
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,10 +1,10 @@
error[E0038]: the trait `NotObjectSafe` cannot be made into an object error[E0038]: the trait `NotObjectSafe` cannot be made into an object
--> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6 --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
| |
LL | trait NotObjectSafe { fn eq(&self, other: Self); }
| -- method `eq` references the `Self` type in its parameters or return type
LL | impl NotObjectSafe for dyn NotObjectSafe { } LL | impl NotObjectSafe for dyn NotObjectSafe { }
| ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object | ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
|
= note: method `eq` references the `Self` type in its arguments or return type
error: aborting due to previous error error: aborting due to previous error

View file

@ -61,8 +61,9 @@ error[E0038]: the trait `X` cannot be made into an object
| |
LL | impl dyn X { LL | impl dyn X {
| ^^^^^ the trait `X` cannot be made into an object | ^^^^^ the trait `X` cannot be made into an object
| ...
= note: method `xxx` has no receiver LL | fn xxx() { ### }
| --- associated function `xxx` has no `self` parameter
error: aborting due to 9 previous errors error: aborting due to 9 previous errors

View file

@ -1,14 +1,13 @@
// compile-flags: -Z teach // compile-flags: -Z teach
trait SomeTrait { trait SomeTrait {
fn foo(); fn foo(); //~ associated function `foo` has no `self` parameter
} }
fn main() { fn main() {
let trait_obj: &dyn SomeTrait = SomeTrait; let trait_obj: &dyn SomeTrait = SomeTrait;
//~^ ERROR expected value, found trait `SomeTrait` //~^ ERROR expected value, found trait `SomeTrait`
//~| ERROR E0038 //~| ERROR E0038
//~| method `foo` has no receiver
let &invalid = trait_obj; let &invalid = trait_obj;
//~^ ERROR E0033 //~^ ERROR E0033

View file

@ -7,13 +7,14 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait;
error[E0038]: the trait `SomeTrait` cannot be made into an object error[E0038]: the trait `SomeTrait` cannot be made into an object
--> $DIR/E0033-teach.rs:8:20 --> $DIR/E0033-teach.rs:8:20
| |
LL | fn foo();
| --- associated function `foo` has no `self` parameter
...
LL | let trait_obj: &dyn SomeTrait = SomeTrait; LL | let trait_obj: &dyn SomeTrait = SomeTrait;
| ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
|
= note: method `foo` has no receiver
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
--> $DIR/E0033-teach.rs:13:9 --> $DIR/E0033-teach.rs:12:9
| |
LL | let &invalid = trait_obj; LL | let &invalid = trait_obj;
| ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced | ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced

View file

@ -1,12 +1,11 @@
trait SomeTrait { trait SomeTrait {
fn foo(); fn foo(); //~ associated function `foo` has no `self` parameter
} }
fn main() { fn main() {
let trait_obj: &dyn SomeTrait = SomeTrait; let trait_obj: &dyn SomeTrait = SomeTrait;
//~^ ERROR expected value, found trait `SomeTrait` //~^ ERROR expected value, found trait `SomeTrait`
//~| ERROR E0038 //~| ERROR E0038
//~| method `foo` has no receiver
let &invalid = trait_obj; let &invalid = trait_obj;
//~^ ERROR E0033 //~^ ERROR E0033

View file

@ -7,13 +7,14 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait;
error[E0038]: the trait `SomeTrait` cannot be made into an object error[E0038]: the trait `SomeTrait` cannot be made into an object
--> $DIR/E0033.rs:6:20 --> $DIR/E0033.rs:6:20
| |
LL | fn foo();
| --- associated function `foo` has no `self` parameter
...
LL | let trait_obj: &dyn SomeTrait = SomeTrait; LL | let trait_obj: &dyn SomeTrait = SomeTrait;
| ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
|
= note: method `foo` has no receiver
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
--> $DIR/E0033.rs:11:9 --> $DIR/E0033.rs:10:9
| |
LL | let &invalid = trait_obj; LL | let &invalid = trait_obj;
| ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced | ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced

View file

@ -1,10 +1,11 @@
error[E0038]: the trait `Trait` cannot be made into an object error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/E0038.rs:5:1 --> $DIR/E0038.rs:5:1
| |
LL | fn foo(&self) -> Self;
| --- method `foo` references the `Self` type in its parameters or return type
...
LL | fn call_foo(x: Box<dyn Trait>) { LL | fn call_foo(x: Box<dyn Trait>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
= note: method `foo` references the `Self` type in its arguments or return type
error: aborting due to previous error error: aborting due to previous error

View file

@ -6,11 +6,11 @@ struct Foo<'a,'b> {
impl<'a,'b> Foo<'a,'b> { impl<'a,'b> Foo<'a,'b> {
fn bar(self: fn bar(self:
Foo<'b,'a> Foo<'b,'a>
//~^ ERROR mismatched method receiver //~^ ERROR mismatched `self` parameter type
//~| expected type `Foo<'a, 'b>` //~| expected type `Foo<'a, 'b>`
//~| found type `Foo<'b, 'a>` //~| found type `Foo<'b, 'a>`
//~| lifetime mismatch //~| lifetime mismatch
//~| ERROR mismatched method receiver //~| ERROR mismatched `self` parameter type
//~| expected type `Foo<'a, 'b>` //~| expected type `Foo<'a, 'b>`
//~| found type `Foo<'b, 'a>` //~| found type `Foo<'b, 'a>`
//~| lifetime mismatch //~| lifetime mismatch

View file

@ -1,4 +1,4 @@
error[E0308]: mismatched method receiver error[E0308]: mismatched `self` parameter type
--> $DIR/explicit-self-lifetime-mismatch.rs:8:12 --> $DIR/explicit-self-lifetime-mismatch.rs:8:12
| |
LL | Foo<'b,'a> LL | Foo<'b,'a>
@ -17,7 +17,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
LL | impl<'a,'b> Foo<'a,'b> { LL | impl<'a,'b> Foo<'a,'b> {
| ^^ | ^^
error[E0308]: mismatched method receiver error[E0308]: mismatched `self` parameter type
--> $DIR/explicit-self-lifetime-mismatch.rs:8:12 --> $DIR/explicit-self-lifetime-mismatch.rs:8:12
| |
LL | Foo<'b,'a> LL | Foo<'b,'a>

View file

@ -0,0 +1,25 @@
// Test that impl trait does not allow creating recursive types that are
// otherwise forbidden. Even when there's an opaque type in another crate
// hiding this.
fn id<T>(t: T) -> impl Sized { t }
fn recursive_id() -> impl Sized { //~ ERROR opaque type expands to a recursive type
id(recursive_id2())
}
fn recursive_id2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
id(recursive_id())
}
fn wrap<T>(t: T) -> impl Sized { (t,) }
fn recursive_wrap() -> impl Sized { //~ ERROR opaque type expands to a recursive type
wrap(recursive_wrap2())
}
fn recursive_wrap2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
wrap(recursive_wrap())
}
fn main() {}

View file

@ -0,0 +1,35 @@
error[E0720]: opaque type expands to a recursive type
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:7:22
|
LL | fn recursive_id() -> impl Sized {
| ^^^^^^^^^^ expands to a recursive type
|
= note: type resolves to itself
error[E0720]: opaque type expands to a recursive type
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:11:23
|
LL | fn recursive_id2() -> impl Sized {
| ^^^^^^^^^^ expands to a recursive type
|
= note: type resolves to itself
error[E0720]: opaque type expands to a recursive type
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:17:24
|
LL | fn recursive_wrap() -> impl Sized {
| ^^^^^^^^^^ expands to a recursive type
|
= note: expanded type is `((impl Sized,),)`
error[E0720]: opaque type expands to a recursive type
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:21:25
|
LL | fn recursive_wrap2() -> impl Sized {
| ^^^^^^^^^^ expands to a recursive type
|
= note: expanded type is `((impl Sized,),)`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0720`.

View file

@ -4,11 +4,11 @@ struct Foo<'a> {
impl <'a> Foo<'a>{ impl <'a> Foo<'a>{
fn bar(self: &mut Foo) { fn bar(self: &mut Foo) {
//~^ mismatched method receiver //~^ mismatched `self` parameter type
//~| expected type `Foo<'a>` //~| expected type `Foo<'a>`
//~| found type `Foo<'_>` //~| found type `Foo<'_>`
//~| lifetime mismatch //~| lifetime mismatch
//~| mismatched method receiver //~| mismatched `self` parameter type
//~| expected type `Foo<'a>` //~| expected type `Foo<'a>`
//~| found type `Foo<'_>` //~| found type `Foo<'_>`
//~| lifetime mismatch //~| lifetime mismatch

View file

@ -1,4 +1,4 @@
error[E0308]: mismatched method receiver error[E0308]: mismatched `self` parameter type
--> $DIR/issue-17740.rs:6:18 --> $DIR/issue-17740.rs:6:18
| |
LL | fn bar(self: &mut Foo) { LL | fn bar(self: &mut Foo) {
@ -23,7 +23,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
LL | impl <'a> Foo<'a>{ LL | impl <'a> Foo<'a>{
| ^^ | ^^
error[E0308]: mismatched method receiver error[E0308]: mismatched `self` parameter type
--> $DIR/issue-17740.rs:6:18 --> $DIR/issue-17740.rs:6:18
| |
LL | fn bar(self: &mut Foo) { LL | fn bar(self: &mut Foo) {

View file

@ -6,8 +6,8 @@ impl Pair<
isize isize
> { > {
fn say(self: &Pair<&str, isize>) { fn say(self: &Pair<&str, isize>) {
//~^ ERROR mismatched method receiver //~^ ERROR mismatched `self` parameter type
//~| ERROR mismatched method receiver //~| ERROR mismatched `self` parameter type
println!("{:?}", self); println!("{:?}", self);
} }
} }

View file

@ -1,4 +1,4 @@
error[E0308]: mismatched method receiver error[E0308]: mismatched `self` parameter type
--> $DIR/issue-17905-2.rs:8:18 --> $DIR/issue-17905-2.rs:8:18
| |
LL | fn say(self: &Pair<&str, isize>) { LL | fn say(self: &Pair<&str, isize>) {
@ -21,7 +21,7 @@ note: ...does not necessarily outlive the lifetime '_ as defined on the impl at
LL | &str, LL | &str,
| ^ | ^
error[E0308]: mismatched method receiver error[E0308]: mismatched `self` parameter type
--> $DIR/issue-17905-2.rs:8:18 --> $DIR/issue-17905-2.rs:8:18
| |
LL | fn say(self: &Pair<&str, isize>) { LL | fn say(self: &Pair<&str, isize>) {

View file

@ -1,10 +1,11 @@
error[E0038]: the trait `Bar` cannot be made into an object error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/issue-18959.rs:11:1 --> $DIR/issue-18959.rs:11:1
| |
LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
| --- method `foo` has generic type parameters
...
LL | fn foo(b: &dyn Bar) { LL | fn foo(b: &dyn Bar) {
| ^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object | ^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
|
= note: method `foo` has generic type parameters
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,10 +1,11 @@
error[E0038]: the trait `Qiz` cannot be made into an object error[E0038]: the trait `Qiz` cannot be made into an object
--> $DIR/issue-19380.rs:11:3 --> $DIR/issue-19380.rs:11:3
| |
LL | fn qiz();
| --- associated function `qiz` has no `self` parameter
...
LL | foos: &'static [&'static (dyn Qiz + 'static)] LL | foos: &'static [&'static (dyn Qiz + 'static)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
|
= note: method `qiz` has no receiver
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,18 +1,21 @@
error[E0038]: the trait `Bar` cannot be made into an object error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/issue-19538.rs:17:15 --> $DIR/issue-19538.rs:17:15
| |
LL | fn foo<T>(&self, val: T);
| --- method `foo` has generic type parameters
...
LL | let test: &mut dyn Bar = &mut thing; LL | let test: &mut dyn Bar = &mut thing;
| ^^^^^^^^^^^^ the trait `Bar` cannot be made into an object | ^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
|
= note: method `foo` has generic type parameters
error[E0038]: the trait `Bar` cannot be made into an object error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/issue-19538.rs:17:30 --> $DIR/issue-19538.rs:17:30
| |
LL | fn foo<T>(&self, val: T);
| --- method `foo` has generic type parameters
...
LL | let test: &mut dyn Bar = &mut thing; LL | let test: &mut dyn Bar = &mut thing;
| ^^^^^^^^^^ the trait `Bar` cannot be made into an object | ^^^^^^^^^^ the trait `Bar` cannot be made into an object
| |
= note: method `foo` has generic type parameters
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&mut dyn Bar>` for `&mut Thing` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -1,8 +1,8 @@
error: the trait `X` cannot be made into an object error: the trait `X` cannot be made into an object
--> $DIR/issue-50781.rs:6:5 --> $DIR/issue-50781.rs:6:8
| |
LL | fn foo(&self) where Self: Trait; LL | fn foo(&self) where Self: Trait;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^
| |
note: lint level defined here note: lint level defined here
--> $DIR/issue-50781.rs:1:9 --> $DIR/issue-50781.rs:1:9

View file

@ -1,7 +1,6 @@
pub trait Trait { pub trait Trait {
fn dyn_instead_of_self(self: Box<dyn Trait>); fn dyn_instead_of_self(self: Box<dyn Trait>);
//~^ ERROR invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)> //~^ ERROR invalid `self` parameter type
} }
pub fn main() { pub fn main() {}
}

View file

@ -1,11 +1,12 @@
error[E0307]: invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)> error[E0307]: invalid `self` parameter type: std::boxed::Box<(dyn Trait + 'static)>
--> $DIR/issue-56806.rs:2:34 --> $DIR/issue-56806.rs:2:34
| |
LL | fn dyn_instead_of_self(self: Box<dyn Trait>); LL | fn dyn_instead_of_self(self: Box<dyn Trait>);
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
| |
= note: type must be `Self` or a type that dereferences to it = note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0307`.

View file

@ -1,23 +1,73 @@
// build-pass (FIXME(62277): could be check-pass?) #![feature(box_patterns)]
#![feature(or_patterns)]
//~^ WARN the feature `or_patterns` is incomplete
#![allow(ellipsis_inclusive_range_patterns)] #![allow(ellipsis_inclusive_range_patterns)]
#![allow(unreachable_patterns)] #![allow(unreachable_patterns)]
#![allow(unused_variables)] #![allow(unused_variables)]
#![warn(unused_parens)] #![deny(unused_parens)]
fn lint_on_top_level() {
let (a) = 0; //~ ERROR unnecessary parentheses around pattern
for (a) in 0..1 {} //~ ERROR unnecessary parentheses around pattern
if let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern
while let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern
fn foo((a): u8) {} //~ ERROR unnecessary parentheses around pattern
let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern
}
// Don't lint in these cases (#64106).
fn or_patterns_no_lint() {
match Box::new(0) {
box (0 | 1) => {} // Should not lint as `box 0 | 1` binds as `(box 0) | 1`.
_ => {}
}
match 0 {
x @ (0 | 1) => {} // Should not lint as `x @ 0 | 1` binds as `(x @ 0) | 1`.
_ => {}
}
if let &(0 | 1) = &0 {} // Should also not lint.
if let &mut (0 | 1) = &mut 0 {} // Same.
fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
//~^ ERROR identifier `a` is bound more than once
let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
//~^ ERROR identifier `a` is bound more than once
}
fn or_patterns_will_lint() {
if let (0 | 1) = 0 {} //~ ERROR unnecessary parentheses around pattern
if let ((0 | 1),) = (0,) {} //~ ERROR unnecessary parentheses around pattern
if let [(0 | 1)] = [0] {} //~ ERROR unnecessary parentheses around pattern
if let 0 | (1 | 2) = 0 {} //~ ERROR unnecessary parentheses around pattern
struct TS(u8);
if let TS((0 | 1)) = TS(0) {} //~ ERROR unnecessary parentheses around pattern
struct NS { f: u8 }
if let NS { f: (0 | 1) } = (NS { f: 0 }) {} //~ ERROR unnecessary parentheses around pattern
}
// Don't lint on `&(mut x)` because `&mut x` means something else (#55342).
fn deref_mut_binding_no_lint() {
let &(mut x) = &0;
}
fn main() { fn main() {
match 1 { match 1 {
(_) => {} //~ WARNING: unnecessary parentheses around pattern (_) => {} //~ ERROR unnecessary parentheses around pattern
(y) => {} //~ WARNING: unnecessary parentheses around pattern (y) => {} //~ ERROR unnecessary parentheses around pattern
(ref r) => {} //~ WARNING: unnecessary parentheses around pattern (ref r) => {} //~ ERROR unnecessary parentheses around pattern
(e @ 1...2) => {} //~ WARNING: unnecessary parentheses around outer pattern (e @ 1...2) => {} //~ ERROR unnecessary parentheses around pattern
(1...2) => {} // Non ambiguous range pattern should not warn (1...2) => {} // Non ambiguous range pattern should not warn
e @ (3...4) => {} // Non ambiguous range pattern should not warn e @ (3...4) => {} // Non ambiguous range pattern should not warn
} }
match &1 { match &1 {
(e @ &(1...2)) => {} //~ WARNING: unnecessary parentheses around outer pattern (e @ &(1...2)) => {} //~ ERROR unnecessary parentheses around pattern
&(_) => {} //~ WARNING: unnecessary parentheses around pattern &(_) => {} //~ ERROR unnecessary parentheses around pattern
e @ &(1...2) => {} // Ambiguous range pattern should not warn e @ &(1...2) => {} // Ambiguous range pattern should not warn
&(1...2) => {} // Ambiguous range pattern should not warn &(1...2) => {} // Ambiguous range pattern should not warn
} }
@ -28,17 +78,17 @@ fn main() {
} }
match 1 { match 1 {
(_) => {} //~ WARNING: unnecessary parentheses around pattern (_) => {} //~ ERROR unnecessary parentheses around pattern
(y) => {} //~ WARNING: unnecessary parentheses around pattern (y) => {} //~ ERROR unnecessary parentheses around pattern
(ref r) => {} //~ WARNING: unnecessary parentheses around pattern (ref r) => {} //~ ERROR unnecessary parentheses around pattern
(e @ 1..=2) => {} //~ WARNING: unnecessary parentheses around outer pattern (e @ 1..=2) => {} //~ ERROR unnecessary parentheses around pattern
(1..=2) => {} // Non ambiguous range pattern should not warn (1..=2) => {} // Non ambiguous range pattern should not warn
e @ (3..=4) => {} // Non ambiguous range pattern should not warn e @ (3..=4) => {} // Non ambiguous range pattern should not warn
} }
match &1 { match &1 {
(e @ &(1..=2)) => {} //~ WARNING: unnecessary parentheses around outer pattern (e @ &(1..=2)) => {} //~ ERROR unnecessary parentheses around pattern
&(_) => {} //~ WARNING: unnecessary parentheses around pattern &(_) => {} //~ ERROR unnecessary parentheses around pattern
e @ &(1..=2) => {} // Ambiguous range pattern should not warn e @ &(1..=2) => {} // Ambiguous range pattern should not warn
&(1..=2) => {} // Ambiguous range pattern should not warn &(1..=2) => {} // Ambiguous range pattern should not warn
} }

View file

@ -1,78 +1,173 @@
warning: unnecessary parentheses around pattern error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/issue-54538-unused-parens-lint.rs:10:9 --> $DIR/issue-54538-unused-parens-lint.rs:35:25
| |
LL | (_) => {} LL | fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
| ^ used in a pattern more than once
error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/issue-54538-unused-parens-lint.rs:38:27
|
LL | let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
| ^ used in a pattern more than once
warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
--> $DIR/issue-54538-unused-parens-lint.rs:3:12
|
LL | #![feature(or_patterns)]
| ^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:12:9
|
LL | let (a) = 0;
| ^^^ help: remove these parentheses | ^^^ help: remove these parentheses
| |
note: lint level defined here note: lint level defined here
--> $DIR/issue-54538-unused-parens-lint.rs:6:9 --> $DIR/issue-54538-unused-parens-lint.rs:9:9
| |
LL | #![warn(unused_parens)] LL | #![deny(unused_parens)]
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:11:9 --> $DIR/issue-54538-unused-parens-lint.rs:13:9
|
LL | for (a) in 0..1 {}
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:14:12
|
LL | if let (a) = 0 {}
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:15:15
|
LL | while let (a) = 0 {}
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:16:12
|
LL | fn foo((a): u8) {}
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:17:14
|
LL | let _ = |(a): u8| 0;
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:43:12
|
LL | if let (0 | 1) = 0 {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:44:13
|
LL | if let ((0 | 1),) = (0,) {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:45:13
|
LL | if let [(0 | 1)] = [0] {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:46:16
|
LL | if let 0 | (1 | 2) = 0 {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:48:15
|
LL | if let TS((0 | 1)) = TS(0) {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:50:20
|
LL | if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:60:9
|
LL | (_) => {}
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:61:9
| |
LL | (y) => {} LL | (y) => {}
| ^^^ help: remove these parentheses | ^^^ help: remove these parentheses
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:12:9 --> $DIR/issue-54538-unused-parens-lint.rs:62:9
| |
LL | (ref r) => {} LL | (ref r) => {}
| ^^^^^^^ help: remove these parentheses | ^^^^^^^ help: remove these parentheses
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:13:9 --> $DIR/issue-54538-unused-parens-lint.rs:63:9
| |
LL | (e @ 1...2) => {} LL | (e @ 1...2) => {}
| ^^^^^^^^^^^ help: remove these parentheses | ^^^^^^^^^^^ help: remove these parentheses
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:19:9 --> $DIR/issue-54538-unused-parens-lint.rs:69:9
| |
LL | (e @ &(1...2)) => {} LL | (e @ &(1...2)) => {}
| ^^^^^^^^^^^^^^ help: remove these parentheses | ^^^^^^^^^^^^^^ help: remove these parentheses
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:20:10 --> $DIR/issue-54538-unused-parens-lint.rs:70:10
| |
LL | &(_) => {} LL | &(_) => {}
| ^^^ help: remove these parentheses | ^^^ help: remove these parentheses
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:31:9 --> $DIR/issue-54538-unused-parens-lint.rs:81:9
| |
LL | (_) => {} LL | (_) => {}
| ^^^ help: remove these parentheses | ^^^ help: remove these parentheses
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:32:9 --> $DIR/issue-54538-unused-parens-lint.rs:82:9
| |
LL | (y) => {} LL | (y) => {}
| ^^^ help: remove these parentheses | ^^^ help: remove these parentheses
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:33:9 --> $DIR/issue-54538-unused-parens-lint.rs:83:9
| |
LL | (ref r) => {} LL | (ref r) => {}
| ^^^^^^^ help: remove these parentheses | ^^^^^^^ help: remove these parentheses
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:34:9 --> $DIR/issue-54538-unused-parens-lint.rs:84:9
| |
LL | (e @ 1..=2) => {} LL | (e @ 1..=2) => {}
| ^^^^^^^^^^^ help: remove these parentheses | ^^^^^^^^^^^ help: remove these parentheses
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:40:9 --> $DIR/issue-54538-unused-parens-lint.rs:90:9
| |
LL | (e @ &(1..=2)) => {} LL | (e @ &(1..=2)) => {}
| ^^^^^^^^^^^^^^ help: remove these parentheses | ^^^^^^^^^^^^^^ help: remove these parentheses
warning: unnecessary parentheses around pattern error: unnecessary parentheses around pattern
--> $DIR/issue-54538-unused-parens-lint.rs:41:10 --> $DIR/issue-54538-unused-parens-lint.rs:91:10
| |
LL | &(_) => {} LL | &(_) => {}
| ^^^ help: remove these parentheses | ^^^ help: remove these parentheses
error: aborting due to 26 previous errors
For more information about this error, try `rustc --explain E0416`.

View file

@ -1,10 +1,11 @@
error[E0038]: the trait `Bar` cannot be made into an object error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/object-safety-associated-consts.rs:9:1 --> $DIR/object-safety-associated-consts.rs:9:1
| |
LL | const X: usize;
| - the trait cannot contain associated consts like `X`
...
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
|
= note: the trait cannot contain associated consts like `X`
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,18 +1,20 @@
error[E0038]: the trait `Bar` cannot be made into an object error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/object-safety-generics.rs:14:1 --> $DIR/object-safety-generics.rs:14:1
| |
LL | fn bar<T>(&self, t: T);
| --- method `bar` has generic type parameters
...
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
|
= note: method `bar` has generic type parameters
error[E0038]: the trait `Bar` cannot be made into an object error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/object-safety-generics.rs:19:1 --> $DIR/object-safety-generics.rs:19:1
| |
LL | fn bar<T>(&self, t: T);
| --- method `bar` has generic type parameters
...
LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar { LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
|
= note: method `bar` has generic type parameters
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -1,18 +1,20 @@
error[E0038]: the trait `Bar` cannot be made into an object error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/object-safety-mentions-Self.rs:17:1 --> $DIR/object-safety-mentions-Self.rs:17:1
| |
LL | fn bar(&self, x: &Self);
| --- method `bar` references the `Self` type in its parameters or return type
...
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar { LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
|
= note: method `bar` references the `Self` type in its arguments or return type
error[E0038]: the trait `Baz` cannot be made into an object error[E0038]: the trait `Baz` cannot be made into an object
--> $DIR/object-safety-mentions-Self.rs:22:1 --> $DIR/object-safety-mentions-Self.rs:22:1
| |
LL | fn bar(&self) -> Self;
| --- method `bar` references the `Self` type in its parameters or return type
...
LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz { LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object
|
= note: method `bar` references the `Self` type in its arguments or return type
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -1,10 +1,11 @@
error[E0038]: the trait `Foo` cannot be made into an object error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/object-safety-no-static.rs:8:1 --> $DIR/object-safety-no-static.rs:8:1
| |
LL | fn foo();
| --- associated function `foo` has no `self` parameter
...
LL | fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<dyn Foo + 'static> { LL | fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<dyn Foo + 'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
= note: method `foo` has no receiver
error: aborting due to previous error error: aborting due to previous error

View file

@ -4,7 +4,7 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
LL | fn bar(_x: Foo) {} LL | fn bar(_x: Foo) {}
| ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
| |
= note: method `bar` has no receiver = note: associated function `bar` has no `self` parameter
error: aborting due to previous error error: aborting due to previous error

View file

@ -0,0 +1,11 @@
// force-host
// no-prefer-dynamic
#![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn id(_: TokenStream, input: TokenStream) -> TokenStream { input }

View file

@ -0,0 +1,60 @@
// aux-build:ident-mac.rs
#![feature(param_attrs)]
#![feature(c_variadic)]
extern crate ident_mac;
use ident_mac::id;
struct W(u8);
extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
//~^ ERROR the attribute `id` is currently unknown to the compiler
type Alias = extern "C" fn(#[id] u8, #[id] ...);
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
fn free(#[id] arg1: u8) {
//~^ ERROR the attribute `id` is currently unknown to the compiler
let lam = |#[id] W(x), #[id] y| ();
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
}
impl W {
fn inherent1(#[id] self, #[id] arg1: u8) {}
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
fn inherent2(#[id] &self, #[id] arg1: u8) {}
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
}
trait A {
fn trait1(#[id] self, #[id] arg1: u8);
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
fn trait2(#[id] &self, #[id] arg1: u8);
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
//~^ ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
//~| ERROR the attribute `id` is currently unknown to the compiler
}
fn main() {}

View file

@ -0,0 +1,228 @@
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:11:21
|
LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:11:38
|
LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:15:38
|
LL | unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:18:28
|
LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:18:38
|
LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:22:9
|
LL | fn free(#[id] arg1: u8) {
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:24:16
|
LL | let lam = |#[id] W(x), #[id] y| ();
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:24:28
|
LL | let lam = |#[id] W(x), #[id] y| ();
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:30:18
|
LL | fn inherent1(#[id] self, #[id] arg1: u8) {}
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:30:30
|
LL | fn inherent1(#[id] self, #[id] arg1: u8) {}
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:33:18
|
LL | fn inherent2(#[id] &self, #[id] arg1: u8) {}
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:33:31
|
LL | fn inherent2(#[id] &self, #[id] arg1: u8) {}
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:36:22
|
LL | fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:36:42
|
LL | fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:39:22
|
LL | fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:39:45
|
LL | fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:45:15
|
LL | fn trait1(#[id] self, #[id] arg1: u8);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:45:27
|
LL | fn trait1(#[id] self, #[id] arg1: u8);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:48:15
|
LL | fn trait2(#[id] &self, #[id] arg1: u8);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:48:28
|
LL | fn trait2(#[id] &self, #[id] arg1: u8);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:51:19
|
LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:51:39
|
LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:54:19
|
LL | fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:54:42
|
LL | fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/proc-macro-cannot-be-used.rs:54:58
|
LL | fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(custom_attribute)]` to the crate attributes to enable
error: aborting due to 25 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,18 +1,21 @@
error[E0038]: the trait `Foo` cannot be made into an object error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/arbitrary-self-types-not-object-safe.rs:31:32 --> $DIR/arbitrary-self-types-not-object-safe.rs:31:32
| |
LL | fn foo(self: &Rc<Self>) -> usize;
| --- method `foo`'s `self` parameter cannot be dispatched on
...
LL | let x = Rc::new(5usize) as Rc<dyn Foo>; LL | let x = Rc::new(5usize) as Rc<dyn Foo>;
| ^^^^^^^^^^^ the trait `Foo` cannot be made into an object | ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
= note: method `foo`'s receiver cannot be dispatched on
error[E0038]: the trait `Foo` cannot be made into an object error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/arbitrary-self-types-not-object-safe.rs:31:13 --> $DIR/arbitrary-self-types-not-object-safe.rs:31:13
| |
LL | fn foo(self: &Rc<Self>) -> usize;
| --- method `foo`'s `self` parameter cannot be dispatched on
...
LL | let x = Rc::new(5usize) as Rc<dyn Foo>; LL | let x = Rc::new(5usize) as Rc<dyn Foo>;
| ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
| |
= note: method `foo`'s receiver cannot be dispatched on
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -3,7 +3,7 @@
struct SomeType {} struct SomeType {}
trait Foo { trait Foo {
fn handler(self: &SomeType); //~ ERROR invalid method receiver type fn handler(self: &SomeType); //~ ERROR invalid `self` parameter type
} }
fn main() {} fn main() {}

View file

@ -1,11 +1,12 @@
error[E0307]: invalid method receiver type: &SomeType error[E0307]: invalid `self` parameter type: &SomeType
--> $DIR/issue-27522.rs:6:22 --> $DIR/issue-27522.rs:6:22
| |
LL | fn handler(self: &SomeType); LL | fn handler(self: &SomeType);
| ^^^^^^^^^ | ^^^^^^^^^
| |
= note: type must be `Self` or a type that dereferences to it = note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0307`.

View file

@ -110,12 +110,17 @@ LL | C::A;
error[E0038]: the trait `assoc_const::C` cannot be made into an object error[E0038]: the trait `assoc_const::C` cannot be made into an object
--> $DIR/trait-item-privacy.rs:101:5 --> $DIR/trait-item-privacy.rs:101:5
| |
LL | const A: u8 = 0;
| - the trait cannot contain associated consts like `A`
...
LL | const B: u8 = 0;
| - the trait cannot contain associated consts like `B`
...
LL | const C: u8 = 0;
| - the trait cannot contain associated consts like `C`
...
LL | C::A; LL | C::A;
| ^^^^ the trait `assoc_const::C` cannot be made into an object | ^^^^ the trait `assoc_const::C` cannot be made into an object
|
= note: the trait cannot contain associated consts like `C`
= note: the trait cannot contain associated consts like `B`
= note: the trait cannot contain associated consts like `A`
error[E0223]: ambiguous associated type error[E0223]: ambiguous associated type
--> $DIR/trait-item-privacy.rs:115:12 --> $DIR/trait-item-privacy.rs:115:12

View file

@ -1,19 +1,22 @@
error[E0038]: the trait `Tr` cannot be made into an object error[E0038]: the trait `Tr` cannot be made into an object
--> $DIR/trait-object-safety.rs:15:22 --> $DIR/trait-object-safety.rs:15:22
| |
LL | fn foo();
| --- associated function `foo` has no `self` parameter
...
LL | let _: &dyn Tr = &St; LL | let _: &dyn Tr = &St;
| ^^^ the trait `Tr` cannot be made into an object | ^^^ the trait `Tr` cannot be made into an object
| |
= note: method `foo` has no receiver
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St`
error[E0038]: the trait `Tr` cannot be made into an object error[E0038]: the trait `Tr` cannot be made into an object
--> $DIR/trait-object-safety.rs:15:12 --> $DIR/trait-object-safety.rs:15:12
| |
LL | fn foo();
| --- associated function `foo` has no `self` parameter
...
LL | let _: &dyn Tr = &St; LL | let _: &dyn Tr = &St;
| ^^^^^^^ the trait `Tr` cannot be made into an object | ^^^^^^^ the trait `Tr` cannot be made into an object
|
= note: method `foo` has no receiver
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -13,20 +13,25 @@ LL | 10.blah::<i32, i32>();
error[E0038]: the trait `bar` cannot be made into an object error[E0038]: the trait `bar` cannot be made into an object
--> $DIR/trait-test-2.rs:11:16 --> $DIR/trait-test-2.rs:11:16
| |
LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
| --- ---- method `blah` has generic type parameters
| |
| method `dup` references the `Self` type in its parameters or return type
...
LL | (box 10 as Box<dyn bar>).dup(); LL | (box 10 as Box<dyn bar>).dup();
| ^^^^^^^^^^^^ the trait `bar` cannot be made into an object | ^^^^^^^^^^^^ the trait `bar` cannot be made into an object
|
= note: method `dup` references the `Self` type in its arguments or return type
= note: method `blah` has generic type parameters
error[E0038]: the trait `bar` cannot be made into an object error[E0038]: the trait `bar` cannot be made into an object
--> $DIR/trait-test-2.rs:11:6 --> $DIR/trait-test-2.rs:11:6
| |
LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
| --- ---- method `blah` has generic type parameters
| |
| method `dup` references the `Self` type in its parameters or return type
...
LL | (box 10 as Box<dyn bar>).dup(); LL | (box 10 as Box<dyn bar>).dup();
| ^^^^^^ the trait `bar` cannot be made into an object | ^^^^^^ the trait `bar` cannot be made into an object
| |
= note: method `dup` references the `Self` type in its arguments or return type
= note: method `blah` has generic type parameters
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn bar>>` for `std::boxed::Box<{integer}>` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn bar>>` for `std::boxed::Box<{integer}>`
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -13,10 +13,11 @@ LL | let y = x as dyn MyAdd<i32>;
error[E0038]: the trait `MyAdd` cannot be made into an object error[E0038]: the trait `MyAdd` cannot be made into an object
--> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18 --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18
| |
LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
| --- method `add` references the `Self` type in its parameters or return type
...
LL | let y = x as dyn MyAdd<i32>; LL | let y = x as dyn MyAdd<i32>;
| ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object | ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object
|
= note: method `add` references the `Self` type in its arguments or return type
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -6,7 +6,7 @@ struct Foo {
impl Foo { impl Foo {
fn foo(self: isize, x: isize) -> isize { fn foo(self: isize, x: isize) -> isize {
//~^ ERROR invalid method receiver type //~^ ERROR invalid `self` parameter type
self.f + x self.f + x
} }
} }
@ -17,11 +17,11 @@ struct Bar<T> {
impl<T> Bar<T> { impl<T> Bar<T> {
fn foo(self: Bar<isize>, x: isize) -> isize { fn foo(self: Bar<isize>, x: isize) -> isize {
//~^ ERROR invalid method receiver type //~^ ERROR invalid `self` parameter type
x x
} }
fn bar(self: &Bar<usize>, x: isize) -> isize { fn bar(self: &Bar<usize>, x: isize) -> isize {
//~^ ERROR invalid method receiver type //~^ ERROR invalid `self` parameter type
x x
} }
} }
@ -34,14 +34,14 @@ trait SomeTrait {
impl<'a, T> SomeTrait for &'a Bar<T> { impl<'a, T> SomeTrait for &'a Bar<T> {
fn dummy1(self: &&'a Bar<T>) { } fn dummy1(self: &&'a Bar<T>) { }
fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched method receiver fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched `self` parameter type
//~^ ERROR mismatched method receiver //~^ ERROR mismatched `self` parameter type
fn dummy3(self: &&Bar<T>) {} fn dummy3(self: &&Bar<T>) {}
//~^ ERROR mismatched method receiver //~^ ERROR mismatched `self` parameter type
//~| expected type `&'a Bar<T>` //~| expected type `&'a Bar<T>`
//~| found type `&Bar<T>` //~| found type `&Bar<T>`
//~| lifetime mismatch //~| lifetime mismatch
//~| ERROR mismatched method receiver //~| ERROR mismatched `self` parameter type
//~| expected type `&'a Bar<T>` //~| expected type `&'a Bar<T>`
//~| found type `&Bar<T>` //~| found type `&Bar<T>`
//~| lifetime mismatch //~| lifetime mismatch

View file

@ -1,31 +1,31 @@
error[E0307]: invalid method receiver type: isize error[E0307]: invalid `self` parameter type: isize
--> $DIR/ufcs-explicit-self-bad.rs:8:18 --> $DIR/ufcs-explicit-self-bad.rs:8:18
| |
LL | fn foo(self: isize, x: isize) -> isize { LL | fn foo(self: isize, x: isize) -> isize {
| ^^^^^ | ^^^^^
| |
= note: type must be `Self` or a type that dereferences to it = note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error[E0307]: invalid method receiver type: Bar<isize> error[E0307]: invalid `self` parameter type: Bar<isize>
--> $DIR/ufcs-explicit-self-bad.rs:19:18 --> $DIR/ufcs-explicit-self-bad.rs:19:18
| |
LL | fn foo(self: Bar<isize>, x: isize) -> isize { LL | fn foo(self: Bar<isize>, x: isize) -> isize {
| ^^^^^^^^^^ | ^^^^^^^^^^
| |
= note: type must be `Self` or a type that dereferences to it = note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error[E0307]: invalid method receiver type: &Bar<usize> error[E0307]: invalid `self` parameter type: &Bar<usize>
--> $DIR/ufcs-explicit-self-bad.rs:23:18 --> $DIR/ufcs-explicit-self-bad.rs:23:18
| |
LL | fn bar(self: &Bar<usize>, x: isize) -> isize { LL | fn bar(self: &Bar<usize>, x: isize) -> isize {
| ^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: type must be `Self` or a type that dereferences to it = note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error[E0308]: mismatched method receiver error[E0308]: mismatched `self` parameter type
--> $DIR/ufcs-explicit-self-bad.rs:37:21 --> $DIR/ufcs-explicit-self-bad.rs:37:21
| |
LL | fn dummy2(self: &Bar<T>) {} LL | fn dummy2(self: &Bar<T>) {}
@ -44,7 +44,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
LL | impl<'a, T> SomeTrait for &'a Bar<T> { LL | impl<'a, T> SomeTrait for &'a Bar<T> {
| ^^ | ^^
error[E0308]: mismatched method receiver error[E0308]: mismatched `self` parameter type
--> $DIR/ufcs-explicit-self-bad.rs:37:21 --> $DIR/ufcs-explicit-self-bad.rs:37:21
| |
LL | fn dummy2(self: &Bar<T>) {} LL | fn dummy2(self: &Bar<T>) {}
@ -63,7 +63,7 @@ note: ...does not necessarily outlive the anonymous lifetime #1 defined on the m
LL | fn dummy2(self: &Bar<T>) {} LL | fn dummy2(self: &Bar<T>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched method receiver error[E0308]: mismatched `self` parameter type
--> $DIR/ufcs-explicit-self-bad.rs:39:21 --> $DIR/ufcs-explicit-self-bad.rs:39:21
| |
LL | fn dummy3(self: &&Bar<T>) {} LL | fn dummy3(self: &&Bar<T>) {}
@ -82,7 +82,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
LL | impl<'a, T> SomeTrait for &'a Bar<T> { LL | impl<'a, T> SomeTrait for &'a Bar<T> {
| ^^ | ^^
error[E0308]: mismatched method receiver error[E0308]: mismatched `self` parameter type
--> $DIR/ufcs-explicit-self-bad.rs:39:21 --> $DIR/ufcs-explicit-self-bad.rs:39:21
| |
LL | fn dummy3(self: &&Bar<T>) {} LL | fn dummy3(self: &&Bar<T>) {}
@ -103,4 +103,5 @@ LL | fn dummy3(self: &&Bar<T>) {}
error: aborting due to 7 previous errors error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0308`. Some errors have detailed explanations: E0307, E0308.
For more information about an error, try `rustc --explain E0307`.

View file

@ -0,0 +1,18 @@
// Check that cyclic glob imports are allowed with underscore imports
// check-pass
mod x {
pub use crate::y::*;
pub use std::ops::Deref as _;
}
mod y {
pub use crate::x::*;
pub use std::ops::Deref as _;
}
pub fn main() {
use x::*;
(&0).deref();
}

View file

@ -0,0 +1,23 @@
// Check that underscore imports don't cause glob imports to be unshadowed
mod a {
pub use std::ops::Deref as Shadow;
}
mod b {
pub use crate::a::*;
macro_rules! m {
($i:ident) => { pub struct $i; }
}
m!(Shadow);
}
mod c {
use crate::b::Shadow as _; // Only imports the struct
fn f(x: &()) {
x.deref(); //~ ERROR no method named `deref` found
}
}
fn main() {}

View file

@ -0,0 +1,13 @@
error[E0599]: no method named `deref` found for type `&()` in the current scope
--> $DIR/shadow.rs:19:11
|
LL | x.deref();
| ^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
`use std::ops::Deref;`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0599`.

Some files were not shown because too many files have changed in this diff Show more