mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-16 05:56:56 +00:00
Auto merge of #37937 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 7 pull requests - Successful merges: #37442, #37760, #37836, #37851, #37859, #37913, #37925 - Failed merges:
This commit is contained in:
commit
127a83df66
@ -17,7 +17,7 @@ the language.
|
||||
|
||||
[**The Rust Reference**][ref]. While Rust does not have a
|
||||
specification, the reference tries to describe its working in
|
||||
detail. It tends to be out of date.
|
||||
detail. It is accurate, but not necessarily complete.
|
||||
|
||||
[**Standard Library API Reference**][api]. Documentation for the
|
||||
standard library.
|
||||
|
@ -48,6 +48,7 @@ use syntax::symbol::{Symbol, InternedString};
|
||||
use syntax_pos::{DUMMY_SP, Span};
|
||||
|
||||
use rustc_const_math::ConstInt;
|
||||
use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
|
||||
|
||||
use hir;
|
||||
use hir::itemlikevisit::ItemLikeVisitor;
|
||||
@ -1887,7 +1888,7 @@ impl<'tcx> TyS<'tcx> {
|
||||
/// Iterator that walks the immediate children of `self`. Hence
|
||||
/// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
|
||||
/// (but not `i32`, like `walk`).
|
||||
pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
|
||||
pub fn walk_shallow(&'tcx self) -> AccIntoIter<walk::TypeWalkerArray<'tcx>> {
|
||||
walk::walk_shallow(self)
|
||||
}
|
||||
|
||||
|
@ -12,17 +12,22 @@
|
||||
//! WARNING: this does not keep track of the region depth.
|
||||
|
||||
use ty::{self, Ty};
|
||||
use std::iter::Iterator;
|
||||
use std::vec::IntoIter;
|
||||
use rustc_data_structures::small_vec::SmallVec;
|
||||
use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
|
||||
|
||||
// The TypeWalker's stack is hot enough that it's worth going to some effort to
|
||||
// avoid heap allocations.
|
||||
pub type TypeWalkerArray<'tcx> = [Ty<'tcx>; 8];
|
||||
pub type TypeWalkerStack<'tcx> = SmallVec<TypeWalkerArray<'tcx>>;
|
||||
|
||||
pub struct TypeWalker<'tcx> {
|
||||
stack: Vec<Ty<'tcx>>,
|
||||
stack: TypeWalkerStack<'tcx>,
|
||||
last_subtree: usize,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeWalker<'tcx> {
|
||||
pub fn new(ty: Ty<'tcx>) -> TypeWalker<'tcx> {
|
||||
TypeWalker { stack: vec![ty], last_subtree: 1, }
|
||||
TypeWalker { stack: SmallVec::one(ty), last_subtree: 1, }
|
||||
}
|
||||
|
||||
/// Skips the subtree of types corresponding to the last type
|
||||
@ -61,8 +66,8 @@ impl<'tcx> Iterator for TypeWalker<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter<Ty<'tcx>> {
|
||||
let mut stack = vec![];
|
||||
pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> AccIntoIter<TypeWalkerArray<'tcx>> {
|
||||
let mut stack = SmallVec::new();
|
||||
push_subtypes(&mut stack, ty);
|
||||
stack.into_iter()
|
||||
}
|
||||
@ -73,7 +78,7 @@ pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter<Ty<'tcx>> {
|
||||
// known to be significant to any code, but it seems like the
|
||||
// natural order one would expect (basically, the order of the
|
||||
// types as they are written).
|
||||
fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
|
||||
fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
|
||||
match parent_ty.sty {
|
||||
ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) |
|
||||
ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyNever | ty::TyError => {
|
||||
@ -112,7 +117,7 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn push_sig_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, sig: &ty::PolyFnSig<'tcx>) {
|
||||
fn push_sig_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, sig: &ty::PolyFnSig<'tcx>) {
|
||||
stack.push(sig.0.output);
|
||||
stack.extend(sig.0.inputs.iter().cloned().rev());
|
||||
}
|
||||
|
@ -130,6 +130,18 @@ impl<A: Array> SmallVec<A> {
|
||||
self.set_len(len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn truncate(&mut self, len: usize) {
|
||||
unsafe {
|
||||
while len < self.len() {
|
||||
// Decrement len before the drop_in_place(), so a panic on Drop
|
||||
// doesn't re-drop the just-failed value.
|
||||
let newlen = self.len() - 1;
|
||||
self.set_len(newlen);
|
||||
::std::ptr::drop_in_place(self.get_unchecked_mut(newlen));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Array> Deref for SmallVec<A> {
|
||||
|
@ -102,6 +102,7 @@ enum CastError {
|
||||
/// Cast of thin to fat raw ptr (eg. `*const () as *const [u8]`)
|
||||
SizedUnsizedCast,
|
||||
IllegalCast,
|
||||
NeedDeref,
|
||||
NeedViaPtr,
|
||||
NeedViaThinPtr,
|
||||
NeedViaInt,
|
||||
@ -138,6 +139,25 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
||||
|
||||
fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) {
|
||||
match e {
|
||||
CastError::NeedDeref => {
|
||||
let cast_ty = fcx.ty_to_string(self.cast_ty);
|
||||
let mut err = fcx.type_error_struct(self.cast_span,
|
||||
|actual| {
|
||||
format!("casting `{}` as `{}` is invalid",
|
||||
actual,
|
||||
cast_ty)
|
||||
},
|
||||
self.expr_ty);
|
||||
err.span_label(self.expr.span,
|
||||
&format!("cannot cast `{}` as `{}`",
|
||||
fcx.ty_to_string(self.expr_ty),
|
||||
cast_ty));
|
||||
if let Ok(snippet) = fcx.sess().codemap().span_to_snippet(self.expr.span) {
|
||||
err.span_label(self.expr.span,
|
||||
&format!("did you mean `*{}`?", snippet));
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
CastError::NeedViaThinPtr |
|
||||
CastError::NeedViaPtr => {
|
||||
let mut err = fcx.type_error_struct(self.span,
|
||||
@ -390,8 +410,28 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
||||
(Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast
|
||||
(Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), // ptr-addr-cast
|
||||
(FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast),
|
||||
(RPtr(_), Int(_)) |
|
||||
(RPtr(_), Float) => Err(CastError::NeedViaPtr),
|
||||
(RPtr(p), Int(_)) |
|
||||
(RPtr(p), Float) => {
|
||||
match p.ty.sty {
|
||||
ty::TypeVariants::TyInt(_) |
|
||||
ty::TypeVariants::TyUint(_) |
|
||||
ty::TypeVariants::TyFloat(_) => {
|
||||
Err(CastError::NeedDeref)
|
||||
}
|
||||
ty::TypeVariants::TyInfer(t) => {
|
||||
match t {
|
||||
ty::InferTy::IntVar(_) |
|
||||
ty::InferTy::FloatVar(_) |
|
||||
ty::InferTy::FreshIntTy(_) |
|
||||
ty::InferTy::FreshFloatTy(_) => {
|
||||
Err(CastError::NeedDeref)
|
||||
}
|
||||
_ => Err(CastError::NeedViaPtr),
|
||||
}
|
||||
}
|
||||
_ => Err(CastError::NeedViaPtr),
|
||||
}
|
||||
}
|
||||
// * -> ptr
|
||||
(Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
|
||||
(FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
|
||||
|
@ -546,17 +546,23 @@ pub fn current_exe() -> io::Result<PathBuf> {
|
||||
os_imp::current_exe()
|
||||
}
|
||||
|
||||
/// An iterator over the arguments of a process, yielding a `String` value
|
||||
/// An iterator over the arguments of a process, yielding a [`String`] value
|
||||
/// for each argument.
|
||||
///
|
||||
/// This structure is created through the `std::env::args` method.
|
||||
/// This structure is created through the [`std::env::args`] method.
|
||||
///
|
||||
/// [`String`]: ../string/struct.String.html
|
||||
/// [`std::env::args`]: ./fn.args.html
|
||||
#[stable(feature = "env", since = "1.0.0")]
|
||||
pub struct Args { inner: ArgsOs }
|
||||
|
||||
/// An iterator over the arguments of a process, yielding an `OsString` value
|
||||
/// An iterator over the arguments of a process, yielding an [`OsString`] value
|
||||
/// for each argument.
|
||||
///
|
||||
/// This structure is created through the `std::env::args_os` method.
|
||||
/// This structure is created through the [`std::env::args_os`] method.
|
||||
///
|
||||
/// [`OsString`]: ../ffi/struct.OsString.html
|
||||
/// [`std::env::args_os`]: ./fn.args_os.html
|
||||
#[stable(feature = "env", since = "1.0.0")]
|
||||
pub struct ArgsOs { inner: sys::args::Args }
|
||||
|
||||
@ -571,7 +577,7 @@ pub struct ArgsOs { inner: sys::args::Args }
|
||||
///
|
||||
/// The returned iterator will panic during iteration if any argument to the
|
||||
/// process is not valid unicode. If this is not desired,
|
||||
/// use the `args_os` function instead.
|
||||
/// use the [`args_os`] function instead.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -583,6 +589,8 @@ pub struct ArgsOs { inner: sys::args::Args }
|
||||
/// println!("{}", argument);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`args_os`]: ./fn.args_os.html
|
||||
#[stable(feature = "env", since = "1.0.0")]
|
||||
pub fn args() -> Args {
|
||||
Args { inner: args_os() }
|
||||
|
@ -194,6 +194,14 @@ impl SocketAddr {
|
||||
|
||||
impl SocketAddrV4 {
|
||||
/// Creates a new socket address from the (ip, port) pair.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::{SocketAddrV4, Ipv4Addr};
|
||||
///
|
||||
/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
|
||||
SocketAddrV4 {
|
||||
@ -207,6 +215,15 @@ impl SocketAddrV4 {
|
||||
}
|
||||
|
||||
/// Returns the IP address associated with this socket address.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::{SocketAddrV4, Ipv4Addr};
|
||||
///
|
||||
/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
|
||||
/// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn ip(&self) -> &Ipv4Addr {
|
||||
unsafe {
|
||||
@ -215,18 +232,47 @@ impl SocketAddrV4 {
|
||||
}
|
||||
|
||||
/// Change the IP address associated with this socket address.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::{SocketAddrV4, Ipv4Addr};
|
||||
///
|
||||
/// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
|
||||
/// socket.set_ip(Ipv4Addr::new(192, 168, 0, 1));
|
||||
/// assert_eq!(socket.ip(), &Ipv4Addr::new(192, 168, 0, 1));
|
||||
/// ```
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
pub fn set_ip(&mut self, new_ip: Ipv4Addr) {
|
||||
self.inner.sin_addr = *new_ip.as_inner()
|
||||
}
|
||||
|
||||
/// Returns the port number associated with this socket address.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::{SocketAddrV4, Ipv4Addr};
|
||||
///
|
||||
/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
|
||||
/// assert_eq!(socket.port(), 8080);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn port(&self) -> u16 {
|
||||
ntoh(self.inner.sin_port)
|
||||
}
|
||||
|
||||
/// Change the port number associated with this socket address.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::{SocketAddrV4, Ipv4Addr};
|
||||
///
|
||||
/// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
|
||||
/// socket.set_port(4242);
|
||||
/// assert_eq!(socket.port(), 4242);
|
||||
/// ```
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
pub fn set_port(&mut self, new_port: u16) {
|
||||
self.inner.sin_port = hton(new_port);
|
||||
|
@ -115,4 +115,9 @@ fn main()
|
||||
let _ = cf as *const Bar;
|
||||
//~^ ERROR casting
|
||||
//~^^ NOTE vtable kinds
|
||||
|
||||
vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
|
||||
//~^ ERROR casting `&{float}` as `f32` is invalid
|
||||
//~| NOTE cannot cast `&{float}` as `f32`
|
||||
//~| NOTE did you mean `*s`?
|
||||
}
|
||||
|
254
src/test/incremental/hashes/struct_constructors.rs
Normal file
254
src/test/incremental/hashes/struct_constructors.rs
Normal file
@ -0,0 +1,254 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
|
||||
// This test case tests the incremental compilation hash (ICH) implementation
|
||||
// for struct constructor expressions.
|
||||
|
||||
// The general pattern followed here is: Change one thing between rev1 and rev2
|
||||
// and make sure that the hash has changed, then change nothing between rev2 and
|
||||
// rev3 and make sure that the hash has not changed.
|
||||
|
||||
// must-compile-successfully
|
||||
// revisions: cfail1 cfail2 cfail3
|
||||
// compile-flags: -Z query-dep-graph
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![crate_type="rlib"]
|
||||
|
||||
|
||||
struct RegularStruct {
|
||||
x: i32,
|
||||
y: i64,
|
||||
z: i16,
|
||||
}
|
||||
|
||||
// Change field value (regular struct) -----------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
fn change_field_value_regular_struct() -> RegularStruct {
|
||||
RegularStruct {
|
||||
x: 0,
|
||||
y: 1,
|
||||
z: 2,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn change_field_value_regular_struct() -> RegularStruct {
|
||||
RegularStruct {
|
||||
x: 0,
|
||||
y: 2,
|
||||
z: 2,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Change field order (regular struct) -----------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
fn change_field_order_regular_struct() -> RegularStruct {
|
||||
RegularStruct {
|
||||
x: 3,
|
||||
y: 4,
|
||||
z: 5,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn change_field_order_regular_struct() -> RegularStruct {
|
||||
RegularStruct {
|
||||
y: 4,
|
||||
x: 3,
|
||||
z: 5,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Add field (regular struct) --------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
fn add_field_regular_struct() -> RegularStruct {
|
||||
let struct1 = RegularStruct {
|
||||
x: 3,
|
||||
y: 4,
|
||||
z: 5,
|
||||
};
|
||||
|
||||
RegularStruct {
|
||||
x: 7,
|
||||
.. struct1
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn add_field_regular_struct() -> RegularStruct {
|
||||
let struct1 = RegularStruct {
|
||||
x: 3,
|
||||
y: 4,
|
||||
z: 5,
|
||||
};
|
||||
|
||||
RegularStruct {
|
||||
x: 7,
|
||||
y: 8,
|
||||
.. struct1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Change field label (regular struct) -----------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
fn change_field_label_regular_struct() -> RegularStruct {
|
||||
let struct1 = RegularStruct {
|
||||
x: 3,
|
||||
y: 4,
|
||||
z: 5,
|
||||
};
|
||||
|
||||
RegularStruct {
|
||||
x: 7,
|
||||
y: 9,
|
||||
.. struct1
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn change_field_label_regular_struct() -> RegularStruct {
|
||||
let struct1 = RegularStruct {
|
||||
x: 3,
|
||||
y: 4,
|
||||
z: 5,
|
||||
};
|
||||
|
||||
RegularStruct {
|
||||
x: 7,
|
||||
z: 9,
|
||||
.. struct1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct RegularStruct2 {
|
||||
x: i8,
|
||||
y: i8,
|
||||
z: i8,
|
||||
}
|
||||
|
||||
// Change constructor path (regular struct) ------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
fn change_constructor_path_regular_struct() {
|
||||
let _ = RegularStruct {
|
||||
x: 0,
|
||||
y: 1,
|
||||
z: 2,
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn change_constructor_path_regular_struct() {
|
||||
let _ = RegularStruct2 {
|
||||
x: 0,
|
||||
y: 1,
|
||||
z: 2,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Change constructor path indirectly (regular struct) -------------------------
|
||||
mod change_constructor_path_indirectly_regular_struct {
|
||||
#[cfg(cfail1)]
|
||||
use super::RegularStruct as Struct;
|
||||
#[cfg(not(cfail1))]
|
||||
use super::RegularStruct2 as Struct;
|
||||
|
||||
fn function() -> Struct {
|
||||
Struct {
|
||||
x: 0,
|
||||
y: 1,
|
||||
z: 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct TupleStruct(i32, i64, i16);
|
||||
|
||||
// Change field value (tuple struct) -------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
fn change_field_value_tuple_struct() -> TupleStruct {
|
||||
TupleStruct(0, 1, 2)
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn change_field_value_tuple_struct() -> TupleStruct {
|
||||
TupleStruct(0, 1, 3)
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct TupleStruct2(u16, u16, u16);
|
||||
|
||||
// Change constructor path (tuple struct) --------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
fn change_constructor_path_tuple_struct() {
|
||||
let _ = TupleStruct(0, 1, 2);
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn change_constructor_path_tuple_struct() {
|
||||
let _ = TupleStruct2(0, 1, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Change constructor path indirectly (tuple struct) ---------------------------
|
||||
mod change_constructor_path_indirectly_tuple_struct {
|
||||
#[cfg(cfail1)]
|
||||
use super::TupleStruct as Struct;
|
||||
#[cfg(not(cfail1))]
|
||||
use super::TupleStruct2 as Struct;
|
||||
|
||||
fn function() -> Struct {
|
||||
Struct(0, 1, 2)
|
||||
}
|
||||
}
|
@ -13,6 +13,9 @@
|
||||
// toolchain.
|
||||
// See https://github.com/rust-lang/rust/issues/34793 for more information.
|
||||
|
||||
// Make sure we don't optimize anything away:
|
||||
// compile-flags: -C no-prepopulate-passes
|
||||
|
||||
// Expand something exponentially
|
||||
macro_rules! go_bacterial {
|
||||
($mac:ident) => ($mac!());
|
||||
@ -23,10 +26,7 @@ macro_rules! go_bacterial {
|
||||
}
|
||||
|
||||
macro_rules! mk_closure {
|
||||
() => ({
|
||||
let c = |a: u32| a + 4;
|
||||
let _ = c(2);
|
||||
})
|
||||
() => ((move || {})())
|
||||
}
|
||||
|
||||
macro_rules! mk_fn {
|
23
src/test/run-pass/issue-23699.rs
Normal file
23
src/test/run-pass/issue-23699.rs
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
fn gimme_a_raw_pointer<T>(_: *const T) { }
|
||||
|
||||
fn test<T>(t: T) { }
|
||||
|
||||
fn main() {
|
||||
// Clearly `pointer` must be of type `*const ()`.
|
||||
let pointer = &() as *const _;
|
||||
gimme_a_raw_pointer(pointer);
|
||||
|
||||
let t = test as fn (i32);
|
||||
t(0i32);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user