mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
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:
commit
a24f636e60
@ -105,5 +105,6 @@ The following table shows known good combinations of toolchain versions.
|
||||
| Rust 1.34 | ✗ | ✓ |
|
||||
| Rust 1.35 | ✗ | ✓ |
|
||||
| Rust 1.36 | ✗ | ✓ |
|
||||
| Rust 1.37 | ✗ | ✓ |
|
||||
|
||||
Note that the compatibility policy for this feature might change in the future.
|
||||
|
@ -9,14 +9,22 @@
|
||||
//! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
|
||||
//! partial orderings between values, respectively. Implementing them overloads
|
||||
//! the `<`, `<=`, `>`, and `>=` operators.
|
||||
//! * [`Ordering`][cmp::Ordering] is an enum returned by the
|
||||
//! main functions of [`Ord`] and [`PartialOrd`], and describes an ordering.
|
||||
//! * [`Reverse`][cmp::Reverse] is a struct that allows you to easily reverse
|
||||
//! an ordering.
|
||||
//! * [`max`][cmp::max] and [`min`][cmp::min] are functions that build off of
|
||||
//! [`Ord`] and allow you to find the maximum or minimum of two values.
|
||||
//! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and
|
||||
//! [`PartialOrd`], and describes an ordering.
|
||||
//! * [`Reverse`] is a struct that allows you to easily reverse an ordering.
|
||||
//! * [`max`] and [`min`] are functions that build off of [`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.
|
||||
//!
|
||||
//! [`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")]
|
||||
|
||||
|
@ -66,13 +66,6 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
|
||||
{
|
||||
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")]
|
||||
|
@ -462,7 +462,7 @@ impl<P: Deref<Target: Unpin>> Pin<P> {
|
||||
/// can ignore the pinning invariants when unwrapping it.
|
||||
///
|
||||
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
|
||||
#[unstable(feature = "pin_into_inner", issue = "60245")]
|
||||
#[stable(feature = "pin_into_inner", since = "1.39.0")]
|
||||
#[inline(always)]
|
||||
pub fn into_inner(pin: Pin<P>) -> P {
|
||||
pin.pointer
|
||||
@ -569,7 +569,7 @@ impl<P: Deref> Pin<P> {
|
||||
///
|
||||
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
|
||||
/// [`Pin::into_inner`]: #method.into_inner
|
||||
#[unstable(feature = "pin_into_inner", issue = "60245")]
|
||||
#[stable(feature = "pin_into_inner", since = "1.39.0")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
|
||||
pin.pointer
|
||||
|
@ -1688,6 +1688,12 @@ fn test_rposition() {
|
||||
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]
|
||||
#[should_panic]
|
||||
fn test_rposition_panic() {
|
||||
|
@ -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
|
||||
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:
|
||||
|
||||
|
@ -186,7 +186,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
});
|
||||
|
||||
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 hash = cstore.crate_hash_untracked(cnum);
|
||||
(name, disambiguator, hash)
|
||||
|
@ -9,7 +9,7 @@ use std::mem;
|
||||
use syntax::ast;
|
||||
use syntax::feature_gate;
|
||||
use syntax::parse::token;
|
||||
use syntax::symbol::{InternedString, LocalInternedString};
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::tokenstream;
|
||||
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 {
|
||||
#[inline]
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
|
@ -1627,7 +1627,7 @@ impl<'tcx> ObligationCause<'tcx> {
|
||||
MainFunctionType => Error0580("main function has wrong type"),
|
||||
StartFunctionType => Error0308("start function 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
|
||||
// say, also take a look at the error code, maybe we can
|
||||
|
@ -33,7 +33,7 @@ use crate::util::common::time;
|
||||
use std::default::Default as StdDefault;
|
||||
use syntax::ast;
|
||||
use syntax::edition;
|
||||
use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
|
||||
use syntax_pos::{MultiSpan, Span, symbol::Symbol};
|
||||
use errors::DiagnosticBuilder;
|
||||
use crate::hir;
|
||||
use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
@ -405,7 +405,7 @@ impl LintStore {
|
||||
pub fn check_lint_name(
|
||||
&self,
|
||||
lint_name: &str,
|
||||
tool_name: Option<LocalInternedString>,
|
||||
tool_name: Option<Symbol>,
|
||||
) -> CheckLintNameResult<'_> {
|
||||
let complete_name = if let Some(tool_name) = tool_name {
|
||||
format!("{}::{}", tool_name, lint_name)
|
||||
|
@ -291,7 +291,7 @@ impl<'a> LintLevelsBuilder<'a> {
|
||||
continue;
|
||||
}
|
||||
|
||||
Some(tool_ident.as_str())
|
||||
Some(tool_ident.name)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -1808,6 +1808,23 @@ pub enum ProjectionElem<V, T> {
|
||||
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
|
||||
/// and the index is a local.
|
||||
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
|
||||
/// a single deref of a local.
|
||||
//
|
||||
|
@ -1384,7 +1384,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
let mut reported_violations = FxHashSet::default();
|
||||
for violation in violations {
|
||||
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)
|
||||
|
@ -20,7 +20,7 @@ use std::borrow::Cow;
|
||||
use std::iter::{self};
|
||||
use syntax::ast::{self};
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax_pos::Span;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum ObjectSafetyViolation {
|
||||
@ -32,10 +32,10 @@ pub enum ObjectSafetyViolation {
|
||||
SupertraitSelf,
|
||||
|
||||
/// Method has something illegal.
|
||||
Method(ast::Name, MethodViolationCode),
|
||||
Method(ast::Name, MethodViolationCode, Span),
|
||||
|
||||
/// Associated const.
|
||||
AssocConst(ast::Name),
|
||||
AssocConst(ast::Name, Span),
|
||||
}
|
||||
|
||||
impl ObjectSafetyViolation {
|
||||
@ -46,22 +46,35 @@ impl ObjectSafetyViolation {
|
||||
ObjectSafetyViolation::SupertraitSelf =>
|
||||
"the trait cannot use `Self` as a type parameter \
|
||||
in the supertraits or where-clauses".into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) =>
|
||||
format!("method `{}` has no receiver", name).into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) =>
|
||||
format!("method `{}` references the `Self` type \
|
||||
in its arguments or return type", name).into(),
|
||||
ObjectSafetyViolation::Method(name,
|
||||
MethodViolationCode::WhereClauseReferencesSelf(_)) =>
|
||||
format!("method `{}` references the `Self` type in where clauses", name).into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) =>
|
||||
format!("associated function `{}` has no `self` parameter", name).into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!(
|
||||
"method `{}` references the `Self` type in its parameters or return type",
|
||||
name,
|
||||
).into(),
|
||||
ObjectSafetyViolation::Method(
|
||||
name,
|
||||
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(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) =>
|
||||
format!("method `{}`'s receiver cannot be dispatched on", name).into(),
|
||||
ObjectSafetyViolation::AssocConst(name) =>
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) =>
|
||||
format!("method `{}`'s `self` parameter cannot be dispatched on", name).into(),
|
||||
ObjectSafetyViolation::AssocConst(name, _) =>
|
||||
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.
|
||||
@ -74,7 +87,7 @@ pub enum MethodViolationCode {
|
||||
ReferencesSelf,
|
||||
|
||||
/// e.g., `fn foo(&self) where Self: Clone`
|
||||
WhereClauseReferencesSelf(Span),
|
||||
WhereClauseReferencesSelf,
|
||||
|
||||
/// e.g., `fn foo<A>()`
|
||||
Generic,
|
||||
@ -88,9 +101,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// astconv -- currently, `Self` in supertraits. This is needed
|
||||
/// because `object_safety_violations` can't be used during
|
||||
/// type collection.
|
||||
pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
|
||||
-> Vec<ObjectSafetyViolation>
|
||||
{
|
||||
pub fn astconv_object_safety_violations(
|
||||
self,
|
||||
trait_def_id: DefId,
|
||||
) -> Vec<ObjectSafetyViolation> {
|
||||
debug_assert!(self.generics_of(trait_def_id).has_self);
|
||||
let violations = traits::supertrait_def_ids(self, trait_def_id)
|
||||
.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) {
|
||||
None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
|
||||
None | Some(MethodViolationCode::WhereClauseReferencesSelf) => true,
|
||||
Some(_) => false,
|
||||
}
|
||||
}
|
||||
@ -138,12 +152,15 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
let mut violations: Vec<_> = self.associated_items(trait_def_id)
|
||||
.filter(|item| item.kind == ty::AssocKind::Method)
|
||||
.filter_map(|item|
|
||||
self.object_safety_violation_for_method(trait_def_id, &item)
|
||||
.map(|code| ObjectSafetyViolation::Method(item.ident.name, code))
|
||||
self.object_safety_violation_for_method(trait_def_id, &item).map(|code| {
|
||||
ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span)
|
||||
})
|
||||
).filter(|violation| {
|
||||
if let ObjectSafetyViolation::Method(_,
|
||||
MethodViolationCode::WhereClauseReferencesSelf(span)) = violation
|
||||
{
|
||||
if let ObjectSafetyViolation::Method(
|
||||
_,
|
||||
MethodViolationCode::WhereClauseReferencesSelf,
|
||||
span,
|
||||
) = violation {
|
||||
// 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.
|
||||
self.lint_node_note(
|
||||
@ -169,7 +186,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
violations.extend(self.associated_items(trait_def_id)
|
||||
.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={:?}) = {:?}",
|
||||
trait_def_id,
|
||||
@ -325,8 +342,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
.visit_tys_shallow(|t| {
|
||||
self.contains_illegal_self_type_reference(trait_def_id, t)
|
||||
}) {
|
||||
let span = self.def_span(method.def_id);
|
||||
return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
|
||||
return Some(MethodViolationCode::WhereClauseReferencesSelf);
|
||||
}
|
||||
|
||||
let receiver_ty = self.liberate_late_bound_regions(
|
||||
|
@ -9,10 +9,9 @@ use syntax::ast::{MetaItem, NestedMetaItem};
|
||||
use syntax::attr;
|
||||
use syntax::symbol::{Symbol, kw, sym};
|
||||
use syntax_pos::Span;
|
||||
use syntax_pos::symbol::LocalInternedString;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OnUnimplementedFormatString(LocalInternedString);
|
||||
pub struct OnUnimplementedFormatString(Symbol);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OnUnimplementedDirective {
|
||||
@ -89,19 +88,19 @@ impl<'tcx> OnUnimplementedDirective {
|
||||
if item.check_name(sym::message) && message.is_none() {
|
||||
if let Some(message_) = item.value_str() {
|
||||
message = Some(OnUnimplementedFormatString::try_parse(
|
||||
tcx, trait_def_id, message_.as_str(), span)?);
|
||||
tcx, trait_def_id, message_, span)?);
|
||||
continue;
|
||||
}
|
||||
} else if item.check_name(sym::label) && label.is_none() {
|
||||
if let Some(label_) = item.value_str() {
|
||||
label = Some(OnUnimplementedFormatString::try_parse(
|
||||
tcx, trait_def_id, label_.as_str(), span)?);
|
||||
tcx, trait_def_id, label_, span)?);
|
||||
continue;
|
||||
}
|
||||
} else if item.check_name(sym::note) && note.is_none() {
|
||||
if let Some(note_) = item.value_str() {
|
||||
note = Some(OnUnimplementedFormatString::try_parse(
|
||||
tcx, trait_def_id, note_.as_str(), span)?);
|
||||
tcx, trait_def_id, note_, span)?);
|
||||
continue;
|
||||
}
|
||||
} else if item.check_name(sym::on) && is_root &&
|
||||
@ -154,7 +153,7 @@ impl<'tcx> OnUnimplementedDirective {
|
||||
message: None,
|
||||
subcommands: vec![],
|
||||
label: Some(OnUnimplementedFormatString::try_parse(
|
||||
tcx, trait_def_id, value.as_str(), attr.span)?),
|
||||
tcx, trait_def_id, value, attr.span)?),
|
||||
note: None,
|
||||
}))
|
||||
} else {
|
||||
@ -218,7 +217,7 @@ impl<'tcx> OnUnimplementedFormatString {
|
||||
fn try_parse(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
from: LocalInternedString,
|
||||
from: Symbol,
|
||||
err_sp: Span,
|
||||
) -> Result<Self, ErrorReported> {
|
||||
let result = OnUnimplementedFormatString(from);
|
||||
@ -234,7 +233,8 @@ impl<'tcx> OnUnimplementedFormatString {
|
||||
) -> Result<(), ErrorReported> {
|
||||
let name = tcx.item_name(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(());
|
||||
for token in parser {
|
||||
match token {
|
||||
@ -294,7 +294,8 @@ impl<'tcx> OnUnimplementedFormatString {
|
||||
}).collect::<FxHashMap<Symbol, String>>();
|
||||
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|
|
||||
match p {
|
||||
Piece::String(s) => s,
|
||||
|
@ -46,7 +46,7 @@ use std::ops::Range;
|
||||
use syntax::ast::{self, Name, Ident, NodeId};
|
||||
use syntax::attr;
|
||||
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 smallvec;
|
||||
@ -3386,10 +3386,6 @@ impl SymbolName {
|
||||
name: InternedString::intern(name)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> LocalInternedString {
|
||||
self.name.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SymbolName {
|
||||
|
@ -709,8 +709,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
if self.found_recursion {
|
||||
None
|
||||
} else if self.seen_opaque_tys.insert(def_id) {
|
||||
return None;
|
||||
}
|
||||
let substs = substs.fold_with(self);
|
||||
if self.seen_opaque_tys.insert(def_id) {
|
||||
let generic_ty = self.tcx.type_of(def_id);
|
||||
let concrete_ty = generic_ty.subst(self.tcx, substs);
|
||||
let expanded_ty = self.fold_ty(concrete_ty);
|
||||
|
@ -5,7 +5,6 @@ use crate::context::CodegenCx;
|
||||
use crate::type_::Type;
|
||||
use crate::type_of::LayoutLlvmExt;
|
||||
use crate::value::Value;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate};
|
||||
use rustc_codegen_ssa::MemFlags;
|
||||
use libc::{c_uint, c_char};
|
||||
@ -24,6 +23,7 @@ use std::ffi::CStr;
|
||||
use std::ops::{Deref, Range};
|
||||
use std::ptr;
|
||||
use std::iter::TrustedLen;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
// All Builders must have an llfn associated with them
|
||||
#[must_use]
|
||||
@ -1082,8 +1082,8 @@ impl StaticBuilderMethods for Builder<'a, 'll, 'tcx> {
|
||||
|
||||
fn static_panic_msg(
|
||||
&mut self,
|
||||
msg: Option<LocalInternedString>,
|
||||
filename: LocalInternedString,
|
||||
msg: Option<Symbol>,
|
||||
filename: Symbol,
|
||||
line: Self::Value,
|
||||
col: Self::Value,
|
||||
kind: &str,
|
||||
|
@ -37,7 +37,7 @@ pub fn get_fn(
|
||||
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);
|
||||
|
||||
// Create a fn pointer with the substituted signature.
|
||||
|
@ -17,7 +17,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||
|
||||
use libc::{c_uint, c_char};
|
||||
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::ast::Mutability;
|
||||
|
||||
pub use crate::context::CodegenCx;
|
||||
@ -122,7 +122,7 @@ impl CodegenCx<'ll, 'tcx> {
|
||||
|
||||
fn const_cstr(
|
||||
&self,
|
||||
s: LocalInternedString,
|
||||
s: Symbol,
|
||||
null_terminated: bool,
|
||||
) -> &'ll Value {
|
||||
unsafe {
|
||||
@ -130,9 +130,10 @@ impl CodegenCx<'ll, 'tcx> {
|
||||
return llval;
|
||||
}
|
||||
|
||||
let s_str = s.as_str();
|
||||
let sc = llvm::LLVMConstStringInContext(self.llcx,
|
||||
s.as_ptr() as *const c_char,
|
||||
s.len() as c_uint,
|
||||
s_str.as_ptr() as *const c_char,
|
||||
s_str.len() as c_uint,
|
||||
!null_terminated as Bool);
|
||||
let sym = self.generate_local_symbol_name("str");
|
||||
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 {
|
||||
let len = s.len();
|
||||
pub fn const_str_slice(&self, s: Symbol) -> &'ll Value {
|
||||
let len = s.as_str().len();
|
||||
let cs = consts::ptrcast(self.const_cstr(s, false),
|
||||
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))
|
||||
|
@ -11,12 +11,11 @@ use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint,
|
||||
Pointer, ErrorHandled, GlobalId};
|
||||
use rustc::mir::mono::MonoItem;
|
||||
use rustc::hir::Node;
|
||||
use syntax_pos::Span;
|
||||
use rustc_target::abi::HasDataLayout;
|
||||
use syntax::symbol::sym;
|
||||
use syntax_pos::symbol::LocalInternedString;
|
||||
use rustc::ty::{self, Ty, Instance};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use syntax::symbol::{Symbol, sym};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc::ty::layout::{self, Size, Align, LayoutOf};
|
||||
|
||||
@ -122,10 +121,11 @@ fn check_and_apply_linkage(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
attrs: &CodegenFnAttrs,
|
||||
ty: Ty<'tcx>,
|
||||
sym: LocalInternedString,
|
||||
sym: Symbol,
|
||||
span: Span
|
||||
) -> &'ll Value {
|
||||
let llty = cx.layout_of(ty).llvm_type(cx);
|
||||
let sym = sym.as_str();
|
||||
if let Some(linkage) = attrs.linkage {
|
||||
debug!("get_static: sym={} linkage={:?}", sym, linkage);
|
||||
|
||||
@ -221,7 +221,7 @@ impl CodegenCx<'ll, 'tcx> {
|
||||
def_id);
|
||||
|
||||
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);
|
||||
|
||||
@ -232,11 +232,12 @@ impl CodegenCx<'ll, 'tcx> {
|
||||
Node::Item(&hir::Item {
|
||||
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?");
|
||||
}
|
||||
|
||||
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) {
|
||||
unsafe {
|
||||
|
@ -29,7 +29,7 @@ use std::cell::{Cell, RefCell};
|
||||
use std::iter;
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::source_map::{DUMMY_SP, Span};
|
||||
use crate::abi::Abi;
|
||||
|
||||
@ -52,7 +52,7 @@ pub struct CodegenCx<'ll, 'tcx> {
|
||||
pub vtables:
|
||||
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>,
|
||||
/// 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.
|
||||
/// Key is a Value holding a *T,
|
||||
|
@ -2251,7 +2251,7 @@ pub fn create_global_var_metadata(
|
||||
None
|
||||
} else {
|
||||
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);
|
||||
|
@ -290,7 +290,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
let scope_line = span_start(self, span).line;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -121,7 +121,7 @@ fn reachable_non_generics_provider(
|
||||
})
|
||||
.map(|def_id| {
|
||||
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
|
||||
// it has hidden visibility rather than public
|
||||
// visibility, as this is primarily here to ensure it's
|
||||
|
@ -14,7 +14,7 @@ use crate::traits::*;
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::Pos;
|
||||
|
||||
use super::{FunctionCx, LocalRef};
|
||||
@ -397,7 +397,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
|
||||
// Get the location information.
|
||||
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 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])
|
||||
}
|
||||
_ => {
|
||||
let str = msg.description();
|
||||
let msg_str = LocalInternedString::intern(str);
|
||||
let msg_str = Symbol::intern(msg.description());
|
||||
let msg_file_line_col = bx.static_panic_msg(
|
||||
Some(msg_str),
|
||||
filename,
|
||||
@ -531,7 +530,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let layout = bx.layout_of(ty);
|
||||
if layout.abi.is_uninhabited() {
|
||||
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 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 {}",
|
||||
ty
|
||||
);
|
||||
let msg_str = LocalInternedString::intern(&str);
|
||||
let msg_str = Symbol::intern(&str);
|
||||
let msg_file_line_col = bx.static_panic_msg(
|
||||
Some(msg_str),
|
||||
filename,
|
||||
|
@ -58,7 +58,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
|
||||
self.to_raw_string(),
|
||||
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);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::BackendTypes;
|
||||
use syntax_pos::symbol::LocalInternedString;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::layout::Align;
|
||||
|
||||
@ -12,8 +12,8 @@ pub trait StaticBuilderMethods: BackendTypes {
|
||||
fn get_static(&mut self, def_id: DefId) -> Self::Value;
|
||||
fn static_panic_msg(
|
||||
&mut self,
|
||||
msg: Option<LocalInternedString>,
|
||||
filename: LocalInternedString,
|
||||
msg: Option<Symbol>,
|
||||
filename: Symbol,
|
||||
line: Self::Value,
|
||||
col: Self::Value,
|
||||
kind: &str,
|
||||
|
@ -40,7 +40,7 @@ impl SymbolNamesTest<'tcx> {
|
||||
let instance = Instance::mono(tcx, def_id);
|
||||
let mangled = self.tcx.symbol_name(instance);
|
||||
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-alt({:#})", demangling));
|
||||
}
|
||||
|
@ -398,18 +398,37 @@ impl UnusedParens {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_unused_parens_pat(&self,
|
||||
cx: &EarlyContext<'_>,
|
||||
value: &ast::Pat,
|
||||
msg: &str) {
|
||||
if let ast::PatKind::Paren(_) = value.node {
|
||||
fn check_unused_parens_pat(
|
||||
&self,
|
||||
cx: &EarlyContext<'_>,
|
||||
value: &ast::Pat,
|
||||
avoid_or: bool,
|
||||
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()
|
||||
.span_to_snippet(value.span) {
|
||||
snippet
|
||||
} else {
|
||||
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) {
|
||||
use syntax::ast::ExprKind::*;
|
||||
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, ..) => {
|
||||
let left = e.span.lo() + syntax_pos::BytePos(2);
|
||||
let right = block.span.lo();
|
||||
@ -486,7 +512,8 @@ impl EarlyLintPass for UnusedParens {
|
||||
(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()))
|
||||
}
|
||||
|
||||
@ -531,26 +558,46 @@ impl EarlyLintPass for UnusedParens {
|
||||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
|
||||
use ast::PatKind::{Paren, Range};
|
||||
// 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.
|
||||
if let Paren(ref pat) = p.node {
|
||||
match pat.node {
|
||||
Range(..) => {}
|
||||
_ => self.check_unused_parens_pat(cx, &p, "pattern")
|
||||
}
|
||||
use ast::{PatKind::*, Mutability};
|
||||
match &p.node {
|
||||
// Do not lint on `(..)` as that will result in the other arms being useless.
|
||||
Paren(_)
|
||||
// The other cases do not contain sub-patterns.
|
||||
| Wild | Rest | Lit(..) | Mac(..) | Range(..) | Ident(.., None) | Path(..) => return,
|
||||
// These are list-like patterns; parens can always be removed.
|
||||
TupleStruct(_, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
|
||||
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) {
|
||||
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 {
|
||||
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, ¶m.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! {
|
||||
|
@ -54,7 +54,7 @@ fn main() {
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
@ -62,7 +62,7 @@ fn main() {
|
||||
// havoc ensues.
|
||||
//
|
||||
// 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
|
||||
// are gated on `if !is_crossed`
|
||||
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();
|
||||
|
||||
// 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
|
||||
// of llvm-config, not the target that we're attempting to link.
|
||||
let mut cmd = Command::new(&llvm_config);
|
||||
|
@ -336,7 +336,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let local = &self.body.local_decls[local_index];
|
||||
match local.name {
|
||||
Some(name) if !local.from_compiler_desugaring() => {
|
||||
buf.push_str(name.as_str().get());
|
||||
buf.push_str(&name.as_str());
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(()),
|
||||
|
@ -3,7 +3,7 @@ use crate::borrow_check::places_conflict;
|
||||
use crate::borrow_check::AccessDepth;
|
||||
use crate::dataflow::indexes::BorrowIndex;
|
||||
use rustc::mir::{BasicBlock, Location, Body, Place, PlaceBase};
|
||||
use rustc::mir::{ProjectionElem, BorrowKind};
|
||||
use rustc::mir::BorrowKind;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
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
|
||||
/// This is called for all Yield statements on movable generators
|
||||
pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
|
||||
place.iterate(|place_base, place_projection| {
|
||||
match place_base {
|
||||
PlaceBase::Static(..) => return false,
|
||||
PlaceBase::Local(..) => {},
|
||||
}
|
||||
match place.base {
|
||||
PlaceBase::Static(_) => false,
|
||||
|
||||
for proj in place_projection {
|
||||
// Reborrow of already borrowed data is ignored
|
||||
// Any errors will be caught on the initial borrow
|
||||
if proj.elem == ProjectionElem::Deref {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
// Reborrow of already borrowed data is ignored
|
||||
// Any errors will be caught on the initial borrow
|
||||
PlaceBase::Local(_) => !place.is_indirect(),
|
||||
}
|
||||
}
|
||||
|
@ -93,19 +93,10 @@ struct BorrowedLocalsVisitor<'gk> {
|
||||
}
|
||||
|
||||
fn find_local(place: &Place<'_>) -> Option<Local> {
|
||||
place.iterate(|place_base, place_projection| {
|
||||
for proj in place_projection {
|
||||
if proj.elem == ProjectionElem::Deref {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
if let PlaceBase::Local(local) = place_base {
|
||||
Some(*local)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
match place.base {
|
||||
PlaceBase::Local(local) if !place.is_indirect() => Some(local),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for BorrowedLocalsVisitor<'_> {
|
||||
|
@ -777,7 +777,7 @@ where
|
||||
debug!("CodegenUnit {}:", cgu.name());
|
||||
|
||||
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 = symbol_hash_start.map(|i| &symbol_name[i ..])
|
||||
.unwrap_or("<no hash>");
|
||||
|
@ -19,7 +19,7 @@ use crate::astconv::AstConv as _;
|
||||
|
||||
use errors::{Applicability, DiagnosticBuilder};
|
||||
use syntax::ast;
|
||||
use syntax::symbol::{Symbol, LocalInternedString, kw, sym};
|
||||
use syntax::symbol::{Symbol, kw, sym};
|
||||
use syntax::source_map::Span;
|
||||
use syntax::util::lev_distance::find_best_match_for_name;
|
||||
use rustc::hir;
|
||||
@ -1244,7 +1244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
_ => {
|
||||
// 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(
|
||||
variant,
|
||||
&field.ident.as_str(),
|
||||
@ -1288,11 +1288,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Return an hint about the closest match in field names
|
||||
fn suggest_field_name(variant: &'tcx ty::VariantDef,
|
||||
field: &str,
|
||||
skip: Vec<LocalInternedString>)
|
||||
skip: Vec<Symbol>)
|
||||
-> Option<Symbol> {
|
||||
let names = variant.fields.iter().filter_map(|field| {
|
||||
// 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)
|
||||
{
|
||||
None
|
||||
|
@ -1420,8 +1420,8 @@ fn check_opaque_for_cycles<'tcx>(
|
||||
tcx.sess, span, E0733,
|
||||
"recursion in an `async fn` requires boxing",
|
||||
)
|
||||
.span_label(span, "an `async fn` cannot invoke itself directly")
|
||||
.note("a recursive `async fn` must be rewritten to return a boxed future.")
|
||||
.span_label(span, "recursive `async fn`")
|
||||
.note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
|
||||
.emit();
|
||||
} else {
|
||||
let mut err = struct_span_err!(
|
||||
|
@ -762,19 +762,19 @@ fn check_opaque_types<'fcx, 'tcx>(
|
||||
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>(
|
||||
fcx: &FnCtxt<'fcx, 'tcx>,
|
||||
method_sig: &hir::MethodSig,
|
||||
method: &ty::AssocItem,
|
||||
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`.
|
||||
debug!("check_method_receiver({:?}, self_ty={:?})",
|
||||
method, self_ty);
|
||||
debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty);
|
||||
|
||||
if !method.method_has_self_argument {
|
||||
return;
|
||||
@ -805,12 +805,7 @@ fn check_method_receiver<'fcx, 'tcx>(
|
||||
if fcx.tcx.features().arbitrary_self_types {
|
||||
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
|
||||
// Report error; `arbitrary_self_types` was enabled.
|
||||
fcx.tcx.sess.diagnostic().mut_span_err(
|
||||
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();
|
||||
e0307(fcx, span, receiver_ty);
|
||||
}
|
||||
} else {
|
||||
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) {
|
||||
@ -830,17 +825,22 @@ fn check_method_receiver<'fcx, 'tcx>(
|
||||
.emit();
|
||||
} else {
|
||||
// Report error; would not have worked with `arbitrary_self_types`.
|
||||
fcx.tcx.sess.diagnostic().mut_span_err(
|
||||
span, &format!("invalid method receiver type: {:?}", receiver_ty)
|
||||
).note("type must be `Self` or a type that dereferences to it")
|
||||
.help(HELP_FOR_SELF_TYPE)
|
||||
.code(DiagnosticId::Error("E0307".into()))
|
||||
.emit();
|
||||
e0307(fcx, span, receiver_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn e0307(fcx: &FnCtxt<'fcx, 'tcx>, span: Span, receiver_ty: Ty<'_>) {
|
||||
fcx.tcx.sess.diagnostic().mut_span_err(
|
||||
span,
|
||||
&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)
|
||||
.code(DiagnosticId::Error("E0307".into()))
|
||||
.emit();
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
|
||||
|
@ -212,7 +212,7 @@ match string {
|
||||
E0033: r##"
|
||||
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
|
||||
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
|
||||
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##"
|
||||
A cross-crate opt-out trait was implemented on something which wasn't a struct
|
||||
or enum type. Erroneous code example:
|
||||
@ -4851,7 +4932,6 @@ register_diagnostics! {
|
||||
// E0247,
|
||||
// E0248, // value used as a type, now reported earlier during resolution as E0412
|
||||
// E0249,
|
||||
E0307, // invalid method `self` type
|
||||
// E0319, // trait impls for defaulted traits allowed just for structs/enums
|
||||
// E0372, // coherence not object safe
|
||||
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
|
||||
|
@ -371,6 +371,14 @@ where
|
||||
loop {
|
||||
if g.len == g.buf.len() {
|
||||
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));
|
||||
let capacity = g.buf.capacity();
|
||||
g.buf.set_len(capacity);
|
||||
|
@ -244,7 +244,6 @@
|
||||
#![feature(cfg_target_has_atomic)]
|
||||
#![feature(cfg_target_thread_local)]
|
||||
#![feature(char_error_internals)]
|
||||
#![feature(checked_duration_since)]
|
||||
#![feature(clamp)]
|
||||
#![feature(compiler_builtins_lib)]
|
||||
#![feature(concat_idents)]
|
||||
|
@ -221,7 +221,6 @@ impl Instant {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(checked_duration_since)]
|
||||
/// use std::time::{Duration, Instant};
|
||||
/// use std::thread::sleep;
|
||||
///
|
||||
@ -231,7 +230,7 @@ impl Instant {
|
||||
/// println!("{:?}", new_now.checked_duration_since(now));
|
||||
/// 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> {
|
||||
self.0.checked_sub_instant(&earlier.0)
|
||||
}
|
||||
@ -242,7 +241,6 @@ impl Instant {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(checked_duration_since)]
|
||||
/// use std::time::{Duration, Instant};
|
||||
/// use std::thread::sleep;
|
||||
///
|
||||
@ -252,7 +250,7 @@ impl Instant {
|
||||
/// println!("{:?}", new_now.saturating_duration_since(now));
|
||||
/// 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 {
|
||||
self.checked_duration_since(earlier).unwrap_or(Duration::new(0, 0))
|
||||
}
|
||||
|
@ -889,6 +889,36 @@ impl<'a> Parser<'a> {
|
||||
hi = path.span;
|
||||
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) {
|
||||
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)?;
|
||||
hi = await_hi;
|
||||
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 {
|
||||
if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
|
||||
// Don't complain about bare semicolons after unclosed braces
|
||||
|
@ -818,10 +818,14 @@ impl Ident {
|
||||
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 {
|
||||
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 {
|
||||
self.name.as_interned_str()
|
||||
}
|
||||
@ -916,6 +920,25 @@ impl Symbol {
|
||||
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 {
|
||||
with_interner(|interner| unsafe {
|
||||
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 {
|
||||
with_interner(|interner| InternedString {
|
||||
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
|
||||
// `LocalInternedString`, by creating a new thread right after constructing the
|
||||
// interner.
|
||||
#[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)]
|
||||
#[derive(Clone, Copy, Eq, PartialOrd, Ord)]
|
||||
pub struct LocalInternedString {
|
||||
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
|
||||
where
|
||||
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
|
||||
/// main differences to `Symbol`.
|
||||
///
|
||||
@ -1285,28 +1270,19 @@ impl InternedString {
|
||||
}
|
||||
|
||||
pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
|
||||
let str = with_interner(|interner| {
|
||||
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) }
|
||||
self.symbol.with(f)
|
||||
}
|
||||
|
||||
fn with2<F: FnOnce(&str, &str) -> R, R>(self, other: &InternedString, f: F) -> R {
|
||||
let (self_str, other_str) = with_interner(|interner| {
|
||||
(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) }
|
||||
self.symbol.with2(other.symbol, f)
|
||||
}
|
||||
|
||||
pub fn as_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 {
|
||||
self.symbol.as_str()
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
error[E0038]: the trait `Trait` cannot be made into an object
|
||||
--> $DIR/associated-const-in-trait.rs:9:6
|
||||
|
|
||||
LL | const N: usize;
|
||||
| - the trait cannot contain associated consts like `N`
|
||||
...
|
||||
LL | impl dyn Trait {
|
||||
| ^^^^^^^^^ the trait `Trait` cannot be made into an object
|
||||
|
|
||||
= note: the trait cannot contain associated consts like `N`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -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() {}
|
@ -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`.
|
@ -2,9 +2,9 @@ error[E0733]: recursion in an `async fn` requires boxing
|
||||
--> $DIR/recursive-async-impl-trait-type.rs:5:40
|
||||
|
|
||||
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
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
error[E0038]: the trait `NotObjectSafe` cannot be made into an object
|
||||
--> $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 { }
|
||||
| ^^^^^^^^^^^^^ 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
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
error[E0038]: the trait `NotObjectSafe` cannot be made into an object
|
||||
--> $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 { }
|
||||
| ^^^^^^^^^^^^^ 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
|
||||
|
||||
|
@ -61,8 +61,9 @@ error[E0038]: the trait `X` cannot be made into an object
|
||||
|
|
||||
LL | impl dyn X {
|
||||
| ^^^^^ 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
|
||||
|
||||
|
@ -1,14 +1,13 @@
|
||||
// compile-flags: -Z teach
|
||||
|
||||
trait SomeTrait {
|
||||
fn foo();
|
||||
fn foo(); //~ associated function `foo` has no `self` parameter
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
//~^ ERROR expected value, found trait `SomeTrait`
|
||||
//~| ERROR E0038
|
||||
//~| method `foo` has no receiver
|
||||
|
||||
let &invalid = trait_obj;
|
||||
//~^ ERROR E0033
|
||||
|
@ -7,13 +7,14 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
error[E0038]: the trait `SomeTrait` cannot be made into an object
|
||||
--> $DIR/E0033-teach.rs:8:20
|
||||
|
|
||||
LL | fn foo();
|
||||
| --- associated function `foo` has no `self` parameter
|
||||
...
|
||||
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
| ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
|
||||
|
|
||||
= note: method `foo` has no receiver
|
||||
|
||||
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;
|
||||
| ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
|
||||
|
@ -1,12 +1,11 @@
|
||||
trait SomeTrait {
|
||||
fn foo();
|
||||
fn foo(); //~ associated function `foo` has no `self` parameter
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
//~^ ERROR expected value, found trait `SomeTrait`
|
||||
//~| ERROR E0038
|
||||
//~| method `foo` has no receiver
|
||||
|
||||
let &invalid = trait_obj;
|
||||
//~^ ERROR E0033
|
||||
|
@ -7,13 +7,14 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
error[E0038]: the trait `SomeTrait` cannot be made into an object
|
||||
--> $DIR/E0033.rs:6:20
|
||||
|
|
||||
LL | fn foo();
|
||||
| --- associated function `foo` has no `self` parameter
|
||||
...
|
||||
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
| ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
|
||||
|
|
||||
= note: method `foo` has no receiver
|
||||
|
||||
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
|
||||
--> $DIR/E0033.rs:11:9
|
||||
--> $DIR/E0033.rs:10:9
|
||||
|
|
||||
LL | let &invalid = trait_obj;
|
||||
| ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
|
||||
|
@ -1,10 +1,11 @@
|
||||
error[E0038]: the trait `Trait` cannot be made into an object
|
||||
--> $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>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
|
@ -6,11 +6,11 @@ struct Foo<'a,'b> {
|
||||
impl<'a,'b> Foo<'a,'b> {
|
||||
fn bar(self:
|
||||
Foo<'b,'a>
|
||||
//~^ ERROR mismatched method receiver
|
||||
//~^ ERROR mismatched `self` parameter type
|
||||
//~| expected type `Foo<'a, 'b>`
|
||||
//~| found type `Foo<'b, 'a>`
|
||||
//~| lifetime mismatch
|
||||
//~| ERROR mismatched method receiver
|
||||
//~| ERROR mismatched `self` parameter type
|
||||
//~| expected type `Foo<'a, 'b>`
|
||||
//~| found type `Foo<'b, 'a>`
|
||||
//~| lifetime mismatch
|
||||
|
@ -1,4 +1,4 @@
|
||||
error[E0308]: mismatched method receiver
|
||||
error[E0308]: mismatched `self` parameter type
|
||||
--> $DIR/explicit-self-lifetime-mismatch.rs:8:12
|
||||
|
|
||||
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> {
|
||||
| ^^
|
||||
|
||||
error[E0308]: mismatched method receiver
|
||||
error[E0308]: mismatched `self` parameter type
|
||||
--> $DIR/explicit-self-lifetime-mismatch.rs:8:12
|
||||
|
|
||||
LL | Foo<'b,'a>
|
||||
|
@ -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() {}
|
@ -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`.
|
@ -4,11 +4,11 @@ struct Foo<'a> {
|
||||
|
||||
impl <'a> Foo<'a>{
|
||||
fn bar(self: &mut Foo) {
|
||||
//~^ mismatched method receiver
|
||||
//~^ mismatched `self` parameter type
|
||||
//~| expected type `Foo<'a>`
|
||||
//~| found type `Foo<'_>`
|
||||
//~| lifetime mismatch
|
||||
//~| mismatched method receiver
|
||||
//~| mismatched `self` parameter type
|
||||
//~| expected type `Foo<'a>`
|
||||
//~| found type `Foo<'_>`
|
||||
//~| lifetime mismatch
|
||||
|
@ -1,4 +1,4 @@
|
||||
error[E0308]: mismatched method receiver
|
||||
error[E0308]: mismatched `self` parameter type
|
||||
--> $DIR/issue-17740.rs:6:18
|
||||
|
|
||||
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>{
|
||||
| ^^
|
||||
|
||||
error[E0308]: mismatched method receiver
|
||||
error[E0308]: mismatched `self` parameter type
|
||||
--> $DIR/issue-17740.rs:6:18
|
||||
|
|
||||
LL | fn bar(self: &mut Foo) {
|
||||
|
@ -6,8 +6,8 @@ impl Pair<
|
||||
isize
|
||||
> {
|
||||
fn say(self: &Pair<&str, isize>) {
|
||||
//~^ ERROR mismatched method receiver
|
||||
//~| ERROR mismatched method receiver
|
||||
//~^ ERROR mismatched `self` parameter type
|
||||
//~| ERROR mismatched `self` parameter type
|
||||
println!("{:?}", self);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
error[E0308]: mismatched method receiver
|
||||
error[E0308]: mismatched `self` parameter type
|
||||
--> $DIR/issue-17905-2.rs:8:18
|
||||
|
|
||||
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,
|
||||
| ^
|
||||
|
||||
error[E0308]: mismatched method receiver
|
||||
error[E0308]: mismatched `self` parameter type
|
||||
--> $DIR/issue-17905-2.rs:8:18
|
||||
|
|
||||
LL | fn say(self: &Pair<&str, isize>) {
|
||||
|
@ -1,10 +1,11 @@
|
||||
error[E0038]: the trait `Bar` cannot be made into an object
|
||||
--> $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) {
|
||||
| ^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
|
||||
|
|
||||
= note: method `foo` has generic type parameters
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
error[E0038]: the trait `Qiz` cannot be made into an object
|
||||
--> $DIR/issue-19380.rs:11:3
|
||||
|
|
||||
LL | fn qiz();
|
||||
| --- associated function `qiz` has no `self` parameter
|
||||
...
|
||||
LL | foos: &'static [&'static (dyn Qiz + 'static)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
|
||||
|
|
||||
= note: method `qiz` has no receiver
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,18 +1,21 @@
|
||||
error[E0038]: the trait `Bar` cannot be made into an object
|
||||
--> $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;
|
||||
| ^^^^^^^^^^^^ 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
|
||||
--> $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;
|
||||
| ^^^^^^^^^^ 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`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,8 +1,8 @@
|
||||
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;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/issue-50781.rs:1:9
|
||||
|
@ -1,7 +1,6 @@
|
||||
pub trait 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() {}
|
||||
|
@ -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
|
||||
|
|
||||
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`)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0307`.
|
||||
|
@ -1,25 +1,75 @@
|
||||
// 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(unreachable_patterns)]
|
||||
#![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() {
|
||||
match 1 {
|
||||
(_) => {} //~ WARNING: unnecessary parentheses around pattern
|
||||
(y) => {} //~ WARNING: unnecessary parentheses around pattern
|
||||
(ref r) => {} //~ WARNING: unnecessary parentheses around pattern
|
||||
(e @ 1...2) => {} //~ WARNING: unnecessary parentheses around outer pattern
|
||||
(1...2) => {} // Non ambiguous range pattern should not warn
|
||||
(_) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
(y) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
(ref r) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
(e @ 1...2) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
(1...2) => {} // Non ambiguous range pattern should not warn
|
||||
e @ (3...4) => {} // Non ambiguous range pattern should not warn
|
||||
}
|
||||
|
||||
match &1 {
|
||||
(e @ &(1...2)) => {} //~ WARNING: unnecessary parentheses around outer pattern
|
||||
&(_) => {} //~ WARNING: unnecessary parentheses around pattern
|
||||
e @ &(1...2) => {} // Ambiguous range pattern should not warn
|
||||
&(1...2) => {} // Ambiguous range pattern should not warn
|
||||
(e @ &(1...2)) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
&(_) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
e @ &(1...2) => {} // Ambiguous range pattern should not warn
|
||||
&(1...2) => {} // Ambiguous range pattern should not warn
|
||||
}
|
||||
|
||||
match &1 {
|
||||
@ -28,19 +78,19 @@ fn main() {
|
||||
}
|
||||
|
||||
match 1 {
|
||||
(_) => {} //~ WARNING: unnecessary parentheses around pattern
|
||||
(y) => {} //~ WARNING: unnecessary parentheses around pattern
|
||||
(ref r) => {} //~ WARNING: unnecessary parentheses around pattern
|
||||
(e @ 1..=2) => {} //~ WARNING: unnecessary parentheses around outer pattern
|
||||
(1..=2) => {} // Non ambiguous range pattern should not warn
|
||||
(_) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
(y) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
(ref r) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
(e @ 1..=2) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
(1..=2) => {} // Non ambiguous range pattern should not warn
|
||||
e @ (3..=4) => {} // Non ambiguous range pattern should not warn
|
||||
}
|
||||
|
||||
match &1 {
|
||||
(e @ &(1..=2)) => {} //~ WARNING: unnecessary parentheses around outer pattern
|
||||
&(_) => {} //~ WARNING: unnecessary parentheses around pattern
|
||||
e @ &(1..=2) => {} // Ambiguous range pattern should not warn
|
||||
&(1..=2) => {} // Ambiguous range pattern should not warn
|
||||
(e @ &(1..=2)) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
&(_) => {} //~ ERROR unnecessary parentheses around pattern
|
||||
e @ &(1..=2) => {} // Ambiguous range pattern should not warn
|
||||
&(1..=2) => {} // Ambiguous range pattern should not warn
|
||||
}
|
||||
|
||||
match &1 {
|
||||
|
@ -1,78 +1,173 @@
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:10:9
|
||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||
--> $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
|
||||
|
|
||||
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
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:11:9
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $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) => {}
|
||||
| ^^^ help: remove these parentheses
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:12:9
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:62:9
|
||||
|
|
||||
LL | (ref r) => {}
|
||||
| ^^^^^^^ help: remove these parentheses
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:13:9
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:63:9
|
||||
|
|
||||
LL | (e @ 1...2) => {}
|
||||
| ^^^^^^^^^^^ help: remove these parentheses
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:19:9
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:69:9
|
||||
|
|
||||
LL | (e @ &(1...2)) => {}
|
||||
| ^^^^^^^^^^^^^^ help: remove these parentheses
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:20:10
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:70:10
|
||||
|
|
||||
LL | &(_) => {}
|
||||
| ^^^ help: remove these parentheses
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:31:9
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:81:9
|
||||
|
|
||||
LL | (_) => {}
|
||||
| ^^^ help: remove these parentheses
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:32:9
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:82:9
|
||||
|
|
||||
LL | (y) => {}
|
||||
| ^^^ help: remove these parentheses
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:33:9
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:83:9
|
||||
|
|
||||
LL | (ref r) => {}
|
||||
| ^^^^^^^ help: remove these parentheses
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:34:9
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:84:9
|
||||
|
|
||||
LL | (e @ 1..=2) => {}
|
||||
| ^^^^^^^^^^^ help: remove these parentheses
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:40:9
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:90:9
|
||||
|
|
||||
LL | (e @ &(1..=2)) => {}
|
||||
| ^^^^^^^^^^^^^^ help: remove these parentheses
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:41:10
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-54538-unused-parens-lint.rs:91:10
|
||||
|
|
||||
LL | &(_) => {}
|
||||
| ^^^ help: remove these parentheses
|
||||
|
||||
error: aborting due to 26 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0416`.
|
||||
|
@ -1,10 +1,11 @@
|
||||
error[E0038]: the trait `Bar` cannot be made into an object
|
||||
--> $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 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
|
||||
|
|
||||
= note: the trait cannot contain associated consts like `X`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,18 +1,20 @@
|
||||
error[E0038]: the trait `Bar` cannot be made into an object
|
||||
--> $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 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
|
||||
|
|
||||
= note: method `bar` has generic type parameters
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -1,18 +1,20 @@
|
||||
error[E0038]: the trait `Bar` cannot be made into an object
|
||||
--> $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 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $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> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
||||
|
|
||||
= note: method `foo` has no receiver
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
|
||||
LL | fn bar(_x: Foo) {}
|
||||
| ^^^^^^^^^^^^^^^ 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
|
||||
|
||||
|
11
src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs
Normal file
11
src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs
Normal 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 }
|
@ -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() {}
|
@ -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`.
|
@ -1,18 +1,21 @@
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $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>;
|
||||
| ^^^^^^^^^^^ 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
|
||||
--> $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>;
|
||||
| ^^^^^^^^^^^^^^^ 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>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -3,7 +3,7 @@
|
||||
struct SomeType {}
|
||||
|
||||
trait Foo {
|
||||
fn handler(self: &SomeType); //~ ERROR invalid method receiver type
|
||||
fn handler(self: &SomeType); //~ ERROR invalid `self` parameter type
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,11 +1,12 @@
|
||||
error[E0307]: invalid method receiver type: &SomeType
|
||||
error[E0307]: invalid `self` parameter type: &SomeType
|
||||
--> $DIR/issue-27522.rs:6:22
|
||||
|
|
||||
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`)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0307`.
|
||||
|
@ -110,12 +110,17 @@ LL | C::A;
|
||||
error[E0038]: the trait `assoc_const::C` cannot be made into an object
|
||||
--> $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;
|
||||
| ^^^^ 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
|
||||
--> $DIR/trait-item-privacy.rs:115:12
|
||||
|
@ -1,19 +1,22 @@
|
||||
error[E0038]: the trait `Tr` cannot be made into an object
|
||||
--> $DIR/trait-object-safety.rs:15:22
|
||||
|
|
||||
LL | fn foo();
|
||||
| --- associated function `foo` has no `self` parameter
|
||||
...
|
||||
LL | let _: &dyn Tr = &St;
|
||||
| ^^^ 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`
|
||||
|
||||
error[E0038]: the trait `Tr` cannot be made into an object
|
||||
--> $DIR/trait-object-safety.rs:15:12
|
||||
|
|
||||
LL | fn foo();
|
||||
| --- associated function `foo` has no `self` parameter
|
||||
...
|
||||
LL | let _: &dyn Tr = &St;
|
||||
| ^^^^^^^ the trait `Tr` cannot be made into an object
|
||||
|
|
||||
= note: method `foo` has no receiver
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -13,20 +13,25 @@ LL | 10.blah::<i32, i32>();
|
||||
error[E0038]: the trait `bar` cannot be made into an object
|
||||
--> $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();
|
||||
| ^^^^^^^^^^^^ 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
|
||||
--> $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();
|
||||
| ^^^^^^ 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}>`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
@ -13,10 +13,11 @@ LL | let y = x as dyn MyAdd<i32>;
|
||||
error[E0038]: the trait `MyAdd` cannot be made into an object
|
||||
--> $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>;
|
||||
| ^^^^^^^^^^^^^^ 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
|
||||
|
||||
|
@ -6,7 +6,7 @@ struct Foo {
|
||||
|
||||
impl Foo {
|
||||
fn foo(self: isize, x: isize) -> isize {
|
||||
//~^ ERROR invalid method receiver type
|
||||
//~^ ERROR invalid `self` parameter type
|
||||
self.f + x
|
||||
}
|
||||
}
|
||||
@ -17,11 +17,11 @@ struct Bar<T> {
|
||||
|
||||
impl<T> Bar<T> {
|
||||
fn foo(self: Bar<isize>, x: isize) -> isize {
|
||||
//~^ ERROR invalid method receiver type
|
||||
//~^ ERROR invalid `self` parameter type
|
||||
x
|
||||
}
|
||||
fn bar(self: &Bar<usize>, x: isize) -> isize {
|
||||
//~^ ERROR invalid method receiver type
|
||||
//~^ ERROR invalid `self` parameter type
|
||||
x
|
||||
}
|
||||
}
|
||||
@ -34,14 +34,14 @@ trait SomeTrait {
|
||||
|
||||
impl<'a, T> SomeTrait for &'a Bar<T> {
|
||||
fn dummy1(self: &&'a Bar<T>) { }
|
||||
fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched method receiver
|
||||
//~^ ERROR mismatched method receiver
|
||||
fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched `self` parameter type
|
||||
//~^ ERROR mismatched `self` parameter type
|
||||
fn dummy3(self: &&Bar<T>) {}
|
||||
//~^ ERROR mismatched method receiver
|
||||
//~^ ERROR mismatched `self` parameter type
|
||||
//~| expected type `&'a Bar<T>`
|
||||
//~| found type `&Bar<T>`
|
||||
//~| lifetime mismatch
|
||||
//~| ERROR mismatched method receiver
|
||||
//~| ERROR mismatched `self` parameter type
|
||||
//~| expected type `&'a Bar<T>`
|
||||
//~| found type `&Bar<T>`
|
||||
//~| lifetime mismatch
|
||||
|
@ -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
|
||||
|
|
||||
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`)
|
||||
|
||||
error[E0307]: invalid method receiver type: Bar<isize>
|
||||
error[E0307]: invalid `self` parameter type: Bar<isize>
|
||||
--> $DIR/ufcs-explicit-self-bad.rs:19:18
|
||||
|
|
||||
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`)
|
||||
|
||||
error[E0307]: invalid method receiver type: &Bar<usize>
|
||||
error[E0307]: invalid `self` parameter type: &Bar<usize>
|
||||
--> $DIR/ufcs-explicit-self-bad.rs:23:18
|
||||
|
|
||||
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`)
|
||||
|
||||
error[E0308]: mismatched method receiver
|
||||
error[E0308]: mismatched `self` parameter type
|
||||
--> $DIR/ufcs-explicit-self-bad.rs:37:21
|
||||
|
|
||||
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> {
|
||||
| ^^
|
||||
|
||||
error[E0308]: mismatched method receiver
|
||||
error[E0308]: mismatched `self` parameter type
|
||||
--> $DIR/ufcs-explicit-self-bad.rs:37:21
|
||||
|
|
||||
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>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched method receiver
|
||||
error[E0308]: mismatched `self` parameter type
|
||||
--> $DIR/ufcs-explicit-self-bad.rs:39:21
|
||||
|
|
||||
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> {
|
||||
| ^^
|
||||
|
||||
error[E0308]: mismatched method receiver
|
||||
error[E0308]: mismatched `self` parameter type
|
||||
--> $DIR/ufcs-explicit-self-bad.rs:39:21
|
||||
|
|
||||
LL | fn dummy3(self: &&Bar<T>) {}
|
||||
@ -103,4 +103,5 @@ LL | fn dummy3(self: &&Bar<T>) {}
|
||||
|
||||
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`.
|
||||
|
18
src/test/ui/underscore-imports/cycle.rs
Normal file
18
src/test/ui/underscore-imports/cycle.rs
Normal 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();
|
||||
}
|
23
src/test/ui/underscore-imports/shadow.rs
Normal file
23
src/test/ui/underscore-imports/shadow.rs
Normal 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() {}
|
13
src/test/ui/underscore-imports/shadow.stderr
Normal file
13
src/test/ui/underscore-imports/shadow.stderr
Normal 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
Loading…
Reference in New Issue
Block a user