a == b
}
+/// Hash the raw pointer address behind a reference, rather than the value
+/// it points to.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(ptr_hash)]
+/// use std::collections::hash_map::DefaultHasher;
+/// use std::hash::{Hash, Hasher};
+/// use std::ptr;
+///
+/// let five = 5;
+/// let five_ref = &five;
+///
+/// let mut hasher = DefaultHasher::new();
+/// ptr::hash(five_ref, &mut hasher);
+/// let actual = hasher.finish();
+///
+/// let mut hasher = DefaultHasher::new();
+/// (five_ref as *const i32).hash(&mut hasher);
+/// let expected = hasher.finish();
+///
+/// assert_eq!(actual, expected);
+/// ```
+#[unstable(feature = "ptr_hash", reason = "newly added", issue = "56286")]
+pub fn hash<T, S: hash::Hasher>(hashee: *const T, into: &mut S) {
+ use hash::Hash;
+ hashee.hash(into);
+}
+
// Impls for function pointers
macro_rules! fnptr_impls_safety_abi {
($FnTy: ty, $($Arg: ident),*) => {
continue;
}
- let result = select.select(&Obligation::new(dummy_cause.clone(), new_env, pred));
+ // Call infcx.resolve_type_vars_if_possible to see if we can
+ // get rid of any inference variables.
+ let obligation = infcx.resolve_type_vars_if_possible(
+ &Obligation::new(dummy_cause.clone(), new_env, pred)
+ );
+ let result = select.select(&obligation);
match &result {
&Ok(Some(ref vtable)) => {
}
&Ok(None) => {}
&Err(SelectionError::Unimplemented) => {
- if self.is_of_param(pred.skip_binder().trait_ref.substs) {
+ if self.is_param_no_infer(pred.skip_binder().trait_ref.substs) {
already_visited.remove(&pred);
self.add_user_pred(
&mut user_computed_preds,
finished_map
}
- pub fn is_of_param(&self, substs: &Substs<'_>) -> bool {
- if substs.is_noop() {
- return false;
- }
+ fn is_param_no_infer(&self, substs: &Substs<'_>) -> bool {
+ return self.is_of_param(substs.type_at(0)) &&
+ !substs.types().any(|t| t.has_infer_types());
+ }
- return match substs.type_at(0).sty {
+ pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
+ return match ty.sty {
ty::Param(_) => true,
- ty::Projection(p) => self.is_of_param(p.substs),
+ ty::Projection(p) => self.is_of_param(p.self_ty()),
_ => false,
};
}
+ fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
+ match p.ty().skip_binder().sty {
+ ty::Projection(proj) if proj == p.skip_binder().projection_ty => {
+ true
+ },
+ _ => false
+ }
+ }
+
pub fn evaluate_nested_obligations<
'b,
'c,
) -> bool {
let dummy_cause = ObligationCause::misc(DUMMY_SP, ast::DUMMY_NODE_ID);
- for (obligation, predicate) in nested
- .filter(|o| o.recursion_depth == 1)
+ for (obligation, mut predicate) in nested
.map(|o| (o.clone(), o.predicate.clone()))
{
let is_new_pred =
fresh_preds.insert(self.clean_pred(select.infcx(), predicate.clone()));
+ // Resolve any inference variables that we can, to help selection succeed
+ predicate = select.infcx().resolve_type_vars_if_possible(&predicate);
+
+ // We only add a predicate as a user-displayable bound if
+ // it involves a generic parameter, and doesn't contain
+ // any inference variables.
+ //
+ // Displaying a bound involving a concrete type (instead of a generic
+ // parameter) would be pointless, since it's always true
+ // (e.g. u8: Copy)
+ // Displaying an inference variable is impossible, since they're
+ // an internal compiler detail without a defined visual representation
+ //
+ // We check this by calling is_of_param on the relevant types
+ // from the various possible predicates
match &predicate {
&ty::Predicate::Trait(ref p) => {
- let substs = &p.skip_binder().trait_ref.substs;
+ if self.is_param_no_infer(p.skip_binder().trait_ref.substs)
+ && !only_projections
+ && is_new_pred {
- if self.is_of_param(substs) && !only_projections && is_new_pred {
self.add_user_pred(computed_preds, predicate);
}
predicates.push_back(p.clone());
}
&ty::Predicate::Projection(p) => {
- // If the projection isn't all type vars, then
- // we don't want to add it as a bound
- if self.is_of_param(p.skip_binder().projection_ty.substs) && is_new_pred {
- self.add_user_pred(computed_preds, predicate);
- } else {
+ debug!("evaluate_nested_obligations: examining projection predicate {:?}",
+ predicate);
+
+ // As described above, we only want to display
+ // bounds which include a generic parameter but don't include
+ // an inference variable.
+ // Additionally, we check if we've seen this predicate before,
+ // to avoid rendering duplicate bounds to the user.
+ if self.is_param_no_infer(p.skip_binder().projection_ty.substs)
+ && !p.ty().skip_binder().is_ty_infer()
+ && is_new_pred {
+ debug!("evaluate_nested_obligations: adding projection predicate\
+ to computed_preds: {:?}", predicate);
+
+ // Under unusual circumstances, we can end up with a self-refeential
+ // projection predicate. For example:
+ // <T as MyType>::Value == <T as MyType>::Value
+ // Not only is displaying this to the user pointless,
+ // having it in the ParamEnv will cause an issue if we try to call
+ // poly_project_and_unify_type on the predicate, since this kind of
+ // predicate will normally never end up in a ParamEnv.
+ //
+ // For these reasons, we ignore these weird predicates,
+ // ensuring that we're able to properly synthesize an auto trait impl
+ if self.is_self_referential_projection(p) {
+ debug!("evaluate_nested_obligations: encountered a projection
+ predicate equating a type with itself! Skipping");
+
+ } else {
+ self.add_user_pred(computed_preds, predicate);
+ }
+ }
+
+ // We can only call poly_project_and_unify_type when our predicate's
+ // Ty is an inference variable - otherwise, there won't be anything to
+ // unify
+ if p.ty().skip_binder().is_ty_infer() {
+ debug!("Projecting and unifying projection predicate {:?}",
+ predicate);
match poly_project_and_unify_type(select, &obligation.with(p.clone())) {
Err(e) => {
debug!(
}
});
- let whitelisted_legacy_custom_derives = registry.take_whitelisted_custom_derives();
let Registry {
syntax_exts,
early_lint_passes,
crate_loader,
&resolver_arenas,
);
- resolver.whitelisted_legacy_custom_derives = whitelisted_legacy_custom_derives;
syntax_ext::register_builtins(&mut resolver, syntax_exts, sess.features_untracked().quote);
// Expand all macros
#[doc(hidden)]
pub attributes: Vec<(String, AttributeType)>,
-
- whitelisted_custom_derives: Vec<ast::Name>,
}
impl<'a> Registry<'a> {
lint_groups: FxHashMap::default(),
llvm_passes: vec![],
attributes: vec![],
- whitelisted_custom_derives: Vec::new(),
}
}
}));
}
- /// This can be used in place of `register_syntax_extension` to register legacy custom derives
- /// (i.e. attribute syntax extensions whose name begins with `derive_`). Legacy custom
- /// derives defined by this function do not trigger deprecation warnings when used.
- pub fn register_custom_derive(&mut self, name: ast::Name, extension: SyntaxExtension) {
- assert!(name.as_str().starts_with("derive_"));
- self.whitelisted_custom_derives.push(name);
- self.register_syntax_extension(name, extension);
- }
-
- pub fn take_whitelisted_custom_derives(&mut self) -> Vec<ast::Name> {
- ::std::mem::replace(&mut self.whitelisted_custom_derives, Vec::new())
- }
-
/// Register a macro of the usual kind.
///
/// This is a convenience wrapper for `register_syntax_extension`.
macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
macro_defs: FxHashMap<Mark, DefId>,
local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
- pub whitelisted_legacy_custom_derives: Vec<Name>,
pub found_unresolved_macro: bool,
/// List of crate local macros that we need to warn about as being unused.
macro_defs,
local_macro_def_scopes: FxHashMap::default(),
name_already_seen: FxHashMap::default(),
- whitelisted_legacy_custom_derives: Vec::new(),
potentially_unused_imports: Vec::new(),
struct_constructors: Default::default(),
found_unresolved_macro: false,
use rustc::hir::def::{Def, NonMacroAttrKind};
use rustc::hir::map::{self, DefCollector};
use rustc::{ty, lint};
-use syntax::ast::{self, Name, Ident};
+use syntax::ast::{self, Ident};
use syntax::attr;
use syntax::errors::DiagnosticBuilder;
use syntax::ext::base::{self, Determinacy};
-use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
+use syntax::ext::base::{MacroKind, SyntaxExtension};
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
use syntax::ext::hygiene::{self, Mark};
use syntax::ext::tt::macro_rules;
-use syntax::feature_gate::{self, feature_err, emit_feature_err, is_builtin_attr_name, GateIssue};
-use syntax::feature_gate::EXPLAIN_DERIVE_UNDERSCORE;
+use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue};
use syntax::fold::{self, Folder};
-use syntax::parse::parser::PathStyle;
-use syntax::parse::token::{self, Token};
use syntax::ptr::P;
use syntax::symbol::{Symbol, keywords};
-use syntax::tokenstream::{TokenStream, TokenTree, Delimited, DelimSpan};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::{Span, DUMMY_SP};
use errors::Applicability;
ret.into_iter().next().unwrap()
}
- fn is_whitelisted_legacy_custom_derive(&self, name: Name) -> bool {
- self.whitelisted_legacy_custom_derives.contains(&name)
- }
-
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
derives: &[Mark]) {
let invocation = self.invocations[&mark];
ImportResolver { resolver: self }.resolve_imports()
}
- // Resolves attribute and derive legacy macros from `#![plugin(..)]`.
- fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_derive: bool)
- -> Option<ast::Attribute> {
- if !allow_derive {
- return None;
- }
-
- // Check for legacy derives
- for i in 0..attrs.len() {
- let name = attrs[i].name();
-
- if name == "derive" {
- let result = attrs[i].parse_list(&self.session.parse_sess, |parser| {
- parser.parse_path_allowing_meta(PathStyle::Mod)
- });
-
- let mut traits = match result {
- Ok(traits) => traits,
- Err(mut e) => {
- e.cancel();
- continue
- }
- };
-
- for j in 0..traits.len() {
- if traits[j].segments.len() > 1 {
- continue
- }
- let trait_name = traits[j].segments[0].ident.name;
- let legacy_name = Symbol::intern(&format!("derive_{}", trait_name));
- if !self.builtin_macros.contains_key(&legacy_name) {
- continue
- }
- let span = traits.remove(j).span;
- self.gate_legacy_custom_derive(legacy_name, span);
- if traits.is_empty() {
- attrs.remove(i);
- } else {
- let mut tokens = Vec::with_capacity(traits.len() - 1);
- for (j, path) in traits.iter().enumerate() {
- if j > 0 {
- tokens.push(TokenTree::Token(attrs[i].span, Token::Comma).into());
- }
- tokens.reserve((path.segments.len() * 2).saturating_sub(1));
- for (k, segment) in path.segments.iter().enumerate() {
- if k > 0 {
- tokens.push(TokenTree::Token(path.span, Token::ModSep).into());
- }
- let tok = Token::from_ast_ident(segment.ident);
- tokens.push(TokenTree::Token(path.span, tok).into());
- }
- }
- let delim_span = DelimSpan::from_single(attrs[i].span);
- attrs[i].tokens = TokenTree::Delimited(delim_span, Delimited {
- delim: token::Paren,
- tts: TokenStream::concat(tokens).into(),
- }).into();
- }
- return Some(ast::Attribute {
- path: ast::Path::from_ident(Ident::new(legacy_name, span)),
- tokens: TokenStream::empty(),
- id: attr::mk_attr_id(),
- style: ast::AttrStyle::Outer,
- is_sugared_doc: false,
- span,
- });
- }
- }
- }
-
- None
- }
-
fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
let (path, kind, derives_in_scope, after_derive) = match invoc.kind {
feature_err(&self.session.parse_sess, "rustc_attrs", path.span,
GateIssue::Language, &msg).emit();
}
- } else if name.starts_with("derive_") {
- if !features.custom_derive {
- feature_err(&self.session.parse_sess, "custom_derive", path.span,
- GateIssue::Language, EXPLAIN_DERIVE_UNDERSCORE).emit();
- }
} else if !features.custom_attribute {
let msg = format!("The attribute `{}` is currently unknown to the \
compiler and may have meaning added to it in the \
self.define(module, ident, MacroNS, (def, vis, item.span, expansion));
}
}
-
- fn gate_legacy_custom_derive(&mut self, name: Symbol, span: Span) {
- if !self.session.features_untracked().custom_derive {
- let sess = &self.session.parse_sess;
- let explain = feature_gate::EXPLAIN_CUSTOM_DERIVE;
- emit_feature_err(sess, "custom_derive", span, GateIssue::Language, explain);
- } else if !self.is_whitelisted_legacy_custom_derive(name) {
- self.session.span_warn(span, feature_gate::EXPLAIN_DEPR_CUSTOM_DERIVE);
- }
- }
}
("thumbv7em-none-eabi", thumbv7em_none_eabi),
("thumbv7em-none-eabihf", thumbv7em_none_eabihf),
("thumbv8m.base-none-eabi", thumbv8m_base_none_eabi),
+ ("thumbv8m.main-none-eabi", thumbv8m_main_none_eabi),
+ ("thumbv8m.main-none-eabihf", thumbv8m_main_none_eabihf),
("msp430-none-elf", msp430_none_elf),
// - Cortex-M4(F)
// - Cortex-M7(F)
// - Cortex-M23
+// - Cortex-M33
//
// We have opted for these instead of one target per processor (e.g. `cortex-m0`, `cortex-m3`,
// etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile),
+// without the Floating Point extension.
+
+use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+ Ok(Target {
+ llvm_target: "thumbv8m.main-none-eabi".to_string(),
+ target_endian: "little".to_string(),
+ target_pointer_width: "32".to_string(),
+ target_c_int_width: "32".to_string(),
+ data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+ arch: "arm".to_string(),
+ target_os: "none".to_string(),
+ target_env: String::new(),
+ target_vendor: String::new(),
+ linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
+
+ options: TargetOptions {
+ max_atomic_width: Some(32),
+ .. super::thumb_base::opts()
+ },
+ })
+}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile),
+// with the Floating Point extension.
+
+use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+ Ok(Target {
+ llvm_target: "thumbv8m.main-none-eabihf".to_string(),
+ target_endian: "little".to_string(),
+ target_pointer_width: "32".to_string(),
+ target_c_int_width: "32".to_string(),
+ data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+ arch: "arm".to_string(),
+ target_os: "none".to_string(),
+ target_env: String::new(),
+ target_vendor: String::new(),
+ linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
+
+ options: TargetOptions {
+ // If the Floating Point extension is implemented in the Cortex-M33
+ // processor, the Cortex-M33 Technical Reference Manual states that
+ // the FPU uses the FPv5 architecture, single-precision instructions
+ // and 16 D registers.
+ // These parameters map to the following LLVM features.
+ features: "+fp-armv8,+fp-only-sp,+d16".to_string(),
+ max_atomic_width: Some(32),
+ .. super::thumb_base::opts()
+ },
+ })
+}
fcx.resolve_generator_interiors(def_id);
for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
+ let ty = fcx.normalize_ty(span, ty);
fcx.require_type_is_sized(ty, span, code);
}
fcx.select_all_obligations_or_error();
//
// to work in stable even if the Sized bound on `drop` is relaxed.
for i in 0..fn_sig.inputs().skip_binder().len() {
- let input = tcx.erase_late_bound_regions(&fn_sig.input(i));
+ // We just want to check sizedness, so instead of introducing
+ // placeholder lifetimes with probing, we just replace higher lifetimes
+ // with fresh vars.
+ let input = self.replace_bound_vars_with_fresh_vars(
+ expr.span,
+ infer::LateBoundRegionConversionTime::FnCall,
+ &fn_sig.input(i)).0;
self.require_type_is_sized_deferred(input, expr.span,
traits::SizedArgumentType);
}
// Here we want to prevent struct constructors from returning unsized types.
// There were two cases this happened: fn pointer coercion in stable
// and usual function call in presense of unsized_locals.
- let output = tcx.erase_late_bound_regions(&fn_sig.output());
+ // Also, as we just want to check sizedness, instead of introducing
+ // placeholder lifetimes with probing, we just replace higher lifetimes
+ // with fresh vars.
+ let output = self.replace_bound_vars_with_fresh_vars(
+ expr.span,
+ infer::LateBoundRegionConversionTime::FnCall,
+ &fn_sig.output()).0;
self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
}
fn next_node_id(&mut self) -> ast::NodeId;
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark;
fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item>;
- fn is_whitelisted_legacy_custom_derive(&self, name: Name) -> bool;
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
derives: &[Mark]);
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
fn resolve_imports(&mut self);
- // Resolves attribute and derive legacy macros from `#![plugin(..)]`.
- fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<Attribute>, allow_derive: bool)
- -> Option<Attribute>;
fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy>;
fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID }
fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }
fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item> { item }
- fn is_whitelisted_legacy_custom_derive(&self, _name: Name) -> bool { false }
fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment,
_derives: &[Mark]) {}
fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {}
fn resolve_imports(&mut self) {}
- fn find_legacy_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>, _allow_derive: bool)
- -> Option<Attribute> { None }
fn resolve_macro_invocation(&mut self, _invoc: &Invocation, _invoc_id: Mark, _force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
Err(Determinacy::Determined)
let (mut attr, mut traits, mut after_derive) = (None, Vec::new(), false);
item = item.map_attrs(|mut attrs| {
- if let Some(legacy_attr_invoc) = self.cx.resolver.find_legacy_attr_invoc(&mut attrs,
- true) {
- attr = Some(legacy_attr_invoc);
- return attrs;
- }
-
attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
traits = collect_derives(&mut self.cx, &mut attrs);
attrs
let (mut attr, mut after_derive) = (None, false);
item = item.map_attrs(|mut attrs| {
- if let Some(legacy_attr_invoc) = self.cx.resolver.find_legacy_attr_invoc(&mut attrs,
- false) {
- attr = Some(legacy_attr_invoc);
- return attrs;
- }
-
attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
attrs
});
}
feature_tests! {
- fn enable_quotes = quote,
fn enable_asm = asm,
fn enable_custom_test_frameworks = custom_test_frameworks,
fn enable_global_asm = global_asm,
fn enable_concat_idents = concat_idents,
fn enable_trace_macros = trace_macros,
fn enable_allow_internal_unstable = allow_internal_unstable,
- fn enable_custom_derive = custom_derive,
fn enable_format_args_nl = format_args_nl,
fn macros_in_extern_enabled = macros_in_extern,
fn proc_macro_hygiene = proc_macro_hygiene,
// Allows the use of custom attributes; RFC 572
(active, custom_attribute, "1.0.0", Some(29642), None),
- // Allows the use of #[derive(Anything)] as sugar for
- // #[derive_Anything].
- (active, custom_derive, "1.0.0", Some(29644), None),
-
// Allows the use of rustc_* attributes; RFC 572
(active, rustc_attrs, "1.0.0", Some(29642), None),
Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
(removed, panic_implementation, "1.28.0", Some(44489), None,
Some("subsumed by `#[panic_handler]`")),
+ // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
+ (removed, custom_derive, "1.0.0", Some(29644), None,
+ Some("subsumed by `#[proc_macro_derive]`")),
);
declare_features! (
"unless otherwise specified, attributes \
with the prefix `rustc_` \
are reserved for internal compiler diagnostics");
- } else if name.starts_with("derive_") {
- gate_feature!(self, custom_derive, attr.span, EXPLAIN_DERIVE_UNDERSCORE);
} else if !attr::is_known(attr) {
// Only run the custom attribute lint during regular
// feature gate checking. Macro gating runs
pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str =
"allow_internal_unsafe side-steps the unsafe_code lint";
-pub const EXPLAIN_CUSTOM_DERIVE: &str =
- "`#[derive]` for custom traits is deprecated and will be removed in the future.";
-
-pub const EXPLAIN_DEPR_CUSTOM_DERIVE: &str =
- "`#[derive]` for custom traits is deprecated and will be removed in the future. \
- Prefer using procedural macro custom derive.";
-
-pub const EXPLAIN_DERIVE_UNDERSCORE: &str =
- "attributes of the form `#[derive_*]` are reserved for the compiler";
-
pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str =
"unsized tuple coercion is not stable enough for use and is subject to change";
mod diagnostics;
-#[macro_use]
-// for custom_derive
-pub mod deriving;
-
mod asm;
mod assert;
mod cfg;
mod format_foreign;
mod global_asm;
mod log_syntax;
-mod trace_macros;
+mod proc_macro_server;
mod test;
mod test_case;
+mod trace_macros;
+pub mod deriving;
pub mod proc_macro_decls;
pub mod proc_macro_impl;
-mod proc_macro_server;
use rustc_data_structures::sync::Lrc;
use syntax::ast;
#[macro_use]
extern crate derive_a;
-#[derive_A] //~ ERROR: attributes of the form `#[derive_*]` are reserved for the compiler
+#[derive_A] //~ ERROR attribute `derive_A` is currently unknown
struct A;
fn main() {}
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
- reg.register_custom_derive(
+ reg.register_syntax_extension(
Symbol::intern("derive_TotalSum"),
MultiDecorator(box expand));
- reg.register_custom_derive(
+ reg.register_syntax_extension(
Symbol::intern("derive_Nothing"),
MultiDecorator(box noop));
}
// aux-build:custom_derive_partial_eq.rs
// ignore-stage1
-#![feature(plugin, custom_derive)]
+#![feature(plugin)]
#![plugin(custom_derive_partial_eq)]
#![allow(unused)]
-#[derive(CustomPartialEq)] // Check that this is not a stability error.
+#[derive_CustomPartialEq] // Check that this is not a stability error.
enum E { V1, V2 }
fn main() {}
+++ /dev/null
-warning: `#[derive]` for custom traits is deprecated and will be removed in the future. Prefer using procedural macro custom derive.
- --> $DIR/custom-derive-partial-eq.rs:17:10
- |
-LL | #[derive(CustomPartialEq)] // Check that this is not a stability error.
- | ^^^^^^^^^^^^^^^
-
// aux-build:custom_derive_plugin_attr.rs
// ignore-stage1
-#![feature(plugin, custom_derive, rustc_attrs)]
+#![feature(plugin, rustc_attrs)]
#![plugin(custom_derive_plugin_attr)]
trait TotalSum {
// aux-build:custom_derive_plugin.rs
// ignore-stage1
-#![feature(plugin, custom_derive)]
+#![feature(plugin)]
#![plugin(custom_derive_plugin)]
trait TotalSum {
}
}
-#[derive(TotalSum)]
+#[derive_TotalSum]
struct Foo {
seven: Seven,
bar: Bar,
baz: isize,
}
-#[derive(TotalSum)]
+#[derive_TotalSum]
struct Bar {
quux: isize,
bleh: isize,
// aux-build:custom_derive_plugin.rs
// ignore-stage1
-#![feature(plugin, custom_derive)]
+#![feature(plugin)]
#![plugin(custom_derive_plugin)]
-#[derive(Nothing, Nothing, Nothing)]
+#[derive_Nothing]
+#[derive_Nothing]
+#[derive_Nothing]
struct S;
fn main() {}
--- /dev/null
+use std::ops::Deref;
+
+fn foo<P>(_value: <P as Deref>::Target)
+where
+ P: Deref,
+ <P as Deref>::Target: Sized,
+{}
+
+fn main() {
+ foo::<Box<u32>>(2);
+}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+pub trait Signal {
+ type Item;
+}
+
+pub trait Signal2 {
+ type Item2;
+}
+
+impl<B, C> Signal2 for B where B: Signal<Item = C> {
+ type Item2 = C;
+}
+
+// @has issue_50159/struct.Switch.html
+// @has - '//code' 'impl<B> Send for Switch<B> where <B as Signal>::Item: Send'
+// @has - '//code' 'impl<B> Sync for Switch<B> where <B as Signal>::Item: Sync'
+// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0
+// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2
+pub struct Switch<B: Signal> {
+ pub inner: <B as Signal2>::Item2,
+}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Some unusual code minimized from
+// https://github.com/sile/handy_async/tree/7b619b762c06544fc67792c8ff8ebc24a88fdb98
+
+pub trait Pattern {
+ type Value;
+}
+
+pub struct Constrain<A, B = A, C = A>(A, B, C);
+
+impl<A, B, C> Pattern for Constrain<A, B, C>
+ where A: Pattern,
+ B: Pattern<Value = A::Value>,
+ C: Pattern<Value = A::Value>,
+{
+ type Value = A::Value;
+}
+
+pub struct Wrapper<T>(T);
+
+impl<T> Pattern for Wrapper<T> {
+ type Value = T;
+}
+
+
+// @has self_referential/struct.WriteAndThen.html
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<P1> Send for \
+// WriteAndThen<P1> where <P1 as Pattern>::Value: Send"
+pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
+ where P1: Pattern;
+
+++ /dev/null
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[derive_Clone]
-//~^ ERROR attributes of the form `#[derive_*]` are reserved
-struct Test;
-
-pub fn main() {}
+++ /dev/null
-error[E0658]: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644)
- --> $DIR/feature-gate-custom_derive.rs:11:3
- |
-LL | #[derive_Clone]
- | ^^^^^^^^^^^^
- |
- = help: add #![feature(custom_derive)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
macro_rules! foo (
() => (
- #[derive_Clone] //~ ERROR attributes of the form
+ #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown
struct T;
);
);
foo!();
bar!(
- #[derive_Clone] //~ ERROR attributes of the form
+ #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown
struct S;
);
-error[E0658]: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644)
+error[E0658]: The attribute `derive_Clone` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/issue-32655.rs:16:11
|
-LL | #[derive_Clone] //~ ERROR attributes of the form
+LL | #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown
| ^^^^^^^^^^^^
...
LL | foo!();
| ------- in this macro invocation
|
- = help: add #![feature(custom_derive)] to the crate attributes to enable
+ = help: add #![feature(custom_attribute)] to the crate attributes to enable
-error[E0658]: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644)
+error[E0658]: The attribute `derive_Clone` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/issue-32655.rs:28:7
|
-LL | #[derive_Clone] //~ ERROR attributes of the form
+LL | #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown
| ^^^^^^^^^^^^
|
- = help: add #![feature(custom_derive)] to the crate attributes to enable
+ = help: add #![feature(custom_attribute)] to the crate attributes to enable
error: aborting due to 2 previous errors
-Subproject commit 29bf75cd3147d4e34a5e70bd167898a8105f7e5d
+Subproject commit 1df5766cbb559aab0ad5c2296d8b768182b5186c